Tom*_*ell 127 language-agnostic geometry angle
给定坐标范围内的2个角度-PI - > PI,它们之间的两个角度中最小的值是多少?
考虑到PI和-PI之间的差异不是2 PI而是零.
例:
想象一个圆圈,从中心出来2条线,这些线之间有2个角度,它们在内部的角度也就是较小的角度,以及它们在外部产生的角度,也就是更大的角度.加起来时两个角度都会形成一个完整的圆圈.假设每个角度都可以在一定范围内,那么考虑到翻转,角度值越小
ben*_*ich 175
这为任何角度提供了一个有角度的角度:
a = targetA - sourceA
a = (a + 180) % 360 - 180
Run Code Online (Sandbox Code Playgroud)
请注意,在许多语言中,modulo操作返回一个与被除数相同符号的值(如C,C++,C#,JavaScript,此处为完整列表).这需要一个自定义mod函数,如下所示:
mod = (a, n) -> a - floor(a/n) * n
Run Code Online (Sandbox Code Playgroud)
或者:
mod = (a, n) -> (a % n + n) % n
Run Code Online (Sandbox Code Playgroud)
如果角度在[-180,180]之内,这也有效:
a = targetA - sourceA
a += (a>180) ? -360 : (a<-180) ? 360 : 0
Run Code Online (Sandbox Code Playgroud)
以更冗长的方式:
a = targetA - sourceA
a -= 360 if a > 180
a += 360 if a < -180
Run Code Online (Sandbox Code Playgroud)
Pet*_*r B 138
x是目标角度.y是来源或起始角度:
atan2(sin(x-y), cos(x-y))
Run Code Online (Sandbox Code Playgroud)
它返回有符号的delta角度.请注意,根据您的API,atan2()函数的参数顺序可能不同.
Lau*_*ves 35
如果你的两个角是x和y,那么它们之间的一个角是abs(x-y).另一个角度是(2*PI) - abs(x-y).所以2个角度中最小的角度的值是:
min((2 * PI) - abs(x - y), abs(x - y))
Run Code Online (Sandbox Code Playgroud)
这将为您提供角度的绝对值,并假设输入已标准化(即:在范围内[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
Run Code Online (Sandbox Code Playgroud)
请注意,%操作符在所有语言中的行为都不相同,尤其是涉及负值时,因此如果需要移植某些符号调整,则需要进行操作.
我接受提供签名答案的挑战:
def f(x,y):
import math
return min(y-x, y-x+2*math.pi, y-x-2*math.pi, key=abs)
Run Code Online (Sandbox Code Playgroud)
在 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);
}
Run Code Online (Sandbox Code Playgroud)
Arithmetical(与算法相对)解决方案:
angle = Pi - abs(abs(a1 - a2) - Pi);
Run Code Online (Sandbox Code Playgroud)