Rob Miracle
Rob Miracle

Reputation: 3063

How can I calculate the relative angle between two points like a compass?

I'm building an app that given a latitude and longitude of a location and the lat, long of my current location, I want to point an arrow toward the destination. I can get the angle to the point in a 0-360 degree value. I can also get my compass heading in degrees as well. Using this formula:

deltaAngle = abs( floor( compassHeading - gpsAngle ) )

For the most part it works, through when the compassHeading moves from 0 to 359 the pointer jumps about 90 degrees. Here is the output as I near 0 degrees:

angle:  317.86451281503 compass 358.80545043945 deltaAngle: 40  40.940937624423 
angle:  317.86451281503 compass 357.77563476562 deltaAngle: 39  39.911121950595
angle:  317.86451281503 compass 358.86737060547 deltaAngle: 41  41.002857790438
angle:  317.86451281503 compass 359.96002197266 deltaAngle: 42  42.095509157626
angle:  317.86451281503 compass 1.178640127182  deltaAngle: 317 -316.68587268785
angle:  317.86451281503 compass 2.3249001502991 deltaAngle: 316 -315.53961266473 

How can I work out the math near this point? I have a feeling that a % 180 is going to be involved and then adding or subtracting something if I need to be pointing left or right.

Upvotes: 0

Views: 2598

Answers (2)

Daniel Martin
Daniel Martin

Reputation: 23548

You don't actually want to use abs in your formula for deltaAngle. Instead, what you want is this, or something like it:

deltaAngle = floor( compassHeading - gpsAngle )
if (deltaAngle < 0) {
    deltaAngle += 360
}

In some languages, you can dispense with the if statement, and use something like this: (which will work in python, but WILL NOT WORK in C or java or javascript)

deltaAngle = floor( compassHeading - gpsAngle ) % 360

Unfortunately, C has a silly definition of % when the first number is negative, and both Java and Javascript (and many other languages) have inherited C's definition, instead of the more sensible one Python and Ruby use. In languages that get their % definition from C, you can do:

deltaAngle = floor( compassHeading - gpsAngle + 360) % 360

But at that point, I think that as a matter of style it's just easier to use the if statement.

Upvotes: 2

Eric J.
Eric J.

Reputation: 150108

Note that 360 - 317 = 43. You can get to the heading by going 43 degrees to the left, or 317 degrees to the right. They are equivalent, mathematically (if you are physically turning, there is more turning involved to go to the right).

It sounds like you want to normalize the angle to the "shortest" angle. You can accomplish that by noting when the deltaAngle > 180.0. When it is, convert to the shorter angle by substituting 360.0 - deltaAngle.

Upvotes: 1

Related Questions