Calculating the Angle Between a Line and the X-Axis

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:

  1. Treat (deltaX, deltaY) as a vector.
  2. Normalize that vector to a unit vector. To do so, divide deltaX and deltaY by the vector's length (sqrt(deltaX*deltaX+deltaY*deltaY)), unless the length is 0.
  3. 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 at P1).
  4. And deltaY will now be the sine of that angle.
  5. 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 and deltaY will tell you which quadrant the angle is in, in relation to the positive X axis at P1:

    • +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



Leave a reply



Submit