给定坐标周围 -PI -> PI 范围内的 2 个角度,它们之间的 2 个角度中最小的值是多少?
考虑到 PI 和 -PI 之间的差异不是 2 PI 而是零。
例子:
想象一个圆,有 2 条线从中心出来,这些线之间有 2 个角度,它们在内侧形成的角度称为较小的角度,而它们在外侧形成的角度也称为较大的角度。两个角加起来就是一个完整的圆。假设每个角度都可以在一定范围内拟合,那么较小的角度值是多少,考虑到翻转
给定坐标周围 -PI -> PI 范围内的 2 个角度,它们之间的 2 个角度中最小的值是多少?
考虑到 PI 和 -PI 之间的差异不是 2 PI 而是零。
例子:
想象一个圆,有 2 条线从中心出来,这些线之间有 2 个角度,它们在内侧形成的角度称为较小的角度,而它们在外侧形成的角度也称为较大的角度。两个角加起来就是一个完整的圆。假设每个角度都可以在一定范围内拟合,那么较小的角度值是多少,考虑到翻转
这给出了任何角度的有符号角度:
a = targetA - sourceA
a = (a + 180) % 360 - 180
请注意,在许多语言中,该modulo
操作会返回一个与被除数符号相同的值(如 C、C++、C#、JavaScript,此处为完整列表)。这需要一个自定义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
x 是目标角度。y 是源或起始角度:
atan2(sin(x-y), cos(x-y))
它返回有符号的增量角。请注意,根据您的 API,atan2() 函数的参数顺序可能会有所不同。
如果您的两个角度是 x 和 y,那么它们之间的角度之一是 abs(x - y)。另一个角度是 (2 * PI) - abs(x - y)。所以两个角度中最小的一个值为:
min((2 * PI) - abs(x - y), abs(x - y))
这为您提供了角度的绝对值,并假设输入已标准化(即:在 range 内[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
请注意,%
运算符在所有语言中的行为并不相同,尤其是在涉及负值时,因此如果移植,可能需要进行一些符号调整。
我面临提供签名答案的挑战:
def f(x,y):
import math
return min(y-x, y-x+2*math.pi, y-x-2*math.pi, key=abs)
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);
}
对于 UnityEngine 用户,简单的方法就是使用Mathf.DeltaAngle。
算术(相对于算法)解决方案:
angle = Pi - abs(abs(a1 - a2) - Pi);
我在 C++ 中使用的一个简单方法是:
double deltaOrientation = angle1 - angle2;
double delta = remainder(deltaOrientation, 2*M_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 = difangrad(a,b);
让 diff = 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,没有棕褐色,....只有几何!!!!