我们可以像这样在两个四元数之间进行slerp插值:
quat slerp(quat q1, quat q2, float t) {
float angle = acos(dotProduct(q1, q2));
float denom = sin(angle);
//check if denom is zero
return (q1*sin((1-t)*angle)+q2*sin(t*angle))/denom;
}
这将以最短的方式在两个四元数之间进行插值。但是,在四元数之间进行插值还有很长的路要走。如下图所示(源Maya)。我们如何进行长距离插值?
最佳答案
单位四元数的性质以及它们映射到3D旋转的方式意味着它们可以两种方式描述每个3D旋转值-q(r, v')
和q(-r, -v')
(将它们想象为轴角旋转-将轴和角度都反转会导致相同3D旋转)。
四元数实际上是4D单位球面上的点,这两个值表示该球面上的反足点。
为了使两个四元数的slerp(或nlerp)遵循最短路径,相应的4D点必须位于4D球面的同一半球上(这也是为什么加权平均数不超过2个四元数的原因)独特的解决方案)。这映射到非负点积,通常在插值代码中经过测试。
简单地否定源四元数之一将为您提供一个“在4D球面的相反侧”的点,并导致插值“很长的路要走”(并解释了为什么对插值参数求反会导致相同的结果)。