views:

112

answers:

1

Very "simple" problem: given two CLLocationCoordinate2Ds, how can I get the bearing (as radians) from the first to the second? I've done a lot of research and studying on this, both the general problem and Objective-C/Cocoa Touch/iOS specifically.

Here's my implementation:

- (float) getHeadingForDirectionFromCoordinate:(CLLocationCoordinate2D)fromLoc toCoordinate:(CLLocationCoordinate2D)toLoc
{
    float fLat = fromLoc.latitude;
    float fLng = fromLoc.longitude;
    float tLat = toLoc.latitude;
    float tLng = toLoc.longitude;

    return atan2(sin(fLng-tLng)*cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(fLng-tLng));         
}

However, this method isn't returning consistant results for me. If the bearing is close to due north or due south, it seems to be fine, however, any other direction seems to return inconsistant data, for example:

From 50.405018, 8.437500

To 51.339802, 12.403340

My method returns: 5.918441 radians

Should be 1.18660576 radians

(see http://www.movable-type.co.uk/scripts/latlong.html and http://www.movable-type.co.uk/scripts/latlong-map.html?lat1=50.405018&long1=8.437500&lat2=51.339802&long2=12.403340)

I've double and triple checked the formula is correct. I've also spot checked a bunch of values like the example above, some correct, some wrong. I've played around with various modulos or bounding of the return value, also no luck.

Any ideas? Is there an issue with my code? Maybe I've misunderstood something about how math functions work?

+2  A: 

Your math is correct, with the following exceptions:

  1. Make sure to convert fLat, fLon, tLat, and tLon to radians before applying any sin() or cos() to them. Divide by 180.0 and multiply by PI.

  2. Enter the delta between tLng and fLng as tLng-fLng, and not the other way around. Note that this difference appears twice in the expression.

With those changes, I am getting 1.18660677830947 radians with double precision math and the values in the question.

Oren Trutner
My initial reaction was "convert latitude/longitude to radians? what manner of madness is this?" Then I actually tried it, works like a charm.
jenningj
Good point. The use of degrees in geographic latitude and longitude is so ingrained, that it's easy to forget that they describe angles in the sphere geometry of the Earth. The trig functions in most modern languages expect radians, forcing the conversion.
Oren Trutner
Can you explain 2? What if fLng is larger?
Nick
if fLng>tLng than tLng-fLng will be a negative number. This is okay! The arithmetic will still work fine in that case -- in fact, having the negative value is vital for the correctness of the result.
Oren Trutner