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?
Step 1: Get the "raw" difference. For example, given -528.2
and 740.0
, this is 1268.2
.
raw_diff = first > second ? first - second : second - first
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
.
dist = mod_diff > 180.0 ? 360.0 - mod_diff : mod_diff
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)