第 13 章 三维曲线 (Curves in 3D)

      +

      核心结论

      • 参数化多项式曲线P(t) 是 t 的多项式;三次曲线是"最小可控度"——给出端点 + 切线即确定。

      • 多项式插值:穿过指定点;Aitken 递归算法 / Lagrange 基多项式;适合"已知数据点求平滑曲线"。

      • Hermite 曲线:由两个端点 + 两端点处的切线定义;4 个约束 = 3 次曲线。

      • Bézier 曲线:由端点 + 控制点定义(控制点不穿过曲线但影响形状);de Casteljau 算法可数值稳定求值。

      • 细分 (subdivision):用 de Casteljau 把曲线分成两半;用于自适应渲染。

      • 样条 (spline):多段曲线的拼接;连续性条件 C⁰ / C¹ / C² 分别对应位置 / 切线 / 曲率连续。

      • 自动切线控制:Catmull-Rom / 基数样条 (Cardinal spline) 根据相邻控制点自动生成切线;避免手动指定切线。

      本章主旨

      本章是 3D 图形的"曲线章"——把"用数学描述曲线"的方法系统化。从参数化基础出发,介绍三类核心曲线(多项式插值 / Hermite / Bézier),给出细分技巧,再扩展到样条(多段拼接)与自动切线控制。本章的所有曲线都基于三次多项式——因为三次是"最低能描述端点 + 切线"的阶数。

      一、核心概念

      本章围绕 7 个核心概念展开:从参数化基础出发,介绍三类核心曲线表示,再给细分技巧,最后扩展到样条拼接与自动切线控制。

      概念 定义 + 重要性 实现提示

      参数化多项式曲线

      P(t) 是 t 的多项式;三次多项式最常用(4 个自由度 = 端点 + 切线)。

      §13.1;游戏 / 图形最常用三次曲线;高次曲线数值不稳定。

      多项式插值

      穿过指定点;Aitken 递归 / Lagrange 基多项式;适合"已知数据点求平滑曲线"。

      §13.2;数据拟合基础;不适合动画路径(参数化不直观)。

      Hermite 曲线

      两端点 + 两端点切线定义;Hermite 基矩阵 H 把系数转换为曲线。

      §13.3;几何直观(端点 + 切线);动画路径规划。

      Bézier 曲线

      端点 + 控制点(不穿过曲线但影响形状);de Casteljau 算法数值稳定求值。

      §13.4;设计工具的事实标准(Photoshop 钢笔工具);字体轮廓。

      细分 (Subdivision)

      把曲线分成两段;de Casteljau 算法天然支持;用于自适应渲染。

      §13.5;增加曲线细节(如地形 LOD);实时渲染。

      样条 (Splines)

      多段曲线拼接;连续性 C⁰ / C¹ / C² 分别对应位置 / 切线 / 曲率连续。

      §13.6-§13.8;动画路径、字体轮廓、CAD 曲线。

      自动切线控制

      Catmull-Rom / 基数样条根据相邻控制点自动生成切线;无需手动指定。

      §13.9;设计师友好——只需给"经过的点"。

      二、详细笔记

      2.1 参数化多项式曲线 (Parametric Polynomial Curves)

      WhatP(t) 是 t 的多项式;t ∈ [0, 1] 描述曲线从起点到终点。

      Why:三次曲线是"最低可控度"——给定端点 + 切线即确定;高次曲线数值不稳定。

      How

      一般形式(§13.1):

      \[\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 个自由度 = "端点 + 端点切线 + 端点二阶导"。

      端点关系(§13.1.5):

      \[\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]\]

      Hermite 基矩阵(从系数转换为曲线):

      \[\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 路径、字体轮廓)——设计师友好。

      How

      定义(§13.4):

      \[\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 模型的曲面标准。\]