Language agnostic 我怎样才能找出两个角度之间的差异?

Language agnostic 我怎样才能找出两个角度之间的差异?,language-agnostic,geometry,angle,Language Agnostic,Geometry,Angle,给定坐标周围-PI->PI范围内的2个角度,它们之间的2个角度中最小的值是多少 考虑到PI和-PI之间的差异不是2PI而是零 示例: 想象一个圆,有两条线从中心出来,这些线之间有两个角度,它们在内部形成的角度,即较小的角度,它们在外部形成的角度,即较大的角度。两个角度加起来就是一个完整的圆。假设每个角度都可以在一定范围内,考虑到侧翻,较小的角度值是多少?如果两个角度是x和y,那么其中一个角度是abs(x-y)。另一个角度是(2*PI)-abs(x-y)。因此,两个角度中最小的值为: min((2

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

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

示例:


想象一个圆,有两条线从中心出来,这些线之间有两个角度,它们在内部形成的角度,即较小的角度,它们在外部形成的角度,即较大的角度。两个角度加起来就是一个完整的圆。假设每个角度都可以在一定范围内,考虑到侧翻,较小的角度值是多少?如果两个角度是x和y,那么其中一个角度是abs(x-y)。另一个角度是(2*PI)-abs(x-y)。因此,两个角度中最小的值为:

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
PI=math.PI
TAU=2*PI
def smallestSignedAngleBetween(x,y):
a=(x-y)%TAU
b=(y-x)%TAU
如果a

请注意,
%
运算符在所有语言中的行为并不相同,特别是当涉及负值时,因此如果移植一些符号,则可能需要进行调整。

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

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

它返回带符号的增量角度。请注意,根据API的不同,atan2()函数的参数顺序可能不同。

我面临提供带符号答案的挑战:

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

这将为任何角度提供有符号的角度:

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

在许多语言中谨防<代码>模< /代码>操作返回与股息相同的符号(如C、C++、C、J、JavaScript)。这需要自定义<代码> mod < /C>函数,如下:

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+=(a>180)?-360:(a>180
如果a<-180,则a+=360
算术(与算法相反)解决方案:

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

不需要计算三角函数。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 = 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,没有晒黑,只有几何!!!< /p> < P>对于UNIYEY引擎用户,简单的方法就是使用。< /P> < P>一个C++的高效代码,适用于任意角度,两者都是:弧度和度是:

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

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

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

在我理解你的意思之前,我读了三遍。请添加一个例子,或者更好地解释…想象一个圆圈,有两条线从中心向外延伸,这些线之间有两个角度,它们在内侧形成的角度,也就是较小的角度,和它们在外侧形成的角度,也就是较大的角度。两个角度加在一起构成一个完整的角度圆圈。考虑到@JimG的翻滚可能重复,假设每个角度都可以在一定范围内,那么较小的角度值是多少。这不是同一个问题,在这个问题中,另一个问题中使用的角度P1将是不正确的答案,它将是另一个较小的角度。此外,也不能保证如果你使用Unity c#脚本,你可以使用Mathf.DeltaAngle函数。啊…顺便说一下,答案是Python函数。对不起,我在Python模式下呆了一会儿。希望没问题。我将把新公式插入到我楼上的代码中,看看结果如何!(谢谢^ ^ ^)我很肯定彼得伯的回答也是正确的。而且非常刻薄。:)但这一个不包含三角函数:)java的等效公式是什么?如果角度是度。更简单,更有意义,大声读出,虽然实际上是一样的,第一个bti计算出角度,第二个部分确保它总是2个可能角度中的较小者,尽管人们可能想要做一个%360,例如,如果我有一个agle 0和目标角度721,正确答案为1,上述答案为361A,更简洁,尽管可能更昂贵,相当于后一种方法的第二种说法,即
a-=360*sgn(a)*(abs(a)>180)
。(想想看,如果你已经实现了
sgn
abs
的无分支实现,那么这个特性实际上可能开始补偿需要两次乘法的需求。)“任何角度的符号角度”在大多数情况下,示例都是工作的,只有一个例外。在场景<代码>双目标A=2;双源代码= 359;< /COD> > a将等于-357,而不是C++中的3.0.您可以使用STD::fMOD(a,360),或fMOD(a,360)。使用浮点模。
x-y
提供角度差,但它可能超出所需的界限。请考虑此角度定义单位圆上的一个点。该点的坐标为
(cos(x-y),sin(x-y))
atan2
返回该点的角度(相当于
x-y
)除了它的范围是[-PI,PI]。这通过了测试套件一行简单的解决方案并为我解决了(不是选定的答案;)。但tan反转是一个代价高昂的过程。对我来说,这是最优雅的解决方案。遗憾的是,它可能在计算上很昂贵。对我来说,这也是最优雅的解决方案!完美地解决了我的问题(想得到一个公式,给我一个有符号的转弯角度,它是两个可能的转弯方向/角度中较小的一个)。错误!因为你把PIV2定义为“M#PI+M#PI”,而不是(M#PI+MŠPI)”,所以行
arg=arg-arg-PIV2;
扩展为
arg=arg-MŠPI+MŠPI
,所以什么都不做。如果abs(a1-a2)测试套件失败,测试失败>>>360.改用这个:@bradgonessurfing这是/是真的,但为了公平起见,您的测试检查了未指定的内容
inline double getAbsoluteDiff2Angles(const double x, const double y, const double c)
{
    // c can be PI (for radians) or 180.0 (for degrees);
    return c - fabs(fmod(fabs(x - y), 2*c) - c);
}
double deltaOrientation = angle1 - angle2;
double delta =  remainder(deltaOrientation, 2*M_PI);