Search code examples
c++trigonometrygeometry

Shortest distance between two degree marks on a circle?


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?


Solution

    • 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)