Algorithm or formula for the shortest direction of travel between two degrees on a circle?
Asked Answered
L

6

8

Given two degrees on a 360 degree circle. Lets call them Source and Destination.

For example Source could be 120 degrees and Destination could be 30 degrees.

Is there an elegant solution to the question of which direction of travel from Source to Destination is shorter, i.e. is it shorter clockwise (increasing the degrees) or anti clockwise (decreasing the degrees)?

For example with the degrees given above then the solution would be: Go anti clockwise. On the other hand with Source as 350 and Destination as 20 then the solution would be: Go clockwise.

Lammastide answered 15/9, 2011 at 9:30 Comment(2)
Travel is around the circumference of the circle right?Thaddeusthaddus
Yes. Only the direction is needed, not the distance.Lammastide
I
3

Compute the difference, then normalise it to +/-180. Positive numbers indicate travel in the direction of increasing angle (clockwise in your case).

Interventionist answered 15/9, 2011 at 9:34 Comment(8)
This explanation really needs code. By itself this basically just re-iterates the question.Respect
It depends... I speak English. Do you speak English, or some kind of really vague and undescriptive dialect of that same language? The point I was making is that the OP is literally asking you how to "compute the difference" - that IS the question. By saying "normalise it to +/-180" lacks sufficient context and explanation. The term "normalise" literally has hundreds of interpretations. The OP already knows he needs the "shortest direction" - you are literally re-iterating the question. If you need an example of what an answer looks like, refer to NPE's answer below. Thanks.Respect
@Respect No I'm not. It may be obvious to you that that's how to compute differential angles, it's not obvious that it was obvious to the OP. You are projecting your level of understanding onto others.Interventionist
It is obvious to me. You said "normalise it to +/-180" and the OP said "is it shorter clockwise (increasing the degrees) or anti clockwise (decreasing the degrees)?". Which is the same thing except your response is vaguer and more open to interpretation. I don't understand why you are defending this 1 sentence answer. I just suggested you should post some code to illustrate your explanation, and then you implied I don't understand English. I expect better from someone with so much rep.Respect
Actually to be fair, the OP doesn't mention a single programming language. This whole answer probably belongs on the Math forum...Respect
@Respect the OP was asking about a pair of angles. It is not uncommon for developers to try to solve this using quadrant analysis and multiple edge cases, and get themselves into knots. The idea of computing the difference and clamping to a range may be obvious to you, but it most likely wasn't obvious to the OP, otherwise they would have said so in the original question.Interventionist
I can see where you are coming from now, that's probably fair. For the record though this would have been a better response than implying I don't understand English.Respect
@Respect Agreed, been a long week, feeling a bit tetchy. Sorry.Interventionist
P
16
if ((dest - source + 360) % 360 < 180)
  // clockwise
else
  // anti-clockwise

BTW, your convention that clockwise == "increasing the degrees" is the opposite of the Trigonometry 101 convention that the rest of the world is using, and is therefore confusing (was to me, anyhow).

Publicspirited answered 15/9, 2011 at 9:37 Comment(1)
while trig should certainly be a standard, in CSS positive rotation is CW, negative is CCWReddish
Y
4

This is the function I use to output the shortest distance between two degrees with negative and positive numbers. It also works on degress outside the 0 - 360 ranges.

function shortestDistDegrees(start, stop) {      
  const modDiff = (stop - start) % 360;
  let shortestDistance = 180 - Math.abs(Math.abs(modDiff) - 180);
  return (modDiff + 360) % 360 < 180 ? shortestDistance *= 1 : shortestDistance *= -1;
}

shortestDistDegrees(50, -20)   // Output: -70
shortestDistDegrees(-30, -370) // Output: 20
shortestDistDegrees(160, -710) // Output: -150
Yorker answered 14/12, 2017 at 15:58 Comment(0)
I
3

Compute the difference, then normalise it to +/-180. Positive numbers indicate travel in the direction of increasing angle (clockwise in your case).

Interventionist answered 15/9, 2011 at 9:34 Comment(8)
This explanation really needs code. By itself this basically just re-iterates the question.Respect
It depends... I speak English. Do you speak English, or some kind of really vague and undescriptive dialect of that same language? The point I was making is that the OP is literally asking you how to "compute the difference" - that IS the question. By saying "normalise it to +/-180" lacks sufficient context and explanation. The term "normalise" literally has hundreds of interpretations. The OP already knows he needs the "shortest direction" - you are literally re-iterating the question. If you need an example of what an answer looks like, refer to NPE's answer below. Thanks.Respect
@Respect No I'm not. It may be obvious to you that that's how to compute differential angles, it's not obvious that it was obvious to the OP. You are projecting your level of understanding onto others.Interventionist
It is obvious to me. You said "normalise it to +/-180" and the OP said "is it shorter clockwise (increasing the degrees) or anti clockwise (decreasing the degrees)?". Which is the same thing except your response is vaguer and more open to interpretation. I don't understand why you are defending this 1 sentence answer. I just suggested you should post some code to illustrate your explanation, and then you implied I don't understand English. I expect better from someone with so much rep.Respect
Actually to be fair, the OP doesn't mention a single programming language. This whole answer probably belongs on the Math forum...Respect
@Respect the OP was asking about a pair of angles. It is not uncommon for developers to try to solve this using quadrant analysis and multiple edge cases, and get themselves into knots. The idea of computing the difference and clamping to a range may be obvious to you, but it most likely wasn't obvious to the OP, otherwise they would have said so in the original question.Interventionist
I can see where you are coming from now, that's probably fair. For the record though this would have been a better response than implying I don't understand English.Respect
@Respect Agreed, been a long week, feeling a bit tetchy. Sorry.Interventionist
T
1

This is the algorithm I use for my in-game cameras:

rotSpeed = 0.25;                      //arbitrary speed of rotation

angleDiff      = 180-abs(abs(source-dest)-180);            //find difference and wrap
angleDiffPlus  = 180-abs(abs((source+rotSpeed)-dest)-180); //calculate effect of adding
angleDiffMinus = 180-abs(abs((source-rotSpeed)-dest)-180); //           ... subtracting

if(angleDiffPlus < angleDiff){        //if adding to ∠source reduces difference
    source += rotSpeed;               //add to ∠source
}else if(angleDiffMinus < angleDiff){ //if SUBTRACTING from ∠source reduces difference
    source -= rotSpeed;               //subtract from ∠source
}else{                                //if difference smaller than rotation speed
    source = dest;                    //set ∠source to ∠destination
}

By "wrapping" the angle we can calculate difference. We can then test the current difference versus predictions to see which direction would actually reduce the difference.

Totalitarian answered 3/11, 2016 at 5:49 Comment(0)
N
0

NPE's answer is good, but adding 360 before taking the modulo of 360 is a waste of time depending on the language. Therefore

if ((dest - source) % 360 < 180)
  // clockwise
else
  // anti-clockwise

Note that the Mod function has to return absolute values. For example
dest = 5, source = 10
wolfram alpha

-5 modulo 360 = 355

Beckhoff's implementation of Structured Text

LMOD(-5, 360) = -5
LMOD(-5+360, 360) = 355
MODABS(-5, 360) = 355
Nonjoinder answered 16/3, 2021 at 11:26 Comment(0)
R
-4

The general answer here is: "Modulo arithmetics". You might want to read up on that, it's worth it.

Rior answered 15/9, 2011 at 11:15 Comment(5)
Normalized is a better description I think as it we are working with negative numbers. Modulo gets a bit fuzzy when working with negative numbers.Lammastide
Well, "normalization" is a pretty general term, and it doesn't really matter whether you normalize to +/- 180 and compare with 0 (Marcelo Cantos) or if you compute the difference modulo 360 and compare it to 180 (aix).Rior
True, but personally I prefer the term normalization when working with a generic numbers. It is though of course just a question of preference.Lammastide
Sure. Just wanted to make sure you got the general idea behind the algorithm - that, when computing in a wrap-around space, modulo arithmetics is the key idea.Rior
Yep, thanks. I've used modulus arithmetic extensively in my code but a refresher course in Trigonometry is I think needed. :)Lammastide

© 2022 - 2024 — McMap. All rights reserved.