土法炼钢兴趣小组的算法知识备份

游戏中的数学 (10) - 曲线数学

目录

引言

在游戏中,物体很少做直线运动。为了让移动看起来自然,我们需要曲线。 最著名的曲线莫过于贝塞尔曲线 (Bézier Curve),它广泛应用于路径规划、UI 动画和 3D 建模。

Bezier Curves

1. 线性插值 (Linear Interpolation)

一切的起点是 Lerp。 \[ P(t) = P_0 + (P_1 - P_0)t = (1-t)P_0 + tP_1 \]\(t\) 从 0 变到 1 时,点从 \(P_0\) 移动到 \(P_1\)。这是一条直线。

2. 二阶贝塞尔曲线 (Quadratic Bezier)

如果我们想要弯曲,就需要引入一个控制点 \(P_1\)。 原理是:对 Lerp 进行 Lerp

  1. \(P_0\)\(P_1\) 之间插值得到 \(A\)
  2. \(P_1\)\(P_2\) 之间插值得到 \(B\)
  3. \(A\)\(B\) 之间插值得到最终点 \(P(t)\)

公式: \[ P(t) = (1-t)^2 P_0 + 2(1-t)t P_1 + t^2 P_2 \]

3. 三阶贝塞尔曲线 (Cubic Bezier)

这是最常用的形式(例如 Photoshop 的钢笔工具)。它有两个控制点 \(P_1, P_2\)

公式: \[ P(t) = (1-t)^3 P_0 + 3(1-t)^2 t P_1 + 3(1-t)t^2 P_2 + t^3 P_3 \]

4. 样条曲线 (Splines)

贝塞尔曲线的一个缺点是:曲线不一定经过控制点(除了起点和终点)。 如果我们希望曲线穿过一系列特定的点(例如巡逻路径),我们需要样条曲线

Catmull-Rom Spline

这是一种常用的样条,它保证曲线经过所有控制点,并且在点处平滑过渡。 计算 \(P_i\)\(P_{i+1}\) 之间的曲线段时,需要用到 \(P_{i-1}\)\(P_{i+2}\) 来计算切线。

代码实现 (Quadratic)

Vector3 GetPoint(Vector3 p0, Vector3 p1, Vector3 p2, float t) {
    t = Mathf.Clamp01(t);
    float oneMinusT = 1f - t;
    return oneMinusT * oneMinusT * p0 +
           2f * oneMinusT * t * p1 +
           t * t * p2;
}

总结


< 上一篇: 光照模型 | 回到目录 | 下一篇: 骨骼动画 >


By .