Shortest distance between two degree marks on a circle?

Joe Lyga picture Joe Lyga · Feb 29, 2012 · Viewed 12.8k times · Source

I'm looking for a formula to find the shortest distance in degrees between two degree marks on a circle: for instance, 30 degrees and 170 degrees (140 degrees).

The two degree marks can be virtually any real number, and isn't necessarily between 0 and 360 (can be negative, or much greater than 360, for instance -528.2 and 740 (which is 171.8 degrees)). However, the distance should always be <= 180 degrees and >= 0 degrees.

It sounds simple enough. But, I've been trying to find a good solution for this and I've tried a lot of different code but nothing I've found so far works in all the cases I've tried. I'm working in c++. Does anyone have any ideas?

Answer

ruakh picture ruakh · Feb 29, 2012
  • Step 1: Get the "raw" difference. For example, given -528.2 and 740.0, this is 1268.2.

    • one way: raw_diff = first > second ? first - second : second - first
    • another way: raw_diff = std::fabs(first - second)
  • Step 2: Subtract a multiple of 360.0 to get a value between 0.0 (inclusive) and 360.0 (exclusive).

    • mod_diff = std::fmod(raw_diff, 360.0)
  • Step 3: If this value is greater than 180.0, subtract it from 360.0.

    • one way: dist = mod_diff > 180.0 ? 360.0 - mod_diff : mod_diff
    • another way: dist = 180.0 - std::fabs(mod_diff - 180.0)

It's probably most readable as a series of statements:

double raw_diff = first > second ? first - second : second - first;
double mod_diff = std::fmod(raw_diff, 360.0);
double dist = mod_diff > 180.0 ? 360.0 - mod_diff : mod_diff;

But if desired, it's not hard to put it all into a single expression:

180.0 - std::fabs(std::fmod(std::fabs(first - second), 360.0) - 180.0)