8

I'm working in another iPhone App that uses AR, and I'm creating my own framework, but I'm having trouble trying to get the angle of a second coordinate relative to the current device position, anyone know a good resource that could help me with this?

Thanks in advance!

Paulo Ferreira
  • 423
  • 2
  • 8
  • 16

2 Answers2

17

If the two points are close enough together, and well away from the poles, you can use some simple trig:

float dy = lat2 - lat1;
float dx = cosf(M_PI/180*lat1)*(long2 - long1);
float angle = atan2f(dy, dx);

EDIT: I forgot to mention that latN and longN — and therefore dx and dy — can be in degrees or radians, so long as you don't mix units. angle, however, will always come back in radians. Of course, you can get it back to degrees if you multiply by 180/M_PI.

Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • Something seems a little off. dy is in degrees. It looks like your trying to convert dx to radians. But why is lat1 converted to radians then multiplied by the delta longitude? But otherwise, atan2() should work for close points as you say. – Alex Blakemore Sep 28 '10 at 02:36
  • @Alex: dx and dy are both in degrees. But dx has to be scaled by the cosine of the latitude, and cosf requires radians. – Marcelo Cantos Sep 29 '10 at 13:04
  • @MarceloCantos hope you're still around. I realize this is old. Anyway, please define 'close enough together'. – Aeluned Mar 13 '13 at 00:54
  • @Aeluned: Several hundred km. If you're worried about accuracy, your best bet is to convert the coordinates to 3-space and use cross products. It's a bit tricky, so if you want the details, create a new question (and add a response to this comment with a link so I know about it). I'm at work (It's midday here.), but I can provide the details tonight if no one else does in the meantime. – Marcelo Cantos Mar 13 '13 at 01:07
  • @MarceloCantos Thanks, that should be good enough for my purposes. I've been playing around with this a bit. An angle between 2 points makes no sense. Is this the angle calculated from true or magnetic north somehow? I'd like to know the bearing to a gps point with respect to my current location and heading. So, that needs to factor in somehow. – Aeluned Mar 20 '13 at 14:02
  • @Aeluned: My answer computes the compass bearing from one point to another. To compute a bearing with respect to a heading, simply subtract angles (and handle edge cases). – Marcelo Cantos Mar 21 '13 at 02:28
  • @MarceloCantos thanks again. I had been actually subtracting current heading from bearing but things just didn't seem right. I'm hoping this isn't the case but I think the device may not be accurate enough in small enough distances (say 30-50 feet), because the bearing calculation which I found [here](http://www.movable-type.co.uk/scripts/latlong.html) results in the angle jumping all over the place. I hardcoded the gps coordinates to a friends house who lives a town over and sure enough the bearing calculation is spot on. Thank you for all your help so far. – Aeluned Mar 21 '13 at 23:58
  • 2
    this formula is wrong, shame on all acceptors. an angle between two geo locations is limited to range 0 - 360. related to geo north = 0 degrees, clockwise raising. your formula returns mathematical angles with 0 = east, counterclockwise, and in range -pi,pi. – AlexWien Jun 26 '13 at 10:30
  • 2
    @AlexWien: I've used this formula to produce demonstrably correct programs, so the statement "this formula is wrong" is false. Sure, it uses a different basis — one that mathematicians (and I) prefer, in fact (`atan2f(dy, dx)` corresponds closely to the formula atan(*y*/*x*) found in any good math text). Your basis may be an established norm in geospatial work that we should follow for the sheer benefit of having a convention. If you had argued this (with links) instead of just saying I'm wrong and wagging your finger at upvoters, I'd be cheering you all the way (If you do so, I still might). – Marcelo Cantos Jun 27 '13 at 01:19
  • (Please ignore the asterisks in `y*/*x`. That was a foiled attempt to italicise the variables, which I didn't spot until moments after the (extremely annoying) five-minute window closed.) – Marcelo Cantos Jun 27 '13 at 01:27
1

Here is the android version of this code

import com.google.android.maps.GeoPoint;
    public double calculateAngle(GeoPoint startPoint, GeoPoint endPoint) {
        double lat1 = startPoint.getLatitudeE6() / 1E6;
        double lat2 = endPoint.getLatitudeE6() / 1E6;
        double long2 = startPoint.getLongitudeE6() / 1E6;
        double long1 = endPoint.getLongitudeE6() / 1E6;
        double dy = lat2 - lat1;
        double dx = Math.cos(Math.PI / 180 * lat1) * (long2 - long1);
        double angle = Math.atan2(dy, dx);
        return angle;
    }
u.jegan
  • 833
  • 6
  • 15