查找一个角度是否与另一个角度相差不超过X度

8
我需要一种算法来确定一个角度是否与另一个角度相差一定角度。我的第一个想法是 (a-x < b) && (a+x > b),但当它必须处理从-179到180的角度时,它会失败。在上图中,角度必须在绿色区域内,该区域(绿色)在负侧和正侧之间环绕。我如何确定角度(红线)是否落在此区域内?

尝试使用更新版本。 - cletus
5个回答

6
尝试使用这个公式:
360-(|a-b|)%360<x || (|a-b|)%360<x

或者,在PHP中

<?php

$b = 10;
$angle1 = -179;
$angle2 = 180;

$diff = $angle1 - $angle2;
if(abs($diff % 360) <= $b || (360-abs($diff % 360))<=$b) {
  echo "yes";
} else {
  echo "no";
}

?>

2
正如Marcel所指出的,对负数取模可能会有问题。另外,355度和5度之间有什么区别?它可能被计算为350度,但人们可能期望的是10度。我们做出以下假设:
  1. 我们想要两个角之间最小的正角度,因此 0 <= diff <= 180
  2. 我们使用度数进行计算。如果使用弧度,请将360替换为 2*PI
  3. 角度可以是正数或负数,可以超出范围 -360 < x < 360,其中x是输入角度;
  4. 输入角度的顺序或差异的方向不重要。

输入:角度a和b。因此,算法很简单:

  1. 将a和b归一化为 0 <= x < 360
  2. 计算两个归一化角度之间的最短角度。

对于第一步,将角度转换为所需范围,有两种可能性:

  • x >= 0:normal = x % 360
  • x < 0:normal = (-x / 360 + 1) * 360 + x

第二个步骤旨在消除负模数操作解释上的任何歧义。因此,对于x = -400,我们给出一个示例:

  -x / 360 + 1
= -(-400) / 360 + 1
= 400 / 360 + 1
= 1 + 1
= 2

那么

normal = 2 * 360 + (-400)
       = 320

对于输入的10和-400,正常角度分别为10和320。

现在我们计算它们之间的最短角度。作为一项合理性检查,这两个角度的总和必须为360。在这种情况下,可能性是50和310(画出来你会看到这一点)。要计算它们:

normal1 = min(normal(a), normal(b))
normal2 = max(normal(a), normal(b))
angle1 = normal2 - normal1
angle2 = 360 + normal1 - normal2

所以针对我们的例子:
normal1 = min(320, 10) = 10
normal2 = max(320, 10) = 320
angle1 = normal2 - normal1 = 320 - 10 = 310
angle2 = 360 + normal1 - normal2 = 360 + 10 - 320 = 50

请注意:normal1 + normal2 = 360,如果您愿意,甚至可以证明这一点。

最后:

diff = min(normal1, normal2)

在我们的情况下,或者说是50。


你在angle1和angle2之间打错字了吗? - Charlie Salts
1
在某些编程语言中,对可能为负数的数值(diff)进行取模运算可能是危险的。 - Marcel Jackwerth
1
这是否依赖于角度为0-360,还是我可以将其用于角度在-180到180之间的情况? - user47322

2

你也可以使用点积:

cos(a)*cos(b) + sin(a)*sin(b) >= cos(x)

1
这非常优雅,一次性消除了歧义。 - ryanskeith

1

对于半径为1的情况,线段端点之间的距离为2sin((a-b/2))。因此,忽略掉2,因为你只关心比较,然后将sin(x/2)与sin((a-b)/2)进行比较。三角函数会处理所有的包裹问题。


0

c++ 实现:

float diff = fabsf(angle1 - angle2);
bool isInRange = fmodf(diff, 360.0f) <= ANGLE_RANGE ||
                 360.0f - fmodf(diff, 360.0f) <= ANGLE_RANGE;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接