2.1 参数化多项式曲线 (Parametric Polynomial Curves)
What:P(t) 是 t 的多项式;t ∈ [0, 1] 描述曲线从起点到终点。
Why:三次曲线是"最低可控度"——给定端点 + 切线即确定;高次曲线数值不稳定。
\[\mathbf{P}(t) = \mathbf{a}_0 + \mathbf{a}_1 t + \mathbf{a}_2 t^2 + \mathbf{a}_3 t^3 + \ldots
\end{bmatrix}\]
\[\mathbf{P}(t) = \mathbf{a}_0 + \mathbf{a}_1 t + \mathbf{a}_2 t^2 + \mathbf{a}_3 t^3
\end{bmatrix}\]
4 个系数向量 = 4 个自由度 = "端点 + 端点切线 + 端点二阶导"。
\[\mathbf{P}(0) = \mathbf{a}_0,\quad \mathbf{P}(1) = \mathbf{a}_0 + \mathbf{a}_1 + \mathbf{a}_2 + \mathbf{a}_3
\end{bmatrix>
[latexmath]\]
\mathbf{P}'(0) = \mathbf{a}_1,\quad \mathbf{P}'(1) = \mathbf{a}_1 + 2\mathbf{a}_2 + 3\mathbf{a}_3
\end{bmatrix>
\[[NOTE]
.为什么是三次?
====
* 一次:直线(无灵活性)。
* 二次:抛物线(1 个弯但不能控制形状)。
* 三次:可控制端点位置 + 端点切线("最低可控度")——设计友好。
* 四次及以上:参数过多、形状难控、数值不稳定。
====
*When*:所有平滑轨迹;动画路径;UI 缓动;字体轮廓。
*Example*:直线是 1 次曲线(线性参数化);3D 平滑轨迹常用 3 次(4 个自由度)。
=== 2.2 多项式插值 (Polynomial Interpolation)
*What*:求一个多项式使其穿过指定点;N+1 个点决定 N 次多项式。
*Why*:从数据点构造平滑曲线的基础;CAD / 数据可视化。
*How*:
Aitken 递归算法(§13.2.1):从线性插值开始,逐步升高阶数——`pᵢⱼ(t)` = 在区间 `[i, j]` 上的插值。
Lagrange 基多项式(§13.2.2):
[latexmath]\]
\mathbf{P}(t) = \sum_{i=0}^{n} \mathbf{P}_i \prod_{j \ne i} \frac{t - t_j}{t_i - t_j}
\end{bmatrix}
每个控制点有一个基多项式 `Lᵢ(t)`,所有 `Lᵢ(tᵢ) = 1`、`Lᵢ(tⱼ) = 0`。
[NOTE]
.Aitken vs Lagrange
====
* Aitken:递归实现(数值稳定、计算量 O(n²));适合动态加点。
* Lagrange:直接构造(公式漂亮、但数值不稳定);适合离线计算。
====
*When*:数据点 → 平滑曲线;地形插值;动画关键帧(不常用——更适合用 Catmull-Rom)。
*Example*:4 点 `(0,0)`、`(1,3)`、`(2,2)`、`(3,5)` 决定 3 次插值多项式。
=== 2.3 Hermite 曲线 (Hermite Curves)
*What*:两端点 + 两端点切线定义的三次曲线。
*Why*:几何直观——"起点 / 终点 + 起点 / 终点方向"即可确定;动画路径规划理想。
*How*:
定义(§13.3):
[latexmath]
\mathbf{P}(0) = \mathbf{P}_0,\quad \mathbf{P}(1) = \mathbf{P}_1
\end{bmatrix>
\[\mathbf{P}'(0) = \mathbf{T}_0,\quad \mathbf{P}'(1) = \mathbf{T}_1
\end{bmatrix]\]
\[\mathbf{P}(t) = \begin{bmatrix} 1 & t & t^2 & t^3 \end{bmatrix} \begin{bmatrix} 2 & 1 & -2 & 1 \\ -3 & -2 & 3 & -1 \\ 0 & 1 & 0 & 0 \\ 1 & 0 & 0 & 0 \end{bmatrix} \begin{bmatrix} \mathbf{P}_0 \\ \mathbf{T}_0 \\ \mathbf{P}_1 \\ \mathbf{T}_1 \end{bmatrix}
\end{bmatrix}\]
|
|
Hermite 曲线的几何意义
-
端点:P₀ 与 P₁ 是曲线必经的点。
-
切线:T₀ 与 T₁ 是曲线在端点处的方向。
-
4 个自由度确定唯一三次曲线。
|
When:动画路径(设计师指定起点 / 终点 + 进入 / 离开方向);碰撞响应轨迹;IK 关节插值。
Example:从 (0,0) 出切线 (1,0) 到 (1,1) 出切线 (0,1) 终点——曲线类似"半圆"。
2.4 Bézier 曲线 (Bézier Curves)
What:端点 + 控制点定义的三次曲线;控制点不穿过曲线但影响形状。
Why:设计工具事实标准(Photoshop 钢笔工具、Illustrator 路径、字体轮廓)——设计师友好。
\[\mathbf{P}(t) = (1-t)^3 \mathbf{P}_0 + 3(1-t)^2 t \mathbf{P}_1 + 3(1-t) t^2 \mathbf{P}_2 + t^3 \mathbf{P}_3
\end{bmatrix}\]
其中 P₀, P₃ 是端点,P₁, P₂ 是控制点(不穿过曲线)。
de Casteljau 算法(§13.4.1):递归线性插值求值:
\[\mathbf{Q}_0 = (1-t) \mathbf{P}_0 + t \mathbf{P}_1
\end{bmatrix>
[latexmath]\]
\mathbf{Q}_1 = (1-t) \mathbf{P}_1 + t \mathbf{P}_2,\quad \mathbf{Q}_2 = (1-t) \mathbf{P}_2 + t \mathbf{P}_3
\end{bmatrix>
\[\mathbf{R}_0 = (1-t) \mathbf{Q}_0 + t \mathbf{Q}_1,\quad \mathbf{R}_1 = (1-t) \mathbf{Q}_1 + t \mathbf{Q}_2
\end{bmatrix>
[latexmath]\]
\mathbf{P}(t) = (1-t) \mathbf{R}_0 + t \mathbf{R}_1
\end{bmatrix>
\[[NOTE]
.Bernstein 多项式性质
====
* 凸包:曲线在控制点凸包内(设计安全——曲线不会"飞出去")。
* 端点插值:`P(0) = P₀, P(1) = P₃`。
* 端点切线:`P'(0) ∝ (P₁ − P₀)`、`P'(1) ∝ (P₃ − P₂)`。
* 对称性:`P(t) from [P₀, P₁, P₂, P₃] 与 P(1-t) from [P₃, P₂, P₁, P₀]` 相同。
====
*When*:矢量图形(字体 / 图标 / UI);Bézier surface 是 3D 模型的标准表面(曲面);动画过渡。
*Example*:Photoshop 钢笔工具画曲线时,每个"把手"就是一个 Bézier 控制点。
=== 2.5 细分 (Subdivision)
*What*:用 de Casteljau 把曲线分成两段;用于自适应渲染与几何细分。
*Why*:GPU 渲染三角形需要把曲线离散为多段;细分保证足够精度又不浪费。
*How*:
中点细分(§13.5):
[latexmath]\]
\mathbf{P}(1/2) = \text{de Casteljau at } t = 1/2
\end{bmatrix]
de Casteljau 递归结果天然给出两端点处的"细分控制点"——可直接构造左右两段曲线。
[NOTE]
.细分的级联
====
* 一次细分:1 段 → 2 段。
* 二次细分:2 段 → 4 段。
* n 次细分:1 段 → 2ⁿ 段。
* 每次细分增加 1 阶精度;4-5 次细分可达亚像素精度。
====
*When*:Bézier 曲线离散化;曲线渲染(GPU 输入);地形 / 角色轮廓自适应 LOD。
*Example*:CAD 中绘制 Bézier 曲线时细分 4-5 次得到 ~16-32 段直线近似。
=== 2.6 样条 (Splines)
*What*:多段曲线的拼接;每段是独立曲线(Hermite / Bézier),在连接处满足连续性条件。
*Why*:长曲线(角色路径 / 字体轮廓)需用样条;单段三次曲线无法表达复杂形状。
*How*:
拼接结构:
[source,mermaid]
----
flowchart LR
A[段1: Hermite] --> B[连接点 P1]
B --> C[段2: Hermite]
C --> D[连接点 P2]
D --> E[段3: Hermite]
E --> F[连接点 P3]
F --> G[段4: Hermite]
----
连续性条件(§13.8):
* *C⁰ 连续*:位置连续 `P_left(1) = P_right(0)`。
* *C¹ 连续*:切线连续 `P'_left(1) = P'_right(0)`(方向 + 大小一致)。
* *C² 连续*:曲率连续 `P''_left(1) = P''_right(0)`。
* *G¹ / G²*:仅方向连续 / 曲率方向连续。
[NOTE]
.连续性的工程取舍
====
* *C⁰*:段间有"折角"——路径可见的不连续。适合分段动画。
* *C¹*:视觉上"光滑"——动画路径的标准。
* *C²*:曲率连续——高速运动(车辆 / 飞机)需要。
* 更高阶(G³+):实现复杂、应用少。
====
*When*:长曲线(角色路径、字体、CAD);高速运动轨迹(车辆、飞机)。
*Example*:NURBS(Non-Uniform Rational B-Spline)是工业 CAD 标准;B-Spline 是 Bézier 的推广。
=== 2.7 自动切线控制 (Automatic Tangent Control)
*What*:根据相邻控制点自动生成 Hermite 切线——设计师只需给"经过的点",无需指定切线。
*Why*:设计师友好——大多数情况下"端点 + 切线"是反直觉的;只需给离散点更自然。
*How*:
Catmull-Rom 样条(§13.9.1):
[latexmath]
\mathbf{T}_i = \frac{\mathbf{P}_{i+1} - \mathbf{P}_{i-1}}{2}
\end{bmatrix>
\[切线 = 相邻控制点差分的一半;曲线穿过所有控制点。
基数样条(Cardinal spline,§13.9.2):Catmull-Rom 的推广,加一个 *张力参数 t* 控制曲线"紧度"。
B-Spline:曲线 *不穿过* 控制点(仅"接近");更平滑但更难预测。
[NOTE]
.Catmull-Rom vs B-Spline
====
* *Catmull-Rom*:穿过所有控制点(interpolating);适合动画路径(物体经过每个关键帧)。
* *B-Spline*:不穿过控制点(approximating);适合字体 / CAD 表面。
* *NURBS*:B-Spline 加非均匀节点(non-uniform knot)+ 有理(rational)权重——最灵活但最复杂。
====
*When*:动画路径(Catmull-Rom 是事实标准);角色动作插值;地形 / 字体(B-Spline / NURBS)。
*Example*:Maya / Blender 中"通过控制点的曲线"通常用 Catmull-Rom;Maya 的"NURBS 表面"用 NURBS。
== 三、关键图表
=== 视觉图表
.图 13-1:参数化曲线(P(t) 随 t 变化)
image::fig-13-1.png[图 13-1, 600]
.图 13-2:Hermite 曲线(端点 + 切线)
image::fig-13-2.png[图 13-2, 800]
.图 13-3:Bézier 曲线(控制点影响形状)
image::fig-13-3.png[图 13-3, 800]
.图 13-4:de Casteljau 算法
image::fig-13-4.png[图 13-4, 800]
.图 13-5:曲线细分(中点插入)
image::fig-13-5.png[图 13-5, 800]
.图 13-6:样条拼接(C⁰ / C¹ / C² 连续性)
image::fig-13-6.png[图 13-6, 800]
.图 13-7:Catmull-Rom 自动切线
image::fig-13-7.png[图 13-7, 800]
=== 非可视化条目
[NOTE]
.非可视化条目(表 / 算法)
====
[cols="1,3", options="header"]
|===
| 编号 | 内容摘要
| 式 13-1
| 单位圆的参数化:`x = cos(2πt), y = sin(2πt)`。
| 式 13-2 至 13-10
| Hermite 基矩阵、Bernstein 基多项式、Bézier 求值。
| 列表 13.1-13.x
| C 代码:Aitken 递归插值、de Casteljau 求值、Catmull-Rom 样条。
| 表 13.1
| 4 类曲线的对比(隐式 / 参数化 / 特定类型 / 显式)。
|===
====
=== 核心公式对照表
[NOTE]
.核心公式对照表
====
[cols="1,3", options="header"]
|===
| 概念 | 公式
| 三次多项式
a| latexmath:[\mathbf{P}(t) = \mathbf{a}_0 + \mathbf{a}_1 t + \mathbf{a}_2 t^2 + \mathbf{a}_3 t^3]
| Hermite 矩阵
a| latexmath:[\mathbf{P}(t) = \begin{bmatrix} 1 & t & t^2 & t^3 \end{bmatrix} \begin{bmatrix} 2 & 1 & -2 & 1 \\ -3 & -2 & 3 & -1 \\ 0 & 1 & 0 & 0 \\ 1 & 0 & 0 & 0 \end{bmatrix} \begin{bmatrix} \mathbf{P}_0 \\ \mathbf{T}_0 \\ \mathbf{P}_1 \\ \mathbf{T}_1 \end{bmatrix}]
| 三次 Bézier
a| latexmath:[\mathbf{P}(t) = (1-t)^3 \mathbf{P}_0 + 3(1-t)^2 t \mathbf{P}_1 + 3(1-t) t^2 \mathbf{P}_2 + t^3 \mathbf{P}_3]
| Bernstein 基
a| latexmath:[B_{i,n}(t) = \binom{n}{i} (1-t)^{n-i} t^i]
| Catmull-Rom 切线
a| latexmath:[\mathbf{T}_i = \frac{\mathbf{P}_{i+1} - \mathbf{P}_{i-1}}{2}]
| de Casteljau
a| latexmath:[\mathbf{Q}_i = (1-t) \mathbf{P}_i + t \mathbf{P}_{i+1}](递归线性插值)
|===
====
== 四、思维导图
[source,mermaid]
----
mindmap
root((第 13 章 三维曲线))
参数化多项式
P与t
三次最常用
4自由度
多项式插值
Aitken递归
Lagrange基
数据拟合
Hermite
端点加切线
几何直观
动画路径
Bezier
端点加控制点
deCasteljau
凸包性质
细分
中点插入
级联LOD
渲染离散化
样条
多段拼接
C0C1C2
NURBS
自动切线
CatmullRom
Cardinal
设计师友好
----
== 五、重点与易错点
. *三次是"最低可控度"*:四次及以上数值不稳定、形状难控;游戏 / 图形几乎只用三次曲线。
. *Hermite vs Bézier*:Hermite 由端点 + 切线定义(动画规划);Bézier 由端点 + 控制点定义(设计工具);两者可互转。
. *Bézier 控制点不穿过曲线*:仅"拉"曲线靠近;曲线在控制点凸包内(设计安全)。
. *de Casteljau 是数值稳定的求值方法*:直接用 Bernstein 公式求值在 t 接近 0 或 1 时可能丢精度;de Casteljau 始终稳定。
. *Catmull-Rom 穿过所有控制点*:适合动画路径;B-Spline 不穿过但更平滑。
- *C⁰ / C¹ / C² 连续性的视觉差异*:C⁰ = 折角、C¹ = 光滑、C² = 曲率连续;动画路径通常 C¹ 即可,高速运动需 C²。
- *细分的级联*:每次细分加 1 阶精度;4-5 次细分可达亚像素精度。
- *Lagrange 数值不稳定*:高次多项式插值有 Runge 现象;Aitken / B-Spline 更稳定。
- *Cardinal spline 的张力参数*:t 越大曲线越"紧"(接近折线)、t 越小越"松"(接近 Catmull-Rom)。
- *NURBS 是工业标准*:汽车 / 飞机 / 船舶设计;非均匀节点 + 有理权重提供最大灵活性。
- *跨章衔接*:第 8 章四元数与本章 slerp 配合做曲线插值(朝向过渡);第 9 章几何图元的"参数化表示"是本章的具体应用;第 10 章 Bézier surface 是 3D 模型的曲面标准。\]