Calculate Direction Using Two Lat/Lon Coordinate Pairs

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

This is probably more of a math question than a programming question, but I'm stumped on this one. I bought a GPS receiver for my laptop the other day, and I have been playing with some coordinate calculations. Oddly enough, the GPS doesn't provide speed and direction data - it only provides position data (lat/lon) and other pointless (to me) information, like which satellites it has a fix on, signal strength, etc.

I have found a math formula to calculate the distance between two lat/lon pairs, and from that, I can get the current speed. What I can't figure out is how to find the direction from one point to another (like north, south, etc).

So the question is, how can one calculate the direction traveled to get from one point to another, given two lat/lon pairs?

He has: 698 posts

Joined: Jul 2005

I'm not really sure how the degrees of lat/lon are given to you, but here's my thinking:

To figure the direction from one lat/lon pair to another, find the slope (remember slope from high school math?) between the two pairs. Latitude would be like the y-axis on a graph, and longitude would be like the x-axis on the graph. Treat degrees longitude east of Prime Meridian as positive and degrees west of the line should be changed to negative values. Same for degrees latitude above and below the equator, respectively. Then, create two points: (lon1,lat1),(lon2,lat2) and find the slope:

(lat2-lat1)/(lon2-lon1) would be the slope, and then we can determine the direction based on the value of this number:

if slope = 0, then direction is either east or west (determine using denominator)
if slope = (DIVISION BY ZERO ERROR), then direction is either north or south (I would actually check the denominator for zero first to determine this to avoid an actual PHP error)
if slope > 0, then direction is northeast or southwest (determine by comparing actual lat/lon values
if slope < 0, then direction is northwest or southeast (same as before)

Hope this helped a little...if not, I can explain in more detail. Wink

Kurtis

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

That was my initial thought. I could also subtract lat2 - lat1. A negative number would yield one direction, and the other would be the other direction. Same for lon2 - lon1. The problem with both of these methods is that I was looking for a more specific result, like a number from 0 to 360. Simple programs like this one can do it.

He has: 698 posts

Joined: Jul 2005

Well, I don't have much time to pluck through it right now, but this site does those computations and provides the source behind it. You're going for the bearing, if I'm not mistaken. Wink

Kurtis

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

Thanks for that link - I'm going to try this forumla:

ATAN2(COS(lat1)*SIN(lat2)-SIN(lat1)*COS(lat2)*COS(lon2-lon1), SIN(lon2-lon1)*COS(lat2))

When I look up sin() in the PHP manual, it says that the parameter must be provided in radians, not degrees. This is probably a stupid question, but the lat/lon "degrees" is different from the angle "degree", correct? Or do I need to pass the coordinates through the deg2rad() function first?

He has: 698 posts

Joined: Jul 2005

Nope, degrees are degrees. Wink

greg's picture

He has: 1,581 posts

Joined: Nov 2005

Your suggesting lat2-lat1 isn't going to allow for accuracy.
Subtracting lat1 from lat2 would work MOST times on a basic journey of one point to another, as would Kurtis' idea of checking which was the greater.

But if you want more accuracy and provide for any possible journey around a globe, you obviously need to carry out a lot more checks to determine various things. (I'm sure you both knew that, but it's an interesting topic and I wanted to chip in Laugh)

What if one of the two points goes beyond either pole, you travel from lat2 at +60, past the south pole (-90) and back beyond the north pole to +70. The cardinal direction would show north - lat2-lat1=+10, and you'd get the same result if you simply determine which is the greater value of the two.
Or what if you traveled east across the equator? Last time I looked, 0 minus 0 equals 0.
That of course is simply a check if lat1=0 && lat2=0 you are trying to determine if east or west, even then you may pass beyond the -180 or +180 and still need the additional checks the same as with latitude passing a pole.

You could also calculate intercardinal, and cardinal or intercardinal directions for each point on a journey.
2.5 miles south-east, then 1 mile south, then 3 miles south-west etc.

Hmm, interesting...sounds like a fun set of if/elses Laugh

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

I'm getting the direction from the last two coordinates from the GPS, usually 1-3 seconds apart. It would only give an inaccurate reading for a couple seconds when I cross the 0 degree line. I can live with that. Smiling

Or what if you traveled east across the equator?

You can travel east all you want...you won't cross the equator. Wink

greg's picture

He has: 1,581 posts

Joined: Nov 2005

pr0gr4mm3r wrote:
You can travel east all you want...you won't cross the equator. ;)
That was my point
greg wrote:
Or what if you traveled east across the equator?

I know wording could have been better, such as "along" the equator, but I thought lat2-lat1=0 would have pointed to that.

The degrees are angular degrees, as it's for a sphere.
360° circumference

They have: 8 posts

Joined: Jan 2009

As a soon to be maths graduate I can tell you that this would be easiest solved in a polar coordinates system (as that is basically what lat and lon lines are). You can then calculate the arc length easily to give you the distance travelled and as it is all in a nice vector you can process it correctly to give an accurate direction of travel as well. It would also allow you to deal with your issue of moving over the poles etc.

If you want any more math help on it let me know.

They have: 1 posts

Joined: Mar 2009

The shot is assigned an X-coordinate by adding (type 1) or multiplying
(type 2) DFLS (distance from the last shot) to the X-coordinate of the
shot. Each receiver is assigned an X-coordinate by adding the
shot-receiver distance to the shot X-coordinate. The RP X-coordinate
is calculated by assuming the RP is halfway between the shot and
receiver. The RP number is the RP X-coordinate divided by DBRPS
(distance between RPs) and truncating to an integer. The coordinate of
the first shot of the job is the shot number (from the header) times the
distance from the previous shot. i.e.
xs = FLOAT(lhead(3)) * dfls
rx = FLOAT(lhead(10))
xr = xs + rx
xrp = (xr + xs) / 2.
lhead(6) = NINT( xrp/dbrps )

[Mod Edit: Link removed. Please use your forum signature instead, cheers]

Want to join the discussion? Create an account or log in if you already have one. Joining is fast, free and painless! We’ll even whisk you back here when you’ve finished.