第5 章
样条曲面 
曲线与曲面是计算机图形学中重要的研究对象,是计算机绘图与动画技术的核心
要素。在
计算机中,可以用离散的点来描述曲线曲面,也可以用直线段或者小平面片拼接在
一起表示曲线曲面。平面曲线可以用一个一维数组描述,数组下标作为横坐标,数组元素
的值作为纵坐标;空间曲线可以用三个一维数组描述,每个数组分别为X 、Y、Z 值,这便
是参数方程表示方法;曲面可以用三维数组表示,也可以用一些三角形或者四边形的顶点
数组表示。
5.1 三维空间样条曲线
在第2章中介绍了二维贝塞尔曲线等,现在讨论三维空间的样条曲线,主要介绍贝塞
尔曲线与B样条曲线。
5.1.1 三维空间贝塞尔曲线
第2章中介绍的各种曲线都可以扩展到三维空间中来。例如,2.3节中的式2-8表示
的曲线是平面贝塞尔曲线,如果增加一个表达式,如式5-1所示,那么就表示三维空间中
的贝塞尔曲线。
x(t)=Σn 
i=0
xiBi,n(t) 
y(t)=Σn 
i=0
yiBi,n(t) 
z(t)=Σn 
i=0
ziBi,n(t) 
ì
.
í
.... 
.... (5-1) 
式5-1中的n 就是曲线的次数,当n=3时,式5-1就表示空间三次贝塞尔曲线。
Bi,n(t)=Ci
nti (1-t)n-i是伯恩斯坦多项式,这与二维情形相同。
式2-12是平面贝塞尔曲线的通用矩阵表示形式,在三维空间中,这个表示形式不变, 
只是P(t)= 
x(t) 
y(t) 
z(t) 
é
.
êêêê 
ù
.
úúúú
,P0=(x0,y0,z0),…,P3=(x3,y3,z3)。
例如,当P[3][4]={{1 2 5 6},{1.5 7 11 5},{2 3 6 5.5}},即4个控制

164
计算机图形学(VC++实现)(第
3 
版)

点依次是(1,5,2),(2,7,3),(5,6),(6,5,5)时,其三维空间中的贝塞尔曲线如
图5-1所示。
1.11,5.


图5-
1 
空间三次贝塞尔曲线

空间贝塞尔曲线的两个端点即是两端的控制点,其他控制点用来控制曲线的形状,图
5-1中有4个控制点,生成的贝塞尔曲线是三次贝塞尔曲线。
t),t),t)], 与空间三次贝塞尔曲线类似,让式217 中的P(=[x(y(就可以表
示空间三次B样条曲线段。
-t)z(
上面介绍的各种曲线本质上都是多项式曲线,只因为给定的初始条件不同,或者曲线
对控制点的要求不同,所以产生了区别。一个曲线的多种参数方程是可以互相转换的。

5.1.2 
曲线的拼接
两条曲线端点处的函数值决定是否能实现拼接,函数值相同才可以拼接到一起。如
果端点处的切线斜率(一阶导数)也相同就可以实现平滑连接,没有折起的棱角。有时根
据具体问题,要求连接时函数值相同、一阶导数相同、二阶导数也相同,如果是三维空间曲
线连接,还要求导数的方向也相同,这是一种更高要求的连接。

2.2节中的Hermte曲线给出了端点坐标值以及端点处的切向量,所以该方法绘制
4.i
的曲线容易实现平滑连接。
如果两段贝塞尔曲线要实现光滑连接(一阶导数相同), 那么需要满足一定的条件。
下面的例题研究的是两段三次贝塞尔曲线连接问题。
【例5-1】给定4个控制点P1、P2、P3、P4,绘制出的三次贝塞尔曲线记为C1,再根

据另外4个控制点P4、P5、P6、P7 可以绘制出三次贝塞尔曲线C2。问这7个顶点满足
什么条件时两条曲线在P4 点光滑连接(导数相等)? 

由贝塞尔曲线的性质:贝塞尔曲线起点处切线与终点处切线分别是特征多边形的第
一条边和最后一条边所在直线。所以,当P3、P4、P5 在一条直线上时,两条空间三次贝
塞尔曲线在P4 点光滑连接。


第5 章 样条曲面1 65 
5.1.3 三维空间B 样条曲线
B样条曲线也属于一种由基函数乘以系数构造的参数曲线,其基函数与贝塞尔曲线
不同,所以具有不同的性质。
【例5-2】 给定4个控制点P1、P2、P3、P4 绘制出的三次B 样条曲线段记为C1;再
给定一点P5,绘制出由P2、P3、P4、P5 控制的三次B样条曲线段记为C2,观察曲线段C1 
与C2 的关系。
三次B样条曲线的基函数如下。
F0,3(t)=16
(-t3 +3t2 -3t+1) 
F1,3(t)=16
(3t3 -6t2 +4) 
F2,3(t)=16
(-3t3 +3t2 +3t+1) 
F3,3(t)=16
t3 
三次B样条曲线段的参数方程如下。
x(t)=F0,3(t)x0 +F1,3(t)x1 +F2,3(t)x2 +F3,3(t)x3 
y(t)=F0,3(t)y0 +F1,3(t)y1 +F2,3(t)y2 +F3,3(t)y3 
z(t)=F0,3(t)z0 +F1,3(t)z1 +F2,3(t)z2 +F3,3(t)z3 
ì
.
í
.. 
.. 
建立单文档项目,在视图文件中OnDraw()函数的前面写入函数Draw3()如下。 
void Draw3(float k[4][3],int color,CDC *p) 
{ 
float x,y,z; 
float f3t[4],kk[4][3]={0}; 
for(int i=0;i<4;i++) 
for(int j=0;j<3;j++) 
kk[i][j]=k[i][j]; 
for(float t=0;t<1;t=t+0.001) 
{ 
f3t[0]=1/6.0*(-pow(t,3)+3*pow(t,2)-3*t+1); 
f3t[1]=1/6.0*(3*pow(t,3)-6*pow(t,2)+4); 
f3t[2]=1/6.0*(-3*pow(t,3)+3*pow(t,2)+3*t+1); 
f3t[3]=1/6.0*pow(t,3); 
x=f3t[0]*kk[0][0]+f3t[1]*kk[1][0]+f3t[2]*kk[2][0]+f3t[3]*kk[3][0]; 
y=f3t[0]*kk[0][1]+f3t[1]*kk[1][1]+f3t[2]*kk[2][1]+f3t[3]*kk[3][1]; 
z=f3t[0]*kk[0][2]+f3t[1]*kk[1][2]+f3t[2]*kk[2][2]+f3t[3]*kk[3][2]; 
p->SetPixel((int)x+100,(int)y+100,color); 
} 
}

1 66 计算机图形学(VC++ 实现)(第3 版) 
在OnDraw()函数中写入调用函数Draw3()的代码,写入后OnDraw()函数的代码
如下(其中粗体是加入的语句)。 
void CBbbView::OnDraw(CDC* pDC) 
{ 
CBbbDoc* pDoc = GetDocument(); 
ASSERT_VALID(pDoc); 
//TODO: add draw code for native data here 
Float xyz1[4][3]={{20,100,110},{70,120,10},{200,60,20},{250,20,160}}; 
Draw3(xyz1,0,pDC); 
Float xyz2[4][3]={{70,120,10},{200,60,20},{250,20,160},{150,16,178}}; 
Draw3(xyz2,0,pDC); 
}
编译运行,绘制出如图5-2(a)所示的投影图形。
把语句 
p->SetPixel((int)x+100,(int)y+100,color) 
修改为: 
p->SetPixel((int)x+100,(int)z+100,color) 
绘制出如图5-2(b)所示的投影图形。
把这个语句再修改为: 
p->SetPixel((int)y+100,(int)z+100,color) 
绘制出如图5-2(c)所示的投影图形。
图5-2 三次B样条曲线在三个坐标轴上的投影(0<t<1) 
该程序绘制的曲线是三维空间中的曲线,在三个坐标平面上的投影都是样条曲线。
本来是绘制两段曲线,但是这两段曲线(“无缝地”)连接在一起了。
为了更好地观察连接情况,把语句 
for(float t=0;t<1;t=t+0.001) 
修改为

第5 章 样条曲面1 67 
for(float t=-1;t<1;t=t+0.001) 
结果绘制出的对应各个坐标平面的投影图形如图5-3所示。从图上可以看到两段不
同的曲线在某个点处光滑的连接过渡情形。
图5-3 三次B样条曲线在三个坐标轴上的投影(-1<t<1) 
【注】 该例题的坐标系是VC++ 默认的坐标系,左上角为(0,0)点,横轴正方向向
右,纵轴正方向向下。
【思考题】 在例5-2给出的条件下,为什么两个B样条曲线段能够实现光滑连接? 
参数t 的范围为什么限制在0~1就可以无缝光滑连接? 
与贝塞尔曲面类似,绘制B样条曲线也有快速算法。正是因为有快速绘制方法,所
以这类曲线曲面才在图形绘制中被广泛使用。
5.1.4 三维空间分段插值曲线
给定三维空间中的一些离散点,然后求(或者绘制)满足一定条件的一条曲线,使得该
曲线过这些离散点,这就是三维空间曲线插值问题。
与贝塞尔曲线以及B样条曲线不同的是,插值曲线必须过插值点。
给定三维插值点后,实现三维空间曲线插值有很多方法,其中,三次样条插值是比较
常用的一种方法。
下面以一个具体例子说明三维空间中的三次样条插值问题。
给定5个点(1,1,1),(2,2,3),(3,6,5),(6,3,2),(9,6,1),求三维空间内顺次经过这5 
个点的两段三次样条插值曲线,使得在(3,6,5)点连续并且在该点的一阶导数与二阶导数相
等,在点(1,1,1)处斜率向量为(-1,-1,-1),在点(9,6,1)处的斜率向量为(1,1,1)。
空间曲线可以视为两个曲面的交线,由式5-2确定,也可以由式5-3参数方程确定。
F1(x,y,z)=0 
F2(x,y,z)=0 { (5-2) 
x =x(t) 
y =y(t) 
z =z(t) 
ì
.
í
.. 
..
(5-3)

1 68 计算机图形学(VC++ 实现)(第3 版) 
所谓切向量,如果使用式5-3,就是指dx 
dt,dy 
dt,dz 
dt 
.
è .
.
. ÷ 
。
对于上面的三维空间三次样条插值问题,使用待定系数法可以计算出三次样条插值
曲线(段)。
5.2 贝塞尔曲面
在图形学中,贝塞尔曲面是常用的曲面之一。在前面绘制曲面的过程中,使用了方
程进行绘制。对于计算机图形学中的一些曲面,例如贝塞尔曲面也有参数方程,可以
使用方程绘制。不过,贝塞尔曲面以及B样条曲面除了可以使用方程绘制外,还可以
使用递归快速算法进行绘制。使用贝塞尔曲面可以轻松绘制出高次多项式曲面,同时
可以控制该曲面的大致形状。诸多的优点使得计算机图形学教材或者著作中都介绍
这类曲面。
5.2.1 贝塞尔曲面的定义
下面给出贝塞尔曲面的参数表达形式: 
在三维空间中,给定(n+1)×(m +1)个点Pij =(xij,yij,zij),i=0,1,2,…,n;j= 
0,1,2,…,m 。
X =f(u,v)=Σn 
i=0Σm 
j=0
xijBi,n(u)Bj,m (v) 
Y =g(u,v)=Σn 
i=0Σm 
j=0
yijBi,n(u)Bj,m (v) 
Z =h(u,v)=Σn 
i=0Σm 
j=0
zijBi,n(u)Bj,m (v) 
ì
.
í
.... 
.... 
0≤u ≤1,0≤v ≤1 (5-4) 
其中,Bi,n(u)=Ci
nui (1-u)n-i,Bj,m (v)=Cj
mvj (1-v)m -j 是伯恩斯坦基函数,组合数
Ci
n = n! 
i!(n-i)!,Cj
m = m ! 
j!(m -j)!。
从式5-4看出,贝塞尔曲面的构造方式与贝塞尔曲线类似,基函数是相同的;只是贝
塞尔曲面有三个变量,也就有三个参数方程构成方程组。当u,v 在一个平面区域变化
时,三维点(X ,Y,Z)便形成了曲面。
5.2.2 双一次贝塞尔曲面
在式5-4中,如果n=m =1,那么得到的曲面称为双一次贝塞尔曲面。
【例5-3】 把n=m =1代入式5-4,求出双一次贝塞尔曲面的参数方程,分析双一次
贝塞尔曲面片的特征。
把n=m =1代入后得:

第5 章 样条曲面1 69 
X =Σ1 
i=0Σ1 
j=0
xijBi,1(u)Bj,1(v) 
Y =Σ1 
i=0Σ1 
j=0
yijBi,1(u)Bj,1(v) 
Z =Σ1 
i=0Σ1 
j=0
zijBi,1(u)Bj,1(v) 
ì
.
í
.... 
.... 
. 
X =[B0,1(u)B1,1(u)]x00 x01 
x10 x11 
é
. êê
ù
. úú
B0,1(v) 
B1,1(v) 
é
. êê
ù
. úú 
Y =[B0,1(u)B1,1(u)]y00 y01 
y10 y11 
é
. êê
ù
. úú
B0,1(v) 
B1,1(v) 
é
. êê
ù
. úú 
Z =[B0,1(u)B1,1(u)]z00 z01 
z10 z11 
é
. êê
ù
. úú
B0,1(v) 
B1,1(v) 
é
. êê
ù
. úú 
ì
.
í
....
.
.... 
其中,基函数: 
B0,1(u)=1-u, B1,1(u)=u 
B0,1(v)=1-v, B1,1(v)=v 
所以有
X =(1-u)(1-v)x00 +u(1-v)x10 + (1-u)vx01 +uvx11 
Y =(1-u)(1-v)y00 +u(1-v)y10 + (1-u)vy01 +uvy11 
Z =(1-u)(1-v)z00 +u(1-v)z10 + (1-u)vz01 +uvz11 
ì
.
í
.. 
..
(5-5) 
写成矩阵表示形式为
P(u,v)=[u 1]-1 1 
1 0 
é
. êê
ù
. úú
P00 P01 
P10 P11 
é
. êê
ù
. úú
-1 1 
1 0 
é
. êê
ù
. úú
v1
é
. êê
ù
. úú 
(5-6) 
分析式5-5参数方程(组),该方程组有两个参数,各项的最高次数为2;方程中一共
有4个控制点的12个坐标值;3个方程的形式是相同的,只是分别使用了控制点的x、y 
与z 坐标值。使u 与v 在0~1变化,对应每一个(u,v)都能得到一个空间点(X ,Y, 
Z)。
当u=0、v=0、u=1、v=1其中一个成立时,便得到一条边界直线段;所以一共有4 
条边界直线段。当u 或者v 中一个不变,改变另外一个,得到的是一条直线段。
可以证明,双一次贝塞尔曲面是双曲抛物面。
下面编写程序绘制双一次贝塞尔曲面。
【例5-4】 绘制双一次贝塞尔曲面。
修改例5-2中相关语句如下。 
double cv[4][3]={{20,10,110},{100,60,20},{90,20,10},{5,30,80}}; 
for(double u=0;u<1;u=u+0.05) 
{ n=0; 
for(double v=0;v<1;v=v+0.05) 
{ x[m][n][0]=(1-u)*(1-v)*cv[0][0]+u*(1-v)*cv[1][0]+(1- u)*v*cv[2] 
[0]+u*v*cv[3][0]; 
x[m][n][1]=(1-u)*(1-v)*cv[0][1]+u*(1-v)*cv[1][1]+(1- u)*v*cv[2] 
[1]+u*v*cv[3][1]; 
x[m][n][2]=(1-u)*(1-v)*cv[0][2]+u*(1-v)*cv[1][2]+(1- u)*v*cv[2] 
[2]+u*v*cv[3][2]; 
n++; 
}

1 70 计算机图形学(VC++ 实现)(第3 版) 
绘制出的图形如图5-4(a)所示。
如果把控制点赋值语句修改为如下所示,每次运行,或者调整运行后文档窗口,都可
以重新绘制出新的曲面,图5-4(b)和图5-4(c)就是随机生成的两个曲面。 
double cv[4][3]; 
for(int i=0;i<4;i++) 
for(int j=0;j<3;j++) 
cv[i][j]=rand()%300; //控制点坐标介于0~300 
图5-4 双一次贝塞尔曲面
【注】 空间中的一些直线也可以构成曲面。
【例5-5】 绘制双一次贝塞尔曲面,并绘制出其4个控制点。
在例5-4(从例5-2修改而来)中的函数DrawCurve()的最后加入下面的语句。 
CBrush b(RGB(255,0,0)); 
pDC->SelectObject(&b); 
for(int r=0;r<4;r++) 
{ 
xx[r]=(cv[r][0]-p[0]/p[2]*cv[r][2])+100; 
yy[r]=(cv[r][1]-p[1]/p[2]*cv[r][2])+100; 
pDC->Ellipse(xx[r],yy[r],xx[r]+10,yy[r]+10); 
}
运行程序,除了绘制出双一次贝塞尔曲面外,还绘制出4个控制点。为了清楚,用小
椭圆代替了点。
5.2.3 双二次贝塞尔曲面
在式5-4中,令n=m =2,得到的曲面称为双二次贝塞尔曲面。
当n=m =2时,给定(n+1)×(m +1)=9个点Pij=(xij,yij,zij),其中,i=0,1,2; 
j=0,1,2。代入式5-7: 
P(u,v)=Σ2 
i=0Σ2 
j=0
PijBi,2(u)Bj,2(v) 0≤u ≤1,0≤v ≤1 (5-7) 
其中,基函数:

第5 章 样条曲面1 71 
B0,2(u)=u2 -2u +1, B1,2(u)=-2u2 +2u, B2,2(u)=u2 
B0,2(v)=v2 -2v +1, B1,2(v)=-2v2 +2v, B2,2(v)=v2 
把如式5-7所示双二次贝塞尔曲面的参数方程整理成矩阵表示形式为
P(u,v)=[u2 u 1] 
1 -2 1 
-2 2 0 
1 0 0 
é
.
êêêê 
ù
.
úúúú 
P00 P01 P02 
P10 P11 P12 
P20 P21 P22 
é
.
êêêê 
ù
.
úúúú 
1 -2 1 
-2 2 0 
1 0 0 
é
.
êêêê 
ù
.
úúúú 
v2 
v1 
é
.
êêêê 
ù
.
úúúú 
(5-8) 
其中,顶点矩阵实际上是3个矩阵,即9个控制点的X,Y,Z 矩阵。即矩阵
P00 P01 P02 
P10 P11 P12 
P20 P21 P22 
é
.
êêêê 
ù
.
úúúú 
相当于下面三个矩阵: 
x00 x01 x02 
x10 x11 x12 
x20 x21 x22 
é
.
êêêê 
ù
.
úúúú
,
y00 y01 y02 
y10 y11 y12 
y20 y21 y22 
é
.
êêêê 
ù
.
úúúú
,
z00 z01 z02 
z10 z11 z12 
z20 z21 z22 
é
.
êêêê 
ù
.
úúúú
(5-9) 
对于每一个固定的(u,v),对于式5-9中的每一个矩阵(给定数值后),代入式5-8,都可以
得到一个数值;三个矩阵得到三个数值,便是一个空间点的坐标(x,y,z)。
式5-9中的数值就是贝塞尔曲面的控制点的坐标。
图5-5是借助于MATLAB软件绘制的双二次贝塞尔曲面。
图5-5 9个控制点的双二次贝塞尔曲面及其控制网格
其9个控制点的坐标的X 、Y、Z 值如下。
X =0 0.5000 1.0000 0 0.5000 1.0000 0 0.5000 1.0000 
Y =0 0 0 0.5000 0.5000 0.5000 1.0000 1.0000 1.0000 
Z =0.5468 0.5978 0.9053 0.7596 0.8144 0.1088 0.0963 0.0580 0.7884 
其中有4个控制点在曲面(的4个角)上。

1 72 计算机图形学(VC++ 实现)(第3 版) 
5.2.4 双三次贝塞尔曲面的16 个控制点
当n=m =3时,式5-4表示的曲面称为双三次贝塞尔曲面。
当n=m =3时,给定(n+1)×(m +1)=16个点Pij =(xij,yij,zij),其中,i=0,1, 
2,3;j=0,1,2,3。代入式5-10: 
P(u,v)=Σ3 
i=0Σ3 
j=0
PijBi,3(u)Bj,3(v) 0≤u ≤1,0≤v ≤1 (5-10) 
其中,基函数: 
B0,3(u)=u3 +3u2 -3u +1,B1,3(u)=3u3 +6u2 +3u 
B2,3(u)=-3u3 +3u2,B3,3(u)=u3 
B0,3(v)=v3 +3v2 -3v +1,B1,3(v)=3v3 +6v2 +3v 
B2,3(v)=-3v3 +3v2,B3,3(v)=v3 
把式5-10整理成矩阵形式为
P(u,v)= [u3 u2 u 1]
-1 3 -3 1 
3 -6 3 0 
-3 1 0 0 
0 0 0 0 
é
.
êêêêê 
ù
.
úúúúú 
P00 P01 P02 P03 
P10 P11 P12 P13 
P20 P21 P22 P23 
P30 P31 P32 P33 
é
.
êêêêê 
ù
.
úúúúú 
-1 3 -3 1 
3 -6 3 0 
-3 1 0 0 
0 0 0 0 
é
.
êêêêê 
ù
.
úúúúú 
v3 
v2 
v1 
é
.
êêêêê 
ù
.
úúúúú 
通常在实际工作中,一般使用三次以下的贝塞尔曲面进行物体建模与图形设计。三
次贝塞尔曲面已经具有足够的形状变化。
图5-6就是一个16个控制点控制的三次贝塞尔曲面,同时(为了清晰)只绘制出了Y 
轴方向的网格线。
图5-6 16个控制点的双三次贝塞尔曲面及其Y 轴方向上的控制网格
网格(控制)点的坐标点X 、Y、Z 分量如下。
X = 
0 0.3333 0.6667 1.0000 
0 0.3333 0.6667 1.0000 
0 0.3333 0.6667 1.0000 
0 0.3333 0.6667 1.0000