calculate the angle between a line and x-axis
If you have two points, (x0, y0)
and (x1, y1)
, then the angle of the line joining them (relative to the X axis) is given by:
theta = atan2((y1 - y0), (x1 - x0))
Calculating the angle between a line and the x-axis
Assumptions: x
is the horizontal axis, and increases when moving from left to right.y
is the vertical axis, and increases from bottom to top. (touch_x, touch_y)
is the
point selected by the user. (center_x, center_y)
is the point at the center of the
screen. theta
is measured counter-clockwise from the +x
axis. Then:
delta_x = touch_x - center_x
delta_y = touch_y - center_y
theta_radians = atan2(delta_y, delta_x)
Edit: you mentioned in a comment that y increases from top to bottom. In that
case,
delta_y = center_y - touch_y
But it would be more correct to describe this as expressing (touch_x, touch_y)
in polar coordinates relative to (center_x, center_y)
. As ChrisF mentioned,
the idea of taking an "angle between two points" is not well defined.
How to calculate the angle between a line and the horizontal axis?
First find the difference between the start point and the end point (here, this is more of a directed line segment, not a "line", since lines extend infinitely and don't start at a particular point).
deltaY = P2_y - P1_y
deltaX = P2_x - P1_x
Then calculate the angle (which runs from the positive X axis at P1
to the positive Y axis at P1
).
angleInDegrees = arctan(deltaY / deltaX) * 180 / PI
But arctan
may not be ideal, because dividing the differences this way will erase the distinction needed to distinguish which quadrant the angle is in (see below). Use the following instead if your language includes an atan2
function:
angleInDegrees = atan2(deltaY, deltaX) * 180 / PI
EDIT (Feb. 22, 2017): In general, however, calling atan2(deltaY,deltaX)
just to get the proper angle for cos
and sin
may be inelegant. In those cases, you can often do the following instead:
- Treat
(deltaX, deltaY)
as a vector. - Normalize that vector to a unit vector. To do so, divide
deltaX
anddeltaY
by the vector's length (sqrt(deltaX*deltaX+deltaY*deltaY)
), unless the length is 0. - After that,
deltaX
will now be the cosine of the angle between the vector and the horizontal axis (in the direction from the positive X to the positive Y axis atP1
). - And
deltaY
will now be the sine of that angle. - If the vector's length is 0, it won't have an angle between it and the horizontal axis (so it won't have a meaningful sine and cosine).
EDIT (Feb. 28, 2017): Even without normalizing (deltaX, deltaY)
:
- The sign of
deltaX
will tell you whether the cosine described in step 3 is positive or negative. - The sign of
deltaY
will tell you whether the sine described in step 4 is positive or negative. - The signs of
deltaX
anddeltaY
will tell you which quadrant the angle is in, in relation to the positive X axis atP1
:+deltaX
,+deltaY
: 0 to 90 degrees.-deltaX
,+deltaY
: 90 to 180 degrees.-deltaX
,-deltaY
: 180 to 270 degrees (-180 to -90 degrees).+deltaX
,-deltaY
: 270 to 360 degrees (-90 to 0 degrees).
An implementation in Python using radians (provided on July 19, 2015 by Eric Leschinski, who edited my answer):
from math import *
def angle_trunc(a):
while a < 0.0:
a += pi * 2
return a
def getAngleBetweenPoints(x_orig, y_orig, x_landmark, y_landmark):
deltaY = y_landmark - y_orig
deltaX = x_landmark - x_orig
return angle_trunc(atan2(deltaY, deltaX))
angle = getAngleBetweenPoints(5, 2, 1,4)
assert angle >= 0, "angle must be >= 0"
angle = getAngleBetweenPoints(1, 1, 2, 1)
assert angle == 0, "expecting angle to be 0"
angle = getAngleBetweenPoints(2, 1, 1, 1)
assert abs(pi - angle) <= 0.01, "expecting angle to be pi, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 3)
assert abs(angle - pi/2) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 0)
assert abs(angle - (pi+pi/2)) <= 0.01, "expecting angle to be pi+pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(1, 1, 2, 2)
assert abs(angle - (pi/4)) <= 0.01, "expecting angle to be pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -2, -2)
assert abs(angle - (pi+pi/4)) <= 0.01, "expecting angle to be pi+pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -1, 2)
assert abs(angle - (pi/2)) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
All tests pass. See https://en.wikipedia.org/wiki/Unit_circle
fastest way to compute angle with x-axis
Check for y being zero as atan2 does; then The quotient x/y will be plenty fine. (assuming I understand you correctly).
How to find angle of point from x-axis independant of quadrant?
Use Math.atan2()
because it returns a value from 0->180 in the first two quadrants and -180->0 in the last 2.
Calculate angle (gradient) from a vector with x-axis
You could use the dot product (http://en.wikipedia.org/wiki/Dot_product) but simplifying it all out, you end up just taking the arctangent of the endpoint of your vector to get the angle between it and the x axis. Atan functions usually return on the order [-pi,pi] or [-180,180], so if you're looking to make sure it wraps correctly, you'll need to check to see if the y-component of your vector is negative. In C, you can use atan2 instead of atan, and it'll use the sign of each component to figure out the sign of the angle (http://www.cplusplus.com/reference/clibrary/cmath/atan2/).
For example, if you have the vector points start=<1,2> and end=<-5,-5>, adjust it back to the origin by subtracting the start from the end, giving you <-6,-7>. So you're looking at that point. The angle with the x-axis is atan2(y,x), atan2(-7,-6), which is -130.6.
double x = -6;
double y = -7;
fprintf(stderr,"angle is %.2f\n",atan2(y,x)*180/3.14159);
angle is -130.60
Line Equation with angle
An equation of a line is like:
m*x + n = y
m can be calculated by angle; m = tan(angle)
And if you know a start point then you can find n.
tan(angle) * startPoint_X + n = startPoint_Y
So n = startPoint_Y - (tan ( angle) * startPoint_X )
If you want to draw a line-segment and you know the length, the start point and the angle, there will be two equations.
The first is m*x + n = y
(we solved it).
And this means m*(endPoint_X) + n = endPoint_Y
The second is to find the endPoint.
length^2 = (endPoint_X - startPoint_X)^2 + (endPoint_Y - startPoint_Y)^2
There are only two things that still we don't know: endPoint_x & endPoint_Y
If we rewrite the equation:
length^2 = (endPoint_X - startPoint_X)^2 + ( m*(endPoint_X) + n - startPoint_Y)^2
now we know everything except endPoint_X.
This equation will give us two solutions for endPoint_X.
Then you can find two different ednPoint_Y.
calculate angle between horizontal axis and two points
I'm going to assume that your longitudinal coordinates represent the distance of each point along the x-axis and that your latitudinal coordinates represent the distance of each point along the y-axis. If this is an incorrect assumption let me know.
y
| (B)
| /|
| / |
| / |
| distance(AB) / |
| / | (LatB-LatA)
| / |
| / |
| / |
| /alpha |
| (A)----------
| (LonB-LonA)
|
|
|__________________________________ x
0
Then, in order to find your angle relative to the x-axis, you should apply one of the following rules:
sin(alpha) = (LatB - LatA) / distance(AB)
cos(alpha) = (LonB - LonA) / distance(AB)
tan(alpha) = (LatB - LatA) / (LonB - LonA)
By simply rearranging one of the equations by using the inverse of sin
, cos
, or tan
, you should be able to find alpha
in radians. For example...
alpha = Math.Asin((LatB - LatA) / distance(AB));
alpha = Math.Acos((LonB - LonA) / distance(AB));
alpha = Math.Atan((LatB - LatA) / (LonB - LonA));
Related Topics
How to Set -Source 1.7 in Android Studio and Gradle
How to Instantiate Non Static Inner Class Within a Static Method
How to Convert Between Iso-8859-1 and Utf-8 in Java
Spring Boot - Handle to Hibernate Sessionfactory
Reading Properties File in Java
What Is the Easiest Way to Parse an Ini File in Java
"Invalid Privatekey" When Using Jsch
Jackson Serialization: Ignore Empty Values (Or Null)
Java Filereader Encoding Issue
Setting the Default Font of Swing Program
Authenticated Http Proxy with Java
Hibernate: Automatically Creating/Updating the Db Tables Based on Entity Classes
Converting Utf-8 to Iso-8859-1 in Java - How to Keep It as Single Byte