带四元数的非线性slerp动画

时间:2013-04-25 03:21:42

标签: math animation graphics 3d

虽然用于在3D方向之间进行插值的流行slerp公式非常酷且有用,但我发现这是一个线性动画。

不太复杂的动画,例如浮动之间的简单补间,很容易改变为二次缓入和缓出,但slerp公式并不那么简单(其发明者Shoemake甚至没有发布公式的在他最初的发现时推导出来。)

所以我正在使用它:

template <typename T>
inline QuaternionT<T> QuaternionT<T>::Slerp(T t, const QuaternionT<T>& v1) const
{  
const T epsilon = 0.0005f;
T dot = Dot(v1);

if (dot > 1 - epsilon) {
    QuaternionT<T> result = v1 + (*this - v1).Scaled(t);
    result.Normalize();
    return result;
}

if (dot < 0)
    dot = 0;

if (dot > 1)
    dot = 1;

T theta0 = std::acos(dot);
T theta = theta0 * t;

QuaternionT<T> v2 = (v1 - Scaled(dot));
v2.Normalize();

QuaternionT<T> q = Scaled(std::cos(theta)) + v2.Scaled(std::sin(theta));
q.Normalize();
return q;
}

有没有人知道如何根据t(经过时间/持续时间)进行宽松插值?

1 个答案:

答案 0 :(得分:2)

t的变化率控制了掠夺的“缓和”,而不是掠夺本身。我假设T是一个标量(如float / double)。

AFAICT,你试图获得一个轻松的效果,但路径本身是开始和结束四元数之间的“直接”旋转。因此,只要t从0变为1,您所要做的就是改变t 的变化率以获得“缓和插值”。

我通常使用3*t^2-2*t^3公式来轻松进出。我会留下Wikipedia link,以防万一。

(我觉得我在这里遗漏了一些东西。如果这回答了你的问题,请告诉我。)