检测180度旋转的问题

时间:2011-03-11 15:37:06

标签: algorithm geometry

我有一个计算对象旋转量的算法。

它计算在-180和180度之间,以顺时针和逆时针处理。然而,当旋转仅约180度时,由于四舍五入,当比较形状的不同部分时,它最终会检测到-180度和180度旋转的混合,这取决于如何进行舍入,这会使实际旋转输出相当多。对此的答案是使用绝对值,但最终会打破旋转方向。

这是代码

 double newAngle = objOneAngle - objTwoAngle;
 if (newAngle< -180)
     newAngle += 360;
 else if (newAngle > 180)
     newAngle -= 360;

有关加强上述代码处理180度旋转的最佳方法的想法吗?

编辑: 想到的最明显的方法是将正值和负值分开,然后根据大小或其他指标选择最佳集合,但必须有一个更简单更优雅的解决方案?

2 个答案:

答案 0 :(得分:3)

将一些旋转测量为略高于180度,有些旋转测量稍微不应该是一个问题本身。我怀疑真正的问题在于你是如何从“形状的不同部分”组合这些旋转。例如,如果你对旋转进行平均,那么这将给出绝对疯狂的结果。您可以采取以下三种方法。

(1)以某种方式计算“典型旋转”数字,不受差异的影响:例如,只需随机选择一个旋转。 (如果它们中的一些可能出现严重错误,那么你可以做更多有力的事情。)现在调整你所有的旋转,使“典型的”旋转为零:

for (i=0; i<nSamples; ++i) {
  rotations[i] -= typicalRotation;
  if (rotations[i]<-180) rotations[i] += 360;
  else if (rotations[i]>180) rotations[i] -= 360;
}

现在平均这些(或做你正在做的任何事情),然后通过反向做同样的操作来纠正。

(2)对于(1),但是在处理之前和之后使用旋转或者将它们全部调整180度。选择要做的事情,例如,计算-90和+90之间的旋转,并查看它们是否多于或少于所有旋转的一半。

(3)对于每个角度计算(cos theta,sin theta)和平均那些,而不是平均旋转角度。然后使用atan2将平均值转换回角度。 (这个想法是角度是圆上的“真正”点,因此最好使用这些点而不是角度。当你这样做时,-180和+180度之间的模糊性就会消失。)

如果你真正做的是平均值,我最喜欢的是3.你的里程可能会有所不同。

答案 1 :(得分:0)

在浮点比较中处理舍入误差的常用方法是添加一个小容差:

double newAngle = objOneAngle - objTwoAngle;
if (newAngle < -180.000001)
    newAngle += 360;
else if (newAngle > 180.000001)
    newAngle -= 360;

这样,不会修改足够接近180的值。