旋转矩阵的浮点误差

时间:2015-02-08 03:18:14

标签: c# floating-point double

我一直在研究c#矢量课,以便练习我的技能并自学,我遇到了一个相当令人愤怒的问题。

    public void Rotate (double rotation)
    {
        double xT;
        xT = x * Math.Cos (rotation * (Math.PI / 180)) - y * Math.Sin (rotation * (Math.PI / 180));
        y = x * Math.Sin (rotation * (Math.PI / 180)) + y * Math.Cos (rotation * (Math.PI / 180));
        x = xT; /*Figure out a better way to this*/
    }

我知道这个代码很草率,但问题来自于当我尝试180度左右的简单旋转(1,0),而不是我应该得到的预期(-1,0)时,它会返回( -1,-6.2343e-12)或那种程度的东西。

我知道这是双打中缺乏准确性的问题,但我想知道是否有办法让它仍然返回0而不是数字到-12。

有没有办法做到这一点?

1 个答案:

答案 0 :(得分:1)

使用向量的不可变结构通常更快/更清洁

public struct Vector
{
   readonly double x, y;
   public Vector(double x, double y) { this.x=x; this.y=y; }
   public Vector Rotate(double angle) 
   {
       angle *= Math.PI/180;
       double cos = Math.Cos(angle), sin=Math.Sin(angle);
       return new Vector(
          x*cos-y*sin,
          x*sin+y*cos );
   }
}

现在,就精确度而言,除了使用System.Math中的trig函数之外别无选择。我建议通过在转换为弧度之前将它们包裹在-180..180之间并使用到trig函数来消毒角度输入。