Sign in to follow this  
Zmurf

Getting the True Bearing between 2 points. [Still Not Working]

Recommended Posts

How can I find the true bearing between 2 points? Ie; A . _ _ _ _ _ . B The true bearing of A from B would be 270o, but how can I work that out in code, given the coordinates of both? I've searched all over the forums and found nothing that helps me. [Edited by - Zmurf on November 4, 2005 11:59:13 PM]

Share this post


Link to post
Share on other sites
Heres the code i'm using, but it isn't working ><

double CLimb::PointDir(double x1, double y1, double x2, double y2){
double rise, run, dir;

rise = y2 - y1;
run = x2 - x1;

if (x1 > x2)
dir = 90 - atan(rise/run);
else
dir = 90 + atan(rise/run);

dir *= RADTODEG;


if (dir >= 360)
dir = dir - 360;
if (dir < 0)
dir = 360 - abs(dir);

return dir;
}


But i'm getting weird results, it's facing the opposite direction and and only seems to turn in a 90 degree area.

Share this post


Link to post
Share on other sites
Quote:
A . _ _ _ _ _ . B

The true bearing of A from B would be 270o, but how can I work that out in code, given the coordinates of both?
Given the usual convention of 0 degrees being along the +x axis, the solution would be:
float x = A.x-B.x;
float y = A.y-B.y;
float angle = atan2(y,x);
From your example it looks like you want a different orientation for 0 degrees, so you'll have to add some (integer) multiple of 90 to your result, or swap and/or negate the arguments to atan2().

For this particular problem you should prefer atan2() over atan() as it has better behavior over the range of inputs. Also, remember that c++ math functions work with radians, so you'll need to convert back and forth if you're using degrees.

Share this post


Link to post
Share on other sites
Well, for one in C/C++ the trig functions are in radians so I'm surprised you get turned within 90 degrees since atan is going to return values between -pi/2 and pi/2, i.e. ~+/-1.57. You have code for radians to degrees, buy you have that "90 - atan" in there before you get to it. Second you can use atan2 to get the full 0 to 2pi range so you don't need the if statements.

Share this post


Link to post
Share on other sites
hmm, my new code isn't working just right.

double PointDir(double x1, double y1, double x2, double y2){
double dir, x, y;

x = x2 - x1;
y = y2 - y1;

dir = atan2(y, x) * RADTODEG;

if (dir> 360)
dir = dir - 360;
if (dir < 0)
dir = 360 - abs(dir);

return dir;
}


Since atan2 gets the angle from the origin, i adjust the position its finding as if (x1, y1) were at the origin and looking to (x2, y2) so then it should return the correct direciton from xy1 to xy2. but for some reson it doesn't, instead its doing this:

A ....... 0....
...............
...............
....B..........X

A should be direction to X, but instead its facing to B.

It's kinda confusing but it's hard to explain.

Share this post


Link to post
Share on other sites
I'm not sure what your problem is here, you've got the direction vector from A to B being the vector X, your diagram appears to be correct. The direction vector in this case is the length and direction of how to get to point B from point A.

Share this post


Link to post
Share on other sites
Well i have a line, and i want the line to always point to the mouse, the line starts from A and heads to be, but the mouse is at X. The line should go from A -> X but it doesn't, i need to know how to fix my code so it does this.

Share this post


Link to post
Share on other sites
Is your code trying to calculate the amount to rotate the line to face X? Are you trying to do some interpolation to animate the line rotating from line AB to AX? I'm still not quite following, couldn't you just create a new line (Ax, Ay), (MouseX, MouseY) every time you detect the mouse moving and draw that line to the screen?

Share this post


Link to post
Share on other sites
Can't you just reassign your point B to be equal to the current mouse location? I don't see why this wouldn't work, if A was your achor point and B the mouse location you'd always be drawing a line from A to the current mouse location. If not, if you're looking for an angular relationship b/w the lines AB and AX and then take the dot product b/w these two lines.

Take the direction vector of AX and dot it with the direction vector of AB,
so you'd have acos(AX/|AX|*AB/|AB|) where || is the length of the vector and * is the dot product.

The dot product is defined as |AX|*|AB|Cos(T) = AXx*ABx + AXy*ABy so to solve for T you'd divide by the length of AX and AB and take the arccos of both sides.

Share this post


Link to post
Share on other sites
Try this. I dug it up from an old proggie of mine; it's in a BASIC dialect, but it should be easy enough to translate.

FUNCTION mathAngle2D% (x1 AS SINGLE, y1 AS SINGLE, x2 AS SINGLE, y2 AS SINGLE)
x = x1 - x2
y = (y1 - y2)

IF SGN(x) = 0 THEN
IF SGN(y) = 1 THEN
bearing = 0
ELSEIF SGN(y) = -1 THEN
bearing = 180
END IF
ELSE
refAngle = ATN(ABS(x) / ABS(y)) / (3.1416 / 180)
END IF

IF SGN(x) = 1 AND SGN(y) = 1 THEN
bearing = 360 - refAngle
ELSEIF SGN(x) = -1 AND SGN(y) = 1 THEN
bearing = refAngle
ELSEIF SGN(x) = -1 AND SGN(y) = -1 THEN
bearing = 180 - refAngle
ELSEIF SGN(x) = 1 AND SGN(y) = -1 THEN
bearing = 180 + refAngle
ELSEIF SGN(y) = 0 THEN
IF SGN(x) = 1 THEN
bearing = 270
ELSEIF SGN(x) = -1 THEN
bearing = 90
END IF
END IF
mathAngle2D = bearing
END FUNCTION


I believe this returns 0 degrees at 12 o'clock, 90 at three o clock and so on. However, rememmber that standard math puts 0 degrees at three o clock, 90 degrees at twelve o clock, 180 degrees at 9 o clock, etc...

--j_k

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this