可能有问题的规范化功能

Possibly questionable normalize function

我一直在使用具有归一化功能的向量 class。

       float length = Length();
        if (!MathUtil.IsZero(length))
        {
            float inv = 1.0f / length;
            X *= inv;
            Y *= inv;
            Z *= inv;
        }

我发现,在某些情况下,它生成的单位向量似乎并不完全是单位向量。知道浮点数是一个度数的近似值,在某些情况下,我在点积中使用这个归一化向量并得到一个点值 > 1。这在 Acos 情况下很糟糕,它会产生 NaN。

由于该点用于相机旋转,因此确实会产生旋转神经滴答声。

我最后做的是重写代码:

            float length = a_vector.Length();
        if (!MathUtil.IsZero(length))
        {
            a_vector.X /= length;
            a_vector.Y /= length;
            a_vector.Z /= length;
        }

这似乎将这个问题减少到几乎为 0。

目前,它是确认偏差,除非另有说明。但我的问题是,虽然肯定更慢,但这是更准确的归一化吗?

这在很大程度上取决于您的特定用例中具体错误来源的输入,以及优化设置。一如既往,关于此的开创性文章是 What Every Programmer Should Know About Floating-Point Arithmetic, and you should review the many very-useful floating-point articles on this blog.

请注意,长度应始终为正,并且避免使用浮点数进行相等测试总是更稳健:

   float length = Length();
   if (length > 0)
   {
   ...
   }

DirectXMath中,我提供了两种形式的归一化,以便数学库的用户可以根据具体情况选择权衡:

  • XMVector3NormalizeEst 执行您的第一个函数所做的事情:执行倒数然后乘法。

  • XMVector3Normalize 做第二个函数做的事情:执行除法。