2个角度之间的最小差异

时间:2009-12-10 06:01:33

标签: language-agnostic geometry angle

给定范围内的2个角度-PI - >围绕坐标的PI,它们之间的两个角度中最小的值是多少?

考虑到PI和-PI之间的差异不是2 PI而是零。

示例:

想象一个圆圈,从中心出来2条线,这些线之间有2个角度,它们在内部的角度也称为较小的角度,以及它们在外面,也就是更大的角度。加起来时两个角度都会形成一个完整的圆圈。鉴于每个角度都可以在一定范围内,考虑到翻转的小角度值是什么

9 个答案:

答案 0 :(得分:166)

这为任何角度提供了一个有角度的角度:

a = targetA - sourceA
a = (a + 180) % 360 - 180

谨防许多语言modulo操作返回一个与被除数符号相同的值(如C,C ++,C#,JavaScript,full list here)。这需要一个自定义mod函数,如下所示:

mod = (a, n) -> a - floor(a/n) * n

左右:

mod = (a, n) -> (a % n + n) % n

如果角度在[-180,180]之内,这也有效:

a = targetA - sourceA
a += (a>180) ? -360 : (a<-180) ? 360 : 0

以更详细的方式:

a = targetA - sourceA
a -= 360 if a > 180
a += 360 if a < -180

答案 1 :(得分:131)

x是目标角度。 y是来源或起始角度:

atan2(sin(x-y), cos(x-y))

返回有符号的delta角度。请注意,根据您的API,atan2()函数的参数顺序可能不同。

答案 2 :(得分:34)

如果你的两个角是x和y,那么它们之间的一个角是abs(x-y)。另一个角度是(2 * PI) - abs(x-y)。所以2个角度中最小的角度的值是:

min((2 * PI) - abs(x - y), abs(x - y))

这为您提供角度的绝对值,并假设输入已标准化(即:在[0, 2π)范围内)。

如果您想保留角度的符号(即:方向)并接受范围[0, 2π)以外的角度,您可以概括上述内容。这是通用版本的Python代码:

PI = math.pi
TAU = 2*PI
def smallestSignedAngleBetween(x, y):
    a = (x - y) % TAU
    b = (y - x) % TAU
    return -a if a < b else b

请注意,%运算符在所有语言中的行为都不相同,尤其是涉及负值时,因此如果需要移植某些符号调整,则可能是必要的。

答案 3 :(得分:8)

我接受了提供签名答案的挑战:

def f(x,y):
  import math
  return min(y-x, y-x+2*math.pi, y-x-2*math.pi, key=abs)

答案 4 :(得分:6)

对于UnityEngine用户,简单的方法就是使用Mathf.DeltaAngle

答案 5 :(得分:5)

Arithmetical(与算法相对)解决方案:

angle = Pi - abs(abs(a1 - a2) - Pi);

答案 6 :(得分:1)

无需计算三角函数。 C语言中的简单代码是:

#include <math.h>
#define PIV2 M_PI+M_PI
#define C360 360.0000000000000000000
double difangrad(double x, double y)
{
double arg;

arg = fmod(y-x, PIV2);
if (arg < 0 )  arg  = arg + PIV2;
if (arg > M_PI) arg  = arg - PIV2;

return (-arg);
}
double difangdeg(double x, double y)
{
double arg;
arg = fmod(y-x, C360);
if (arg < 0 )  arg  = arg + C360;
if (arg > 180) arg  = arg - C360;
return (-arg);
}

让dif = a - b,以弧度表示

dif = difangrad(a,b);

让dif = a - b,以度

dif = difangdeg(a,b);

difangdeg(180.000000 , -180.000000) = 0.000000
difangdeg(-180.000000 , 180.000000) = -0.000000
difangdeg(359.000000 , 1.000000) = -2.000000
difangdeg(1.000000 , 359.000000) = 2.000000

没有罪,没有cos,没有晒黑......只有几何!!!!

答案 7 :(得分:1)

C ++中的有效代码是:

inline double getAbsoluteDiff2Angles(const double x, const double y, const double c)
{
    // c can be PI or 180;
    return c - fabs(fmod(fabs(x - y), 2*c) - c);
}

答案 8 :(得分:0)

我在C ++中使用的一种简单方法是:

double deltaOrientation = angle1 - angle2;
double delta =  remainder(deltaOrientation, 2*M_PI);