尝试计算两个角度之间的差异 (atan2)
本文关键字:atan2 之间 两个 计算 | 更新日期: 2023-09-27 17:56:01
Atan2(y,x) 将返回 -pi 和 pi 之间的浮点数。 我想计算两个角度之间的距离,但非连续性让我失望。
请参阅此内容以更好地理解。
我希望能够计算角度 1 和角度 2 之间的距离。
这样做的全部意义在于能够创建一个从中心到指定角度的圆锥体。 基本上我将评估:
if(DistanceFromAngle1 < pi/4 [45°])
{
Angle2 is part of cone
}
如果您所说的距离是指连接两个拦截点的直线,则可以通过这样做来计算距离:
SQRT( ( ABS|cos(A) - cos(B)| )^2 + ( ABS|sin(A) - sin(B)| )^2 )
SQRT = 平方根
ABS = 绝对值
如果距离是角度,则通过执行(伪代码)来计算它
var angle = ABS(A - B)
if(angle > pi) angle = 2*pi - angle
return angle
dAngle1 = //convert angle1 to degrees
dAngle2 = // convert to degrees
delta = Math.Max(dAngle1, dAngle2) - Math.Min(dAngle1, dAngle2)
if (180 < delta) {
delta = 360 - delta;
}
// convert delta to radians if you want
π/2 是 90°,而不是 45°。 我假设你想知道角度 2 是否在以角度 1 为中心的区间内,该区间在两个方向上都远离它 45°。
您可以取角度 2 和角度 1 之间的差值,并减小模 2π,直到差值在 [-π, π) 中。 这将给出角度 2 和角度 1 之间的符号距离。 然后,检查这是否在 (-π/4、π/4) 中。 由于 atan2 返回的值始终介于 -π 和 π 之间,因此原始差异将始终在 -2π 和 2π 之间,因此您可以将所有这些归为一个检查:
if (angle2 - angle1 < -7π/4 ||
(angle2 - angle1 > -π/4 && angle2 - angle1 < π/4) ||
angle2 - angle1 > 7π/4)
{
angle2 is less than 45° away from angle1
}
角度差计算的两个警告:
procedure TForm1.sButton1Click(Sender: TObject);
Var a, b, dif : Extended;
begin
a := sCalcEdit1.Value;
b := sCalcEdit2.Value;
If ((a < 180) and (b >= 180) or
(a >= 180) and (b < 180)) and (abs(a - b) < 180) then
Begin
End else
If (a < 180) and (b >= 180) then
Begin
b := b - 360;
End else
If ((a >= 180) and (b < 180)) then
Begin
a := a - 360;
End;
dif := abs(a - b);
sCalcEdit3.Value := dif;
end;
procedure TForm1.sButton2Click(Sender: TObject);
Var a, b, dif : Extended;
begin
a := sCalcEdit1.Value * pi / 180;
b := sCalcEdit2.Value * pi / 180;
dif := arccos(cos(a - b));
sCalcEdit3.Value := dif * 180 / pi;
end;
给出一个替代解决方案:你可以使用向量数学。例如,如果您有两个向量作为起点(似乎是您的情况),这可能很有用。
给定两个归一化向量,a
和 b
,它们之间的角度只是变得acos(dot(a, b)) = acos(ax*bx + ay*by)
。
要从某个角度获取归一化向量,例如,alpha
可以使用a = vec2(cos(alpha), sin(alpha))
。
要规范化非正规向量,请使用 na = a / length(a) = a / sqrt(dot(a, a))
。
编辑:我不确定这是否有效。我从一些 python 代码翻译了它,但我不确定divmod(radians, math.pi*2)[1]
的行为是否与System.Math.IEEERemainder(radians, Math.PI*2.0)
相同。需要测试...
编辑2:我认为使用%是正确的
编辑3:废话,这是不正确的,因为它为负数返回负值。有谁知道如何在 C# 中获取 pythondivmod?
如何计算两个角度之间的角度:
public static double NormalizeAngle(double radians)
{
return fmod(radians,Math.PI*2.0); # this method doesn't exist, see above
}
public static double ArcLength(double radians1, double radians2)
{
radians1 = NormalizeAngle(radians1);
radians2 = NormalizeAngle(radians2);
return Math.Min(NormalizeAngle(radians1 - radians2, NormalizeAngle(radians2 - radians1));
}
它的工作原理是它尝试两种方式,所有计算 mod 2pi,并选择距离较小的一种。