我正在尝试计算两个角度之间的最小差异。
这是我目前的代码(我在网上发现的一些细微变化):
float a1 = MathHelper.ToDegrees(Rot);
float a2 = MathHelper.ToDegrees(m_fTargetRot);
float dif = (float)(Math.Abs(a1 - a2);
if (dif > 180)
dif = 360 - dif;
dif = MathHelper.ToRadians(dif);
除了圆形边缘的情况外,它的工作正常。例如,如果当前角度为355且目标角度为5,则计算差值为-350而不是10,因为365度等于5度。
关于如何使其发挥作用的任何想法?
答案 0 :(得分:8)
你基本上拥有它。在检查是否大于180之前,只需取出dif模数:
float a1 = MathHelper.ToDegrees(Rot);
float a2 = MathHelper.ToDegrees(m_fTargetRot);
float dif = (float)Math.Abs(a1 - a2) % 360;
if (dif > 180)
dif = 360 - dif;
dif = MathHelper.ToRadians(dif);
编辑:@Andrew Russell对您的问题发表了评论,下面的解决方案充分利用了他建议的MathHelper.WrapAngle方法:
diff = Math.Abs(MathHelper.WrapAngle(a2 - a1));
答案 1 :(得分:3)
您可以扩展检查越界角度:
if (dif < 0) dif = dif + 360;
if (dif > 180) dif = 360 - dif;
答案 2 :(得分:2)
我从不喜欢用case语句处理零包装。相反,我使用点积的定义来计算两个角度之间的(无符号)角度:
vec(a) . vec(b) = ||a|| ||b|| cos(theta)
我们只是制作a和b单位向量,所以||a|| == ||b|| == 1
。
自vec(x) = [cos(x),sin(x)]
以来,我们得到:
unsigned_angle_theta(a,b) = acos(cos(a)cos(b) + sin(a)sin(b))
(n.b。以弧度表示的所有角度)
答案 3 :(得分:1)
您可以将结果标准化为0&lt; = theta&lt; 360:
while(theta < 0) { theta += 360; }
如果你想以弧度保持答案(推荐):
const Double TwoPi = 2 * Math.Pi;
while(theta < 0) { theta += TwoPi; }