给定围绕坐标的-PI-> PI范围内的2个角度,它们之间2个角度中的最小角度值是多少?
考虑到PI和-PI之间的差异不是2 PI,而是零。
例:
想象一个圆,有2条线从中心出来,这些线之间有2个角度,它们在内侧形成的角度也称为较小的角度,而在外侧形成的角度也称为较大的角度。将两个角度相加时,将形成一个完整的圆。考虑到每个角度都可以在一定范围内,考虑到翻转,较小的角度值是多少
给定围绕坐标的-PI-> PI范围内的2个角度,它们之间2个角度中的最小角度值是多少?
考虑到PI和-PI之间的差异不是2 PI,而是零。
例:
想象一个圆,有2条线从中心出来,这些线之间有2个角度,它们在内侧形成的角度也称为较小的角度,而在外侧形成的角度也称为较大的角度。将两个角度相加时,将形成一个完整的圆。考虑到每个角度都可以在一定范围内,考虑到翻转,较小的角度值是多少
Answers:
这给出了任何角度的正负号:
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
a -= 360*sgn(a)*(abs(a) > 180)
。(想一想,如果您有sgn
and的无分支实现abs
,那么该特性实际上可能开始补偿需要两个乘法的时间。)
double targetA = 2; double sourceA = 359;
“ a”等于-357.0而不是3.0
x是目标角度。y是来源或起始角度:
atan2(sin(x-y), cos(x-y))
它返回带符号的角度。请注意,根据您的API,atan2()函数的参数顺序可能有所不同。
x-y
给您带来角度上的差异,但可能超出了所需范围。考虑一下在单位圆上定义一个点的角度。该点的坐标为(cos(x-y), sin(x-y))
。atan2
返回该点的角度(等于x-y
),但范围为[-PI,PI]。
如果两个角度分别为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
请注意,%
运算符在所有语言中的行为均不相同,尤其是在涉及负值时,因此,如果需要移植,可能需要进行一些符号调整。
from math import tau
。
我面临着提供签名答案的挑战:
def f(x,y):
import math
return min(y-x, y-x+2*math.pi, y-x-2*math.pi, key=abs)
算术(与算法相反)解决方案:
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 = 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,没有棕褐色,.....只有几何!
arg = arg - PIV2;
扩展为arg = arg - M_PI + M_PI
,因此不会执行任何操作。