← 返回列表

2026.06.30 计算机图形学

二维贝塞尔曲线、B-spline 和 NURBS 的最小交互演示

用三个最小 Canvas 交互 demo 直观理解二维贝塞尔曲线、B-spline 和 NURBS 曲线。

Computer GraphicsGeometryBezierB-splineNURBS

前言

贝塞尔曲线、B-spline 和 NURBS 都是计算机图形学、CAD 和几何建模里非常基础的曲线表示方法。它们的共同点是:曲线不是逐点手工画出来的,而是由一组控制点间接定义。

下面只讨论二维情况。为了直观起见,本文不追求完整理论,只用三个最小交互 demo 展示它们的核心差异:贝塞尔曲线由一整组控制点整体控制,B-spline 更强调局部控制,NURBS 则在 B-spline 的基础上进一步加入权重。

贝塞尔曲线

一条三次贝塞尔曲线由四个控制点 P0,P1,P2,P3P_0, P_1, P_2, P_3 决定:

B(t)=(1−t)3P0+3(1−t)2tP1+3(1−t)t2P2+t3P3,t∈[0,1]B(t)=(1-t)^3P_0+3(1-t)^2tP_1+3(1-t)t^2P_2+t^3P_3,\quad t\in[0,1]

其中 P0P_0 和 P3P_3 是曲线的起点和终点,P1P_1 和 P2P_2 主要影响曲线的切向和弯曲方式。贝塞尔曲线的一个直观特点是:控制点共同影响整条曲线。

简要推导

贝塞尔曲线可以从反复线性插值得到。设线性插值为:

L(A,B;t)=(1−t)A+tBL(A,B;t)=(1-t)A+tB

对四个控制点先做第一层插值:

Q0=L(P0,P1;t),Q1=L(P1,P2;t),Q2=L(P2,P3;t)Q_0=L(P_0,P_1;t),\quad Q_1=L(P_1,P_2;t),\quad Q_2=L(P_2,P_3;t)

再做第二层插值:

R0=L(Q0,Q1;t),R1=L(Q1,Q2;t)R_0=L(Q_0,Q_1;t),\quad R_1=L(Q_1,Q_2;t)

最后得到曲线点:

B(t)=L(R0,R1;t)B(t)=L(R_0,R_1;t)

把上面的插值式展开,就得到三次贝塞尔曲线的 Bernstein 形式:

B(t)=(1−t)3P0+3(1−t)2tP1+3(1−t)t2P2+t3P3B(t)=(1-t)^3P_0+3(1-t)^2tP_1+3(1-t)t^2P_2+t^3P_3

三次贝塞尔曲线:拖动黄色控制点,观察整条蓝色曲线如何变化。

B-spline 曲线

B-spline 也由控制点定义,但它额外引入了次数和节点向量。直观理解是:曲线被分成若干段,每一段只受附近几个控制点影响。

一个 B-spline 可以写成:

C(t)=∑iNi,p(t)PiC(t)=\sum_i N_{i,p}(t)P_i

其中 PiP_i 是控制点,pp 是曲线次数,Ni,p(t)N_{i,p}(t) 是由节点向量决定的基函数。下面的 demo 使用二次 B-spline,节点向量为:

[0,0,0,0.25,0.5,0.75,1,1,1][0,0,0,0.25,0.5,0.75,1,1,1]

B-spline 最值得注意的是局部性:移动某个控制点时,通常只会明显影响曲线附近的一部分,而不是整条曲线。

简要推导

B-spline 的核心是基函数。给定节点向量:

U=[u0,u1,…,um]U=[u_0,u_1,\ldots,u_m]

零次基函数是分段常数:

Ni,0(t)={1,ui≤t<ui+10,otherwiseN_{i,0}(t)= \begin{cases} 1, & u_i\le t<u_{i+1} \\ 0, & \text{otherwise} \end{cases}

更高次数的基函数由 Cox-de Boor 递推公式得到:

Ni,p(t)=t−uiui+p−uiNi,p−1(t)+ui+p+1−tui+p+1−ui+1Ni+1,p−1(t)N_{i,p}(t)= \frac{t-u_i}{u_{i+p}-u_i}N_{i,p-1}(t)+ \frac{u_{i+p+1}-t}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(t)

把这些局部基函数作为权重加到控制点上,就得到 B-spline 曲线:

C(t)=∑iNi,p(t)PiC(t)=\sum_i N_{i,p}(t)P_i

因为 Ni,p(t)N_{i,p}(t) 只在有限区间 [ui,ui+p+1)[u_i,u_{i+p+1}) 内非零,所以每个控制点通常只影响曲线的一小段,这就是 B-spline 的局部控制性来源。

二次 B-spline 曲线:拖动黄色控制点,观察红色曲线的局部变化。

NURBS 曲线

NURBS 是 Non-Uniform Rational B-spline 的缩写,可以理解为“带权重的有理 B-spline”。它仍然使用 B-spline 基函数,但给每个控制点额外分配一个权重 wiw_i:

C(t)=∑iwiNi,p(t)Pi∑iwiNi,p(t)C(t)=\frac{\sum_i w_i N_{i,p}(t)P_i}{\sum_i w_i N_{i,p}(t)}

也可以写成有理基函数形式:

Ri,p(t)=wiNi,p(t)∑jwjNj,p(t),C(t)=∑iRi,p(t)PiR_{i,p}(t)=\frac{w_iN_{i,p}(t)}{\sum_j w_jN_{j,p}(t)},\quad C(t)=\sum_i R_{i,p}(t)P_i

当所有权重都等于 11 时,NURBS 就退化为普通 B-spline。某个控制点的权重越大,曲线越容易被拉向该控制点。NURBS 在 CAD 中非常重要,因为它不仅能表示自由曲线,也能精确表示圆弧、圆锥曲线等几何对象。

简要推导

NURBS 可以从齐次坐标理解。把二维控制点 Pi=(xi,yi)P_i=(x_i,y_i) 扩展为带权重的齐次点:

P~i=(wixi,wiyi,wi)\tilde P_i=(w_ix_i,w_iy_i,w_i)

先在齐次空间里做一条普通 B-spline:

C~(t)=∑iNi,p(t)P~i\tilde C(t)=\sum_i N_{i,p}(t)\tilde P_i

设 C~(t)=(X(t),Y(t),W(t))\tilde C(t)=(X(t),Y(t),W(t)),再投影回二维平面:

C(t)=(X(t)W(t),Y(t)W(t))C(t)=\left(\frac{X(t)}{W(t)},\frac{Y(t)}{W(t)}\right)

把 X(t)X(t)、Y(t)Y(t) 和 W(t)W(t) 展开,就得到前面的 NURBS 有理形式。

二次 NURBS 曲线:拖动黄色控制点,或调节权重,观察紫色曲线如何被高权重控制点吸引。

小结

贝塞尔曲线形式简单,适合描述单段曲线;B-spline 更适合描述由多段平滑拼接而成的复杂曲线;NURBS 在 B-spline 的基础上加入权重,因此表达能力更强。简单来说:

  • 贝塞尔曲线:一组控制点整体定义一条曲线。
  • B-spline:通过节点向量和局部基函数,让控制点对曲线产生更局部的影响。
  • NURBS:在 B-spline 的基础上加入权重,可以让曲线更靠近某些控制点,也能表示更丰富的几何形状。