我一直在使用具有规范化功能的矢量类。
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。
此刻,它的确认偏见直到另有说明。但我的问题是这个,虽然肯定比较慢,但这是一个更准确的规范化吗?
答案 0 :(得分:2)
在很大程度上取决于特定用例中特定错误源的输入以及优化设置。与往常一样,关于此问题的开创性文章是What Every Programmer Should Know About Floating-Point Arithmetic,您应该查看this blog上许多非常有用的浮点文章。
请注意,长度应始终为正,并且避免使用浮点等于测试时,它总是更加健壮:
float length = Length();
if (length > 0)
{
...
}
在DirectXMath中,我提供了两种规范化形式,以便数学库的用户可以根据具体情况选择权衡:
XMVector3NormalizeEst
执行您的第一个功能:执行倒数然后相乘。
XMVector3Normalize
执行您的第二个功能所做的事情:执行鸿沟。