圆上两度之间最短行进方向的算法或公式?

发布于 2024-12-04 11:15:08 字数 206 浏览 7 评论 0原文

给定 360 度圆上的两个度数。我们称它们为源和目的地。

例如,源可以是 120 度,目标可以是 30 度。

对于从源到目的地哪个方向的行进较短的问题,是否有一个优雅的解决方案,即顺时针(增加度数)或逆时针(减少度数)较短?

例如,对于上面给出的度数,解决方案将是:逆时针旋转。另一方面,如果源为 350,目标为 20,那么解决方案是:顺时针方向走。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

星星的轨迹 2024-12-11 11:15:09
if ((dest - source + 360) % 360 < 180)
  // clockwise
else
  // anti-clockwise

顺便说一句,您的约定顺时针==“增加度数”与世界其他地方正在使用的三角学 101 约定相反,因此令人困惑(无论如何,对我来说)。

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

浴红衣 2024-12-11 11:15:09

这是我用来输出带负数和正数的两度之间的最短距离的函数。它还适用于 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

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
蓬勃野心 2024-12-11 11:15:09

计算差异,然后将其标准化为 +/-180。正数表示沿角度增加的方向行驶(在您的情况下为顺时针方向)。

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

々眼睛长脚气 2024-12-11 11:15:09

这是我在游戏摄像机中使用的算法:

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
}

通过“包裹”角度,我们可以计算差异。然后,我们可以测试当前差异与预测,看看哪个方向实际上会减少差异。

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.

心头的小情儿 2024-12-11 11:15:09

NPE 的答案很好,但是在取 360 的模之前加上 360 是浪费时间,具体取决于语言。因此

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

请注意,Mod 函数必须返回绝对值。
例如
目标 = 5,源 = 10
Wolfram alpha

-5 modulo 360 = 355

Beckhoff 的结构化文本实现

LMOD(-5, 360) = -5
LMOD(-5+360, 360) = 355
MODABS(-5, 360) = 355

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
明天过后 2024-12-11 11:15:09

这里的一般答案是:“模算术”。您可能想阅读相关内容,这是值得的。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文