2

虽然在 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(经过/持续时间)使其成为缓动插值?

4

1 回答 1

2

控制 lerping 的“轻松”的变化率t,而不是 lerping 本身。我假设这T是一个标量(如浮点/双精度)。

AFAICT,您正在尝试获得缓入效果,但路径本身是开始和结束四元数之间的“直线”旋转。因此,只要t从 0 变化到 1,您所要做的就是改变 t 的变化率来获得“缓动插值”。

我通常使用3*t^2-2*t^3公式来轻松进出。我会在这里留下一个维基百科链接,以防万一。

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

于 2013-04-25T05:28:03.573 回答