把一条拱形曲线左侧的控制点提高,右半段会不会改变?如果两段曲线在同一点接上,而且切线方向相同,沿曲线运动的物体会不会突然变速?这两个问题分别涉及控制点的影响范围和参数的含义,仅凭曲线看起来平滑无法回答。

本篇用四个控制点构造三次 Bézier 曲线,实际生成移动前后的图像,再用独立多项式检查求值结果。坐标沿用第 01 篇的向量约定,图像沿用累计 C++17 工程;这里的二维曲线嵌在 z=0 平面,不经过透视相机。

从线性插值到曲线

两点之间的线性插值是 L(t)=(1−t)A+tB,t∈[0,1]。四个点 P₀、P₁、P₂、P₃ 可以先两两插值,得到三个点;再对这三个点插值,得到两个点;最后再插值一次,得到曲线上对应 t 的一个点。

用 Pᵢ⁽ʳ⁾ 表示第 r 层的结果,de Casteljau 递推为:

Pi(0)=Pi,Pi(r)=(1t)Pi(r1)+tPi+1(r1),B(t)=P0(n).P_i^{(0)}=P_i,\qquad P_i^{(r)}=(1-t)P_i^{(r-1)}+tP_{i+1}^{(r-1)},\qquad B(t)=P_0^{(n)}.

n 是次数,因此 n+1 个控制点需要 n 层插值。每次混合的是上一层相邻两点,同一次求值中所有层都使用同一个 t。三次曲线需要 3+2+1=6 次向量插值,不是把三个控制线段分别画出来后接在一起。

累计代码 curve.hppbezier 先复制控制点,再逐层缩短有效数组。每层从左向右更新,右邻点尚未覆盖,因此无需存储整个三角形。时间复杂度 O(n²),工作空间 O(n)。当前接口限制为 1–65 个有限控制点及有限的 t∈[0,1];这是教学实现的输入上限,不是 Bézier 曲线的数学限制。

展开三次递推得到:

B(t)=(1t)3P0+3t(1t)2P1+3t2(1t)P2+t3P3.B(t)=(1-t)^3P_0+3t(1-t)^2P_1+3t^2(1-t)P_2+t^3P_3.

这四个 Bernstein 权重在区间内非负,而且和为 1。曲线因此位于控制点的凸包内。P₀ 与 P₃ 会被曲线经过,内部控制点一般不会被经过;把控制点当作必须穿过的插值节点,会给造型工具提出另一种需求。

递推算法与展开式表达同一条曲线,但程序验证不应把同一段递推再执行一次就当作独立答案。下面选择可手算展开式的控制点,比较两种求值路径。

提高一个控制点,改变了哪些位置

实验固定 P₀=(0,0)、P₁=(1,2)、P₂=(2,2)、P₃=(3,0),所有 z 均为 0。代入并合并多项式,得到 B(t)=(3t,6t(1−t))。端点是 (0,0) 和 (3,0),参数中点为 (1.5,1.5)。

图由 curve_check 实际生成:蓝点是控制点,灰线是控制多边形,橙线连接 1001 个等参数样本。480×480 图像采用 x像素=40+120x、y像素=440−120y,因此数学坐标 y 向上,图像行号向下。颜色是直接指定的诊断码值,不参与光照或线性颜色平均。

现在只把 P₁ 改成 (1,3)。展开式中只有 P₁ 项变化,所以每个参数处的位移为:

ΔB(t)=3t(1t)2(0,1).\Delta B(t)=3t(1-t)^2(0,1).

两个端点不变,中点的 y 增加 3×0.5×0.5²=0.375,变为 1.875。位移权重在整个开区间 (0,1) 都大于零,故右半段也发生变化,只是靠近终点时变化很小。图像右端附近看起来相似,不能据此声称影响只在左侧。

实际程序在 t=i/1000、i=0…1000 处检查位置。原曲线与独立多项式的最大欧氏误差为 8.8991×10⁻¹⁶;移动前后差值与上述位移式的最大误差为 6.6613×10⁻¹⁶。按距离大于 10⁻¹² 计数,1001 个样本中恰好 999 个改变。有限样本检查验证这次实现,整个开区间的结论则来自权重公式。

曲线图只是用 1000 条短线段近似连续曲线。固定采样数没有给出任意输入的屏幕误差保证;尖锐弯曲或放大视图需要更密采样,或者按平坦度细分。当前图像展示控制点影响,不把固定采样当作通用曲线光栅算法。

接上、同向和同速是不同条件

对 n 次 Bézier 求导,可得到由 n 个差分控制点 n(Pᵢ₊₁−Pᵢ) 定义的 n−1 次 Bézier。bezier_derivative 复用同一求值器计算这条导数曲线。端点尤其简单:

B(0)=n(P1P0),B(1)=n(PnPn1).B'(0)=n(P_1-P_0),\qquad B'(1)=n(P_n-P_{n-1}).

基线的起点导数是 (3,6),终点导数是 (3,−6)。前者沿第一条控制边,后者沿最后一条控制边。导数包含长度,归一化之后只剩方向;提前归一化会丢失判断参数速度所需的信息。

让第二条三次曲线 Q 的起点固定为 Q₀=P₃=(3,0),Q₂=(5,−1)、Q₃=(6,0),只改变 Q₁。两段各自都使用单位参数区间,并顺次映射到全局区间 [0,1] 和 [1,2]。实际检查结果如下:

Q₁ 第二段起点导数 C⁰ 位置连续 G¹ 同向切线 C¹ 一阶导数连续
(4,0) (3,0)
(5,−4) (6,−12)
(4,−2) (3,−6)

C⁰ 只要求前段终点等于后段起点。对这里非零的端点导数,G¹ 要求后段导数是前段导数的正倍数;程序检查叉积接近零且点积为正,因而不会把掉头的反向共线误算成同向。零导数情形不能直接套用这个判据,需要检查更高阶行为,本实验没有把它算作已验证情形。

C¹ 还要求这两个导数向量相等。表格第二行虽然没有方向折角,但参数均匀推进时,接点后的速度大小变为此前的两倍。这是参数运动不连续,不是位置断开。

如果两段运动分别耗时 T₁、T₂,物理速度应为 B′/T₁、Q′/T₂。改变时间映射就可能改变速度连续性,而不改变空间中的曲线形状。因此,讨论 C¹ 时必须说明比较哪个参数;讨论动画速度时必须把参数与时间的关系写出来。

为什么等参数取样不是匀速运动

本例基线导数是 (3,6−12t),速度大小为 √(9+(6−12t)²)。它在 t=0.5 最小,在两端较大。让 t 每帧增加相同数值,物体会在中间较慢、两端较快。

程序又取 11 个 t=0,0.1,…,1 的点,统计相邻点的 10 条弦长。最小值为 0.3059411708,最大值为 0.6177378085,约相差两倍。弦长不是精确弧长,但已经足以反驳“每次参数增量相同,所以每次距离相同”。

若需要沿曲线近似匀速运动,可以累积细分折线长度,建立距离到参数的查找表,再按目标距离反查 t。查找表精度依赖细分误差,不能把它称为精确弧长参数化。本篇尚未实现这一步,动画章节会重新处理时间输入。

B 样条怎样限制控制点的影响

一条高次 Bézier 的内部控制点会影响整段参数范围。复杂轮廓若仍由单条曲线表示,修改一个位置可能使远处也变化。B 样条使用分段多项式基函数及节点向量,在不持续提高次数的前提下增加控制点。

其形式仍是 C(u)=ΣNᵢ,ₚ(u)Pᵢ,其中 p 是次数,u 是曲线参数,节点向量规定参数区间的分段方式。与单段 Bézier 的全局权重不同,基函数 Nᵢ,ₚ 的支撑限于 [uᵢ,uᵢ₊ₚ₊₁);在约定端点处按相应极限处理。移动 Pᵢ,只可能改变这段支撑范围内的曲线,支撑外对应权重为零。

“局部”指参数支撑范围,不是以控制点为圆心的某个欧氏距离。节点并不等于曲线上的采样点,控制点也不必被曲线经过。节点重复度会影响连接处的光滑程度,因此 B 样条并不意味着任何节点配置都处处同样平滑。

本篇对 B 样条只建立表示与局部支撑概念,没有实现 B 样条求值器,也没有把 Bézier 的两张实验图当作 B 样条结果。下一篇转向三角网格细分:同样用邻域加权生成新位置,但输入连接关系、更新规则与验收不变量都不同。

复现实验与练习

仓库根目录执行:

1
2
make -C examples/computer-graphics check
examples/computer-graphics/build/curve_check examples/computer-graphics/build

程序输出 curve-before.ppmcurve-after.ppm,数值和命令日志见 writing-plans/computer-graphics/evidence/13-cpu.txt。实验不使用随机数,没有 GPU 或性能测量。四个拒绝样本覆盖负参数、超出区间参数、NaN 参数和空控制点;这些是明确的接口失败,不以静默钳制代替。

练习一:把 P₁ 提高 2 个单位,参数中点增加多少?影响最大的位置是否就是中点?

答案:中点增加 2×3/8=0.75。对权重 w(t)=3t(1−t)² 求导,w′(t)=3(1−t)(1−3t),内部最大值在 t=1/3,权重为 4/9,因此最大位移是 8/9。控制点影响最大的位置不必等于参数中点。

练习二:接续表格第二行的两段曲线,第一段耗时 1 秒,第二段应耗时多少秒才能让接点速度连续?若两个导数反向共线,仅调整正的时长能否修复?

答案:第二段耗时 2 秒,(6,−12)/2=(3,−6)/1。正时长只缩放导数长度,不反转方向,所以反向共线不能靠这种时间缩放修复。

系列导航与资料

前篇:12:三角网格怎样保存邻接系列入口。下一篇:14:粗网格怎样变成曲面

Michigan Tech 曲线课程的 de Casteljau 算法,Actual Computation 与 A Recurrence Relation,核对递推层次与迭代求值;Bézier 导数,核对差分控制点、端点导数与 G¹/C¹ 接续条件;B 样条曲线性质,第 5 项核对局部修改支撑区间。三页于 2026-09-20 实际读取,独立样例与运行记录保存在本系列工程中。