math - 带四元数的非线性 slerp 动画

标签 math animation graphics 3d

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

不太复杂的动画,例如 float 之间的简单补间,可以轻松更改为二次缓入和缓出,但 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(即经过/持续时间)进行缓动插值?

最佳答案

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

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

我通常使用 3*t^2-2*t^3 公式来缓入/缓出。我会留下Wikipedia link在这里,以防万一。

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

关于math - 带四元数的非线性 slerp 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16205821/

相关文章:

JavaScript 数组除法

actionscript-3 - 使用 ActionScript 评估数学公式字符串

java - 第 n 个根实现

c# - 动画化 TreeView 中项目的添加/删除 - WPF

ios - imageView 动画出错了

opengl - 剪辑空间中三角形的重心坐标与屏幕空间中三角形的重心坐标之间有什么关系

math - float 学有问题吗?

javascript - 使用velocity.js 对 SVG 元素进行动画处理

java - 为 JFrame 设置背景颜色

graphics - 计算机图形学基础知识有哪些好的资源?