在360度圆上给出两度。让我们称它们为源和目的地。
例如,Source可以是120度,Destination可以是30度。
对从源到目的地的哪个行进方向较短的问题有一个优雅的解决方案,即它是顺时针(增加度数)还是逆时针(降低度数)?
例如,对于上面给出的度数,解决方案将是:逆时针方向。另一方面,Source为350,Destination为20,则解决方案为:顺时针方向。
答案 0 :(得分:12)
if ((dest - source + 360) % 360 < 180)
// clockwise
else
// anti-clockwise
顺便说一下,顺时针==“增加度数”的约定是世界其他地方正在使用的the opposite of the Trigonometry 101 convention,因此令人困惑(无论如何,对我来说)。
答案 1 :(得分:3)
计算差异,然后将其标准化为+/- 180。正数表示沿增加角度的方向行进(在您的情况下为顺时针方向)。
答案 2 :(得分:1)
这是我用于游戏中相机的算法:
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
}
通过“包裹”角度我们可以计算差异。然后我们可以测试当前的差异与预测,看看哪个方向实际上会减少差异。
答案 3 :(得分:1)
这是我用来输出负数和正数两度之间的最短距离的函数。它也适用于0 - 360范围之外的降低。
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
答案 4 :(得分:0)
NPE 的回答很好,但是在取 360 的模数之前添加 360 是浪费时间,具体取决于语言。因此
if ((dest - source) % 360 < 180)
// clockwise
else
// anti-clockwise
请注意,Mod 函数必须返回绝对值。
例如
目标 = 5,来源 = 10
沃尔夫拉姆阿尔法
-5 modulo 360 = 355
Beckhoff 的结构化文本实现
LMOD(-5, 360) = -5
LMOD(-5+360, 360) = 355
MODABS(-5, 360) = 355
答案 5 :(得分:-3)
这里的一般答案是:“Modulo算术”。你可能想要阅读它,这是值得的。