第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样条曲线在三个坐标轴上的投影(0SelectObject(&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