可能有问题的规范化功能
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
做第二个函数做的事情:执行除法。
我一直在使用具有归一化功能的向量 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
做第二个函数做的事情:执行除法。