1贝齐尔曲面设计 1.1 贝齐尔曲面定义
设Pij(0,1,?n;j?0,1,?m)为(n?1)?(m?1)个空间点列,则m×n次Bezier曲面定义为:
P(u,v)???PijBi,m(u)Bj,n(v)i?0j?0iiBi,m(u)?Cmu(1?u)m?imnu,v?[0,1] (式2-1)
,
其中
Bi,n(v)?Cnjvj(1?v)n?j是Bernstein基函数。依次用线段连
接点列中相邻两点所形成的空间网格,称之为特征网格。
Bezier曲面的矩阵表示式是:
?P00?PP(u,v)??B0,n(u),B1,n(u),?,Bm,n(u)??10????Pn0在一般实际应用中,n、m不大于4。 (1) 双线性Bezier曲面 当m=n=1时
P01?P0m??B0,m(v)??B(v)?P11?P1m???1,m???????????Pn1?Pnm??Bn,m(v)? (式2-2)
11S(u,w)???Bi,1(u)Bj,1(w)piji?0j?0 u,w∈[0,1] (式2-3)
定义一张双线性Bezier曲面。
已知四个角点之后,则
S(u,w)?(1?w)(1?u)?(1?u)p?(1?w)upuwp00011011 (式2-4)
(2) 双二次Bezier曲面 当m=n=2时
S(u,w)???Bi,2(u)Bj,2(w)piji?0j?022 u,w?[0,1] (式2-5)
由此式定义的曲面,其边界曲线及参数坐标曲线均为抛物线。 (3) 双三次Bezier曲面 当m=n=3时
S(u,w)???Bi,3(u)Bj,3(w)piji?0j?033 u,w?[0,1] (式2-6)
?p00?p10S(u,w)?[B0,3(u)B1,3(u)B2,3(u)B3,3(u)]??p20??p30其矩阵表示为
TS(u,w)?UMZBZMZWTp01p11p21p31p02p12p22p32p03??B0,3(w)??B1,3(w)?p13????p23??B2,3(w)????p33??B3,3(w)? (式2-7)
??13?3?3?633232U?[uuu1],W?[www1],Mz????330?00?11?0??0??0?(式2-8)
1.2 贝齐尔曲面性质
1.Bezier曲面特征网格的四个角点正好是Bezier曲面的四个角点,即
P(0,0)=P00 P(1,0)=PM0 P(0,1)=P0N P(1,1)=PMN 2. Bezier曲面特征网格最外一圈顶点定义Bezier曲面的四条边界;Bezier曲面边界的跨界切矢只能与定义该边界的顶点及相邻一排顶点有关,且
P00P10P01, P0nP1nP0,n-1, Pm0Pm-1,0Pm1,
分别是四个角点的切平面;跨界二阶导矢只与定义该边界的及相邻两排顶点有关。几何不变性、凸包性、对称性等性质可由Bezier曲线的相关性质容易推广得到。
图2-1 阴影三角形 1.3 贝齐尔曲面算法
Bezier曲线的递推(de Casteljau)算法,可以推广到Bezier曲面的情形。若给定Bezier曲面特征网格的控制顶点:pij(i?0,1,?m,j?0,1,?n)和一对参数值(u,v),则:
m.n
P(u,v)?Pi,kj,lBi,m(u)Bj,n(v)???P00u,v?[0,1] i j ? 0 式(2-9) ?0一条曲线可以表示成两条低一次曲线的组合,一张曲面可以表示成低一次的四张曲面的线性组合。
m?kn?l??Pi,kj,l其中:
?Pij?k?1,0??(1?u)Pijk?1,0?uPi?1,j?(1?v)Pm,l?1?vPm,l?10,j0,j?1?(k?l?0)(k?1,2,?,m;l?0)(k?m,l?1,2,?,n) 式(2-10)
Pijk,l或: 式(2-11)
上面给出了确定曲面上一点的两种方案。当按(1)式方案执行时,先以u参数值对控制网格u向的n+1个多边形执行曲线de Casteljau算法,m级递推后,得到沿v向由n+1个顶点的中间多边形。
再以v参数值对它执行曲线的de Casteljau算法,n级递推以后,得到一个
mnP00?Pij?1??(1?v)Pij0,l?1?vPi,0j,l??1?(1?u)Pk?1,n?uPk?1,ni0i?1,0?(k?l?0)(k?0;l?1,2,?,n)(k?1,2,?,m;l?n)m0p0j(j?0,1,?n)构成
,即所求曲面上的点。
也可以按(2) 式方案执行,先以v参数值对控制网格沿v向的m+1个多边形执行n级递推,得沿u
0np(i?0,1,?m)构成的中间多边形。再以u参数值对它执行n级递推,得所求点i向由m+1个顶点0mnP00。
1.4 程序设计步骤
1.4.1 Bezier曲面的生成
Bezier曲面是基于Beizer曲线而定义的,有特征网格决定其大致形状,而特征网格是由控制点确定的。因而,绘制Bezier曲面的步骤与绘制Bezie曲面的步骤是一致的: 第一,定义控制点序列; 第二,定义一个二维评价器; 第三,激活二维评价器; 最后,创建网格。
定义一个二维评价器的函数为:glMap2d()或glMap2f()函数,glMap2d()函数的原型为: Void glMap2d(GLenum target, GLdouble u1, GLdouble u2, Glint ustride, Glint uorder, GLdouble v1, GLdouble v2, Glint vorder, Glint uorder, const GLdouble * points);
其中,target参数表示评价器最后生成的坐标类别,它可以取表2-1中的一个常量: 常 量 GL_MAP2_VERTEX_3 GL_MAP2_VERTEX_4 GL_MAP2_INDEX GL_MAP2_COLOR_4 GL_MAP2_NORMAL GL_MAP2_TEXTURE_COORD_1 GL_MAP2_TEXTURE_COORD_2 GL_MAP2_TEXTURE_COORD_3 GL_MAP2_TEXTURE_COORD_4 表2-1 1.4.2 绘制网格曲面 (1)添加一个菜单
含 义 用(x,y,z)描述一个控制点 用(x,y,z,w)描述一个控制点 控制点代表一个颜色素引值 控制点是RGBA颜色值 控制点是一个法线向量 控制点是一个纹理坐标的s分量 控制点是一个(s,t)纹理坐标 控制点是一个(s,t,r)纹理坐标 控制点是一个(s,t,r,q)纹理坐标
添加一个名为Surface的菜单,在其属性对话框里的Caption栏中键入Surface。为其增加一个菜单项,其名为Bezier,在其属性对话框的Caption栏中键入Bezier,勾选Pop-up属性。按表2-2完成。
Caption &Meah &Fill &Texture ID IDM_BZRSUFAC_MESH IDM_BZRSUFAC_FILL IDM_BZRSUFAC_TEXTURE 表2-2
(2)添加保护成员函数
添加一个保护成员函数:BzeSufacMesh(),编辑如下: {
Int I,j;
GLfloat points[4][4][3]= {
{{-0.8f,-0.6f,0.8f},{-0.2f,-0.6f,1.6f},{0.2f,-0.6f,-0.4f},{0.6f,-0.6f,0.8f}}, {{-0.6f,-0.2f,0.8f},{-0.2f,-0.2f,1.6f},{0.2f,-0.2f,-0.4f},{0.6f,-0.2f,0.8f}}, {{-0.6f,0.2f,0.8f},{-0.2f,0.2f,0.4f},{0.2f,0.2f,0.0f},{0.3f,0.2f,-0.4f}}, {{-0.6f,0.6f,0.8f},{-0.2f,0.6f,0.4f},{-0.8f,0.6f,0.0f},{0.8f,0.6f,-0.4f}} };} ////控制点
glMap2f(GL_MAP2_VERTEX_3,0,1,3,4,0,1,12,4,(float*)controlPoints);// 二维评价器 glEnable(GL_MAP2_VERTEX_3); glColor3f(0,0,1); //激活 glPushMatrix(); glRotated(45,1,1,1); for (j=0;j<8;j++){ glBegin(GL_LINE_STRIP); for (i=0;i<30;i++){ glEvalCoord2f((float)i/30,(float)j/8); } glEnd(); glBegin(GL_LINE_STRIP); for (i=0;i<30;i++){ glEvalCoord2f((float)j/8,(float)i/30); } glEnd(); } glPopMatrix(); //绘制
glDisable(GL_MAP2_VERTEX_3); //挂起
该函数将绘制一个网格曲面,因为glBegin()函数的参数为GL_LINE_STRIP。 (3)编辑DrawScenc()函数
在语句switch(m_typeControl){….}中添加语句:
Case BezierSrufaceMesh: BzrSufacMesh(); break; (4)运行程序,得到如图2-2的结果
图2-2 Bezier网格曲面 1.4.3 绘制一个填充曲面 (1)增加两个保护函数
Lighting()和BzrSufacFill()函数, Lighting()函数光照处理,BzrSufacFill()函数则绘制曲面。 Lighting(); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); //光照 glMap2f(GL_MAP2_VERTEX_3,0,1,3,4,0,1,12,4,(float*)controlPoints); //二维评价器 glMapGrid2f(30,0,1,30,0,1); //自动网格 glEnable(GL_MAP2_VERTEX_3); //激活 glPushMatrix(); glRotated(45,1,1,1); glEvalMesh2(GL_FILL,0,30,0,30); glPopMatrix(); //绘制 glDisable(GL_MAP2_VERTEX_3); glDisable(GL_AUTO_NORMAL); glDisable(GL_NORMALIZE); glDisable(GL_LIGHTING); //挂起 (2)编辑DrawScene()函数
在语句switch(m_typeControl){….}中添加语句;
Case BezierSurfaceFill: BzeSufacFill(); break; (3)运行程序,得到如图2-3的结果
图2-3 Beizer填充曲面 1.4.4 三次贝齐尔曲面
通过改变控制点坐标即可改变曲面的形状,这是Bezier曲面的一个特性。说明:程序输出的是斜二