Calculating angle between two points using ATAN/ATAN2 where x2 - x1 = 0 - google-sheets

Using Google Sheets, I've got to calculate the angle between two points with an X and Y coordinate. I've been using ATAN and that works really well when the points are at two unique X and Y coordinates, I get given the angle and then from there I can determine whether it fits prescribed criteria.
The problem I've been running into is when both points fall on the same X coordinate.
TAN(theta) = Y2 - Y1 / X2 - X1
Rearranged to
ATAN(Y2-Y1/X2-X1) = theta
With the example points (16,16) and (16,6) the X2-X1 comes to zero and then the formula won't run due to the denominator being zero.
ATAN2 solves problems with two Y coordinates being identical but I'm yet to find a solution for having two of the same X coordinate. If anyone could help that would be greatly appreciated!

ATAN2() allows for 2 or 1 argument call.
To get a full [-pi...pi] result and cope with OP's case where x1 == x2, use the 2 argument form:
ATAN2(X2-X1, Y2-Y1)
OP posted TAN(theta) = Y2 - Y1 / X2 - X1. Hopefully OP was really doing TAN(theta) = (Y2 - Y1) / (X2 - X1)

In this case, the angle between the two points is just twice the (acute) angle from one of the points to the x-axis. It doesn't matter which point on the x-axis, so long as it's on the same side of the y-axis as that point.

Related

Creating a navigation system (ArcTan2)

I am currently working on a navigation system using way-points, We can define the following perimeters, assume point B is where we want to go and point A is your current location :
We know the locations (X,Y) of both points A & B.
Point A (you) and Point B (our destination) are both positive in their respective X and Y values.
We know the angle Point A (you) are facing. (360 - 0 degrees)
My question is how would I get the smallest angle to turn in order to face point B (our destination)?
My current method is using ArcTan2(X,Y)
B := ArcTan2(Y1 - Y2,X1 - X2)
B := B * 180 / pi ---- To convert radians into degrees.
This does return a suitable angle, but only sometimes... Other times it returns an angle that will make me face the opposite direction of point B (our destination).
Another issue I am having is figuring out if I should turn left or right - Assume we have a returned angle of 80 degrees, Should that then mean that I rotate to the left or the right ?
I hope my explanation is somewhat clear, Trigonometry was never really my strong point.
I'd be very grateful for any input or sources you guys may be able to provide me.
Thanks
MrClear
You are using wrong X/Y argument order
B := ArcTan2(Y2 - Y1, X2 - X1)
is correct formula to get direction from 1st point to 2nd one.
If you really need angle to turn, you also have to provide current direction (or previous point)
Let you are moving from point A to point B and after B you need to turn onto point C. In this case you need calculate relative angle to change direction (this approach uses cross product of vectors):
CBX := C.X - B.X;
CBY := C.Y - B.Y;
BAX := B.X - A.X;
BAY := B.Y - A.Y;
RotationAngle :=
RadToDeg(ArcTan2(CBX * BAY - CBY * BAX, CBX * BAX + CBY * BAY));
Note that function returns signed angle and you can easily check whether you need to turn left or right. Also RadToDeg function helps to get degrees.
If you have two points (xA, yA) and (xB, yB), with point A as the start and point B as the destination, you have a vector from the start to the destination:
v = (xB-xA)i + (yB-yA)j
In a 2D coordinate system, with x-axis to the right and y-axis pointing up, this vector makes an angle with the horizontal axis that is easy to calculate:
angle = atan2((yB-yA), (xB-xA))
where
i = unit vector in x-direction
j = unit vector in y-direction
This angle is expressed in radians. It rotates from the horizontal axis counterclockwise about point A.
Watch for zero length vectors.

Find the smallest x for given y for a rotated UIView

I transformed some UIView with a CGAffineTransform. Now I want to know if it possible to get the smallest x point of the UIView when proving some y value in the UIView.
For example in the picture below, I want to know the smallest x value for a y value which is 0.75 the view's height.
someView.frame.origin.x provides only the x value for the top-left position, but I need something to change that position to get the smallest x value of a given y value.
I assume you can calculate the minimum X and its corresponding Y on the rotated square.. Then calculate the X2, Y2 as shown in the picture below once you know the angle the square has rotated and the length of its sides (then its Pythagorean theorem)..
I used let rotatedRect = CGRectApplyAffineTransform(rotationTransformation, square.frame) to get the rotated rectangle's coordinates. Then I compared all 4 points to find the one with the smallest X value and the equation of the two lines of the square that go through that point (one has positive slope, the other has negative).
Once you have X1, Y1 and X2, Y2, X3, Y3 as shown below, you can calculate the interception of two lines by substitution or elimination as shown below..
To make it simple, I assumed the slope of the line passing through the square was 0 (horizontal-line).
To figure out which is the correct minimum X value, you compare if the X >= X1. If it is, that is the minimum that satisfies your requirements. See below for example..
as the UIView is always a rectangle, I suppose you want to track the minimum x for a given y just for rectangles.
SOLUTION
you can track the position of the 4 vertexes of the UIView always you rotate it. This tracking can be done by simply multiplying the points for a 2x2 rotation matrix.
| cosθ -senθ | | x | = | x * cosθ - y * senθ |
| senθ cosθ | | y | | x * senθ + y * cosθ |
Then, you can get the vertex with minimum x (lets call it V1).
then you need to get other 2 vertexes with the minimum x (called V2 and V3).
if V1.y > (given y)
write linear equation from V1 to vertex with minimum y between V2 and V3
else
write linear equation from V1 to vertex with maximum y between V2 and V3
in the end you will have f(x) = ax + b
replace the given y for f(x) and you get x = (y - b)/a
hope that helps :)

How to find a line from polar coordinates (Hough Transform Confusion)

I recently started a CV course and am going through old homeworks (the current ones aren't released). I've implemented a Hough Lines function, I loop through each point, if it's an edge, then I loop through 0-180 (or -90 to 90) theta values, and calculate rho, and finally store in an array.
When I tried to convert back from Polar Coordinates, I can find an X,Y pair (using rho * sin(theta), and rho * cos(theta)), however I don't understand how to convert that to a line in Cartesian space. To have a line you need either 2 points or a point and a direction (assuming ray then of course)
I just understand where the point is.
I've done some searching but can't seem to quite find the answer, folks tend to say, polar tells you x, then bam you have a line in cartesian, but I seem to be missing that connection where the "bam" was.
What I mean is described here;
Explain Hough Transformation
Also Vector/line from polar coordinates
Where it's asked how do I draw a line from polar coords, which the response was well here's x and y. but to me never mentions rest of that solution.
Is the line somehow related to y = mx+b where m is theta and b is rho?
If not how do I convert back to a line in cartesian space.
EDIT:
After reviewing Sunreef's answer, and trying to convert so y was on it's own side, I discovered this answer as well:
How to convert coordinates back to image (x,y) from hough transformation (rho, theta)?
It appears what I think I'm looking for is this
m = -cotθ
c = p*cosecθ
EDIT#2
I found some other examples on the net. Basically yes I'll need rho * sin(theta) and rho*cos(theta)
The other part that was messing me up was that I needed to convert to radians, once i did that, I started getting good results.
You are right that you can get some base point at the line as
(X0, Y0) = (rho * cos(theta), rho * sin(theta))
and you can find (unit) direction vector of this line as perpendicular to normal:
(dx, dy) = ( -sin(theta), cos(theta))
Taken from Wikipedia:
The non-radial line that crosses the radial line ϕ = ɣ perpendicularly at the point (r0, ɣ) has the equation: r(ϕ) = r0 * sec(ϕ - ɣ).
If I suppose that the coordinates you have for your line are ɣ and r0, then you can rewrite this equation like this:
r(ϕ) * cos(ϕ) * cos(ɣ) + r(ϕ) * sin(ϕ) * sin(ɣ) - r0 = 0
And we know that when translating polar to cartesian coordinates, if we have a point P(r, ϕ) in the polar plane, then its coordinates in the cartesian plane will be:
x = r * cos(ϕ)
y = r * sin(ϕ)
So the equation above becomes a line equation as follows:
x * cos(ɣ) + y * sin(ɣ) - r0 = 0
This is the equation of your line in cartesian coordinates.
(Tell me if you see some mistakes, I did that quickly)

How to transform an image based on the position of camera

I'm trying to create a perspective projection of an image based on the look direction. I'm unexperienced on this field and can't manage to do that myself, however. Will you help me, please?
There is an image and an observer (camera). If camera can be considered an object on an invisible sphere and the image a plane going through the middle of the sphere, then camera position can be expressed as:
x = d cos(θ) cos(φ)
y = d sin(θ)
z = d sin(φ) cos(θ)
Where θ is latitude, φ is longitude and d is the distance (radius) from the middle of the sphere where the middle of the image is.
I found these formulae somwhere, but I'm not sure about the coordinates (I don't know but it looks to me that x should be z but I guess it depends on the coordinate system).
Now, what I need to do is make a proper transformation of my image so it looks as if viewed from the camera (in a proper perspective). Would you be so kind to tell me a few words how this could be done? What steps should I take?
I'm developing an iOS app and I thought I could use the following method from the QuartzCore. But I have no idea what angle I should pass to this method and how to derive the new x, y, z coordinates from the camera position.
CATransform3D CATransform3DRotate (CATransform3D t, CGFloat angle,
CGFloat x, CGFloat y, CGFloat z)
So far I have successfully created a simple viewing perspective by:
using an identity matrix (as the CATransform3D parameter) with .m34 set to 1/-1000,
rotating my image by the angle of φ with the (0, 1, 0) vector,
concatenating the result with a rotation by θ and the (1, 0, 0) vector,
scaling based on the d is ignored (I scale the image based on some other criteria).
But the result I got was not what I wanted (which was obvious) :-/. The perspective looks realistic as long as one of these two angles is close to 0. Therefore I thought there could be a way to calculate somehow a proper angle and the x, y and z coordinates to achieve a proper transformation (which might be wrong because it's just my guess).
I think I managed to find a solution, but unfortunately based on my own calculations, thoughts and experiments, so I have no idea if it is correct. Seems to be OK, but you know...
So if the coordinate system is like this:
and the plane of the image to be transformed goes through the X and the Y axis, and its centre is in the origin of the system, then the following coordinates:
x = d sin(φ) cos(θ)
y = d sin(θ)
z = d cos(θ) cos(φ)
define a vector that starts in the origin of the coordinate system and points to the position of the camera that is observing the image. The d can be set to 1 so we get a unit vector at once without further normalization. Theta is the angle in the ZY plane and phi is the angle in the ZX plane. Theta raises from 0° to 90° from the Z+ to the Y+ axis, whereas phi raises from 0° to 90° from the Z+ to the X+ axis (and to -90° in the opposite direction, in both cases).
Hence the transformation vector is:
x1 = -y / z
y1 = -x / z
z1 = 0.
I'm not sure about z1 = 0, however rotation around the Z axis seemed wrong to me.
The last thing to calculate is the angle by which the image has to be transformed. In my humble opinion this should be the angle between the vector that points to the camera (x, y, z) and the vector normal to the image, which is the Z axis (0, 0, 1).
The dot product of two vectors gives the cosine of the angle between them, so the angle is:
α = arccos(x * 0 + y * 0 + z * 1) = arccos(z).
Therefore the alpha angle and the x1, y1, z1 coordinates are the parameters of CATransform3DRotate method I mentioned in my question.
I would be grateful if somebody could tell me if this approach is correct. Thanks a lot!

Hough Transform Equation

I was wondering why the Hough Transform uses rho=xcos(theta) + ysin(theta) for representation of a straight line (y=mx+b). I tried to work through this (and went to the wikipedia article about this), but can not find a way to derive one from the other.
Does anyone know how to derive one from the other?
Thank you in advance.
Derivation:
The equation x/a + y/b = 1:
defines a line
has x-intercept = a
has y-intercept = b
From trigonometry, recall how a ray rotated by angle t will project onto the x- and y- axes according to (angle=t, radius=1) -> (x=cos(t), y=sin(t))*
Draw the tangent line at the labelled point. Trigonometry (or even geometry with similar triangles) tells us that the tangent line intersects at x=1/cos(t), y=1/sin(t). Thus the line a distance 1 away will have a=1/cos(t) and b=1/sin(t), and thus described by x/(1/cos(t)) + y/(1/sin(t)) = 1...
... which is just cos(t) x + sin(t) y = rho where rho=1
You can see that rho corresponds to how far the line is from the origin (either by playing around with the equation, or by noting that multiplication here just scales all values by the same amount, effectively rescaling the grid).
*see http://en.wikipedia.org/wiki/File:Unit_circle.svg for credit
That's just a transform from a linear coordinate system to a rotational one. The reason for this is outlined in the Wikipedia article:
In the Hough transform, a main idea is to consider the characteristics of the straight line not as image points (x1, y1), (x2, y2), etc., but instead, in terms of its parameters, i.e., the slope parameter m and the intercept parameter b. Based on that fact, the straight line y = mx + b can be represented as a point (b, m) in the parameter space. However, one faces the problem that vertical lines give rise to unbounded values of the parameters m and b. For computational reasons, it is therefore better to use a different pair of parameters, denoted r and θ (theta), for the lines in the Hough transform.
And to transform between the two, use the equation y = -(cos(theta)/sin(theta))x + r/sin(theta). Thus m = -(cos(theta)/sin(theta)) and b = r/sin(theta). These obviously break down when sin(theta)=0 or theta=0, which is why the rotational coordinate system is preferred (there aren't any problems with lines with infinite slopes).
Polar coordinate system is 2-D coordinate system that has a reference point (like origin) called pole and a line from the pole called the polar axis. Each point in the Polar coordinate system is represented as (rho, theta) where 'rho' is the distance between the pole (origin) and the point and 'theta' is the angle between the polar axis and the line joining the pole and the point. See here.
The Polar coordinate (rho, theta) can be converted to Cartesian coordinate (x,y) using the following trigonometric equations.
x = rho cos theta ----(1)
y = rho sin theta ----(2)
Refer here for more info.
How do we get the above equations?
The equations use concepts of a right angle (trignonometry)
See the picture here.
cos theta = adjacent-side/hypotenuse = x/rho, thus we get (1)
sin theta = opposite-side/hypotenuse = y/rho, thus we get (2)
and Pythagorean theorem says,
hypotenuse^2 = adjacent side ^2 + opposite side^2, so
rho^2 = x^2 + y^2 ----(3)
Now let's derive the relationship between Cartesian coordinate (x,y) and Polar coordinate (rho,theta)
rho^2 = x^2 + y^2 ---- from (3)
rho^2 = x*x + y*y
rho^2 = x(rho cos theta) + y (rho sin theta) ---- from (1) and (2)
rho^2 = rho(x cos theta + y sin theta)
rho = x cos theta + y sin theta
Each pair of rho, theta relates to an x,y pair for a given line in that the distance rho from the origin at angle theta places you at an x,y coordinate on the line.
The rho, theta equation is used instead of y=mx+b so that a sequence of rho, theta values can be put into the equation without computational problems that arise with the y=mx+b method where the slope is undefined (that is, the line is vertical).

Resources