1、浙江大学计算机学院,Bezier Curves and Surfaces,浙江大学计算机学院,本章摘要,多边形表示曲线曲面基础知识二次曲面三次样条Bezier曲线曲面样条曲线曲面曲线曲面OpenGL中的曲线曲面,浙江大学计算机学院,曲线曲面基础知识,1963年Ferguson提出参数化方法;法国雷诺汽车公司的Bezier1971年提出Bezier曲线;De Boor于1972年提出样条算法;Gordon,Riesenfeld将样条用于自由曲线曲面;1975年Versprille在博士论文中首次提出了有理样条方法;1991年ISO将NURBS作为定义工业产品几何形状的唯一数学方法,浙江大学计算机
2、学院,曲线曲面基础知识,隐式方程: F(x,y)=0问题:不具有几何不变性;斜率无穷大会出现溢出问题;不便于计算与编程等问题,浙江大学计算机学院,曲线曲面基础知识,参数化表示优点满足几何不变性;便于几何变换;可处理多值问题和斜率无限大问题;规格化的参数变量便于分片表示;更大的自由度控制曲线曲面形状;便于计算曲线曲面的位置距离导数等;便于用矢量矩阵表示;,浙江大学计算机学院,插值、逼近和拟合,型值点:是指通过测量或计算得到的曲线或曲面上少量描述其几何形状的数据点。控制点:是指用来控制或调整曲线曲面形状的特殊点,曲线曲面本身不一定通过控制点。插值和逼近:这是曲线曲面设计中的两种不同方法。插值设计方
3、法要求建立的曲线曲面数学模型,严格通过已知的每一个型值点。而逼近设计方法建立的曲线曲面数学模型只是近似地接近已知的型值点。拟合:是指在曲线曲面的设计过程中,用插值或逼近的方法使生成的曲线曲面达到某些设计要求。,浙江大学计算机学院,插值、逼近和拟合,浙江大学计算机学院,曲线段间的连续性定义,连续性 : C0连续(0阶参数连续)前一段曲线的终点与后一段曲线的起点相同。 C1连续(一阶参数连续) 两相邻曲线段的连接点处有相同的一阶导数。 C2连续(二阶参数连续) 两相邻曲线段的连接点处有相同的一阶导数和二阶导数。,浙江大学计算机学院,对于参数曲线段若:1)则 在P处具有 连续; 2) 在点P处重合,
4、且在点P处的切矢量方向相同,大小不相等,则 在点P处具有 连续; 3) 在点P处重合,且在P点处的切矢量方向相同,大小相等,则 在点P处具有 连续;,浙江大学计算机学院,4)若 在点处已有 , 连续性,且 的大小和方向均相同,则在点P处具有 连续; 5)若 在点处已有 , 连续性,且 的方向相同,大小不相等,则 在点P处具有 连续;,浙江大学计算机学院,Bezier曲线曲面,Bezier曲线的定义在给定空间个点0,1,n,称下列参数曲线为次的Bezier曲线其中, 是Bernstein基函数,即,浙江大学计算机学院,一般称折线0,1,n为C(u)的控制多边形;0,1,n各点为C(u)的控制顶点
5、。控制多边形是C(u)的大致形状的勾画;C(u)是对0,1,n的逼近。,Bezier曲线曲面,浙江大学计算机学院,常用Bezier曲线的矩阵表示,一次Bezier曲线:矩阵表示为:这是一条从 到 的直线段,浙江大学计算机学院,常用Bezier曲线的矩阵表示,二次Bezier曲线 矩阵表示为,浙江大学计算机学院,常用Bezier曲线的矩阵表示,三次Bezier曲线 矩阵表示为:,浙江大学计算机学院,Bernstein基函数具有下列性质: 1) 非负性: 对于所有的i,n以及 均有 成立; 2) 规范性: 3)对称性,浙江大学计算机学院,4)递推性 5)端点性,浙江大学计算机学院,6)最大性 :
6、在 处达到最大值;7)可导性 8)升阶公式,浙江大学计算机学院,9)分割性10)积分性,浙江大学计算机学院,2Bezier曲线的性质 Bezier曲线C(u)具有以下性质: 1)端点性质 2) 端点切矢量 Bezier曲线在 点处与边 相切,在点 处与边相切。,浙江大学计算机学院,3) 端点的曲率:在C(u)两端点的曲率分别为:这是因为,浙江大学计算机学院,4)对称性 若保持原全部顶点的位置不变,只是把次序颠倒过来,则新的Bezier曲线形状不变,但方向相反。5)几何不变性Bezier曲线的位置和形状只与特征多边形的顶点的位置有关,它不依赖坐标系的选择。,浙江大学计算机学院,6)凸包性 因为是
7、多边形各顶点0,1,n的加权平均,而权因子 ,这反映在几何图形上有两重含义:a.Bezier曲线C(u)位于其控制顶点0,1,n的凸包之内;b.Bezier曲线C(u)随着其控制多边形的变化而变化;7)变差缩减性对于平面Bezier曲线C(u),平面内任意条直线与其交点的个数不多于该直线与其控制多边形的交点个数;,浙江大学计算机学院,4Bezier曲线的De Casteljau算法给定三维空间点 以及一维标量参数u;假定:并且 那么 即为Bezier曲线上参数u处的点。,浙江大学计算机学院,DeCasteljau (P,n,u,C) /* Compute point on a Bezier c
8、urve using DeCasteljau algorithm */* Input : P,n,u */* Output: C (a point) */for(i=0;i=n;i+ ) Qi=Pi ;for(k=1; k=n; k+)for(i=0; i=n-k; i+)Qi=(1.0-u)*Qi+u*Qi+1 ;C=Q0 ;,浙江大学计算机学院,5Bezier曲线的几何作图法利用De Casteljau算法可以以几何方式计算参数值 处的曲线点:1)根据给定的参数值u ,在控制多边形的每条边上确定某一分割点,使分割后的线段之比为u:(1-u);由此得分割点为:由此组成一个边数为(n-1)的新
9、的多边形;,浙江大学计算机学院,2)用相同的方法对该多边形再次分割,得到分割点 形成另一个新的多边形;3)按相同的过程分割n-1次后,得到两个顶点 ,再分割得到所求的点 即为所求的u处的曲线点;,浙江大学计算机学院,Sub-Dividing Bezier Curves,P0,P1,P2,P3,考试!,浙江大学计算机学院,图8.6 Bezier 曲线的几何作图法,浙江大学计算机学院,6Bezier曲线的分割几何作图法中计算得到 的同时也将原Bezier曲线分为两个子曲线段: 就是定义在 上的子曲线段,而 是定义在 上的子曲线段。Bezier曲线的任意分割是指给定两个参数值 求原Bezier曲线
10、上由两点 与 所界定的那段子曲线段的控制顶点:1)先用 对原曲线做一分为二的分割;,浙江大学计算机学院,2) 对 那个子曲线用 做一分为二的分割,所得子曲线段就是所求的原Bezier曲线的子曲线段 Bezier 曲线的分割,浙江大学计算机学院,Bezier曲线的升阶有时为了便于Bezier曲线的修改,需要增加控制顶点提高灵活性,而不要改变原来曲线的形状,也就是将n次的Bezier曲线进行升级表达为n+1次的Bezier曲线,即:只需将左边乘以 然后比较 的系数,即可得到,浙江大学计算机学院,几何意义:1)新的控制顶点是对老的特征多边形在参数 处进行线性插值的结果;2)升阶后的新的特征多边形在老
11、的特征多边形的凸包内;3)升阶后的新的特征多边形更逼近Bezier曲线;,浙江大学计算机学院,例如对于二次Bezier曲线: 升阶后的控制顶点为,浙江大学计算机学院,8. Bezier曲线的顶点反求已知Bezier曲线上给定参数处的位置矢量和参数阶次,利用Bezier曲线定义和端点特性,可列出一组方程,求解方程组,就可得到相应的控制顶点。 例子: 已知三次Bezier曲线上的四个点分别为Q0(120,0),Q1(45,0), Q2(0,45),Q3(0,120),它们对应的参数分别为0, 1/3, 2/3, 1,反求三次Bezier曲线的控制顶点。由已知条件可得方程组:,浙江大学计算机学院,Q
12、0 = P0 (t=0)Q1 = (8/27)P0 + (4/9)P1 + (2/9)P2 + (1/27)P3 (t=1/3)Q2 = (1/27)P0 + (2/9)P1 + (4/9)P2 + (8/27)P3 (t=2/3)Q3 = P3 (t=1)zier曲线的端点性质得到的;其余两式是由三次Bezier曲线的展开式:C(u)=(1-u)3P0+3u(1-u)2P1+3u2(1-u)P2+u3P3 分别将Q0、Q1、Q2、Q3的x、y坐标代入方程组求解,可得:x0 = 120 x1= 35 x2 = 27.5 x3 = 0 y0 = 0 y1 = 27.5 y2 = 35 x3 =
13、120,浙江大学计算机学院,9. Bezier曲线的拼接设有两条Bezier曲线 和 ,其控制顶点分别为:0,2,n 和Q0,Q2,Qm:,浙江大学计算机学院,现考虑两条曲线的拼接,不同阶几何连续的条件如下:1)一阶连续性 根据端矢量条件: 其连续条件为 即 :,浙江大学计算机学院,1) 二阶连续性根据二阶导矢量:为满足连续性条件:可得:,浙江大学计算机学院,Bezier 曲线的拼接,浙江大学计算机学院,Bezier曲面,1定义 在空间给定 个点称下列张量积形式的一般称为Pij为Bezier曲面 的控制顶点;把由两组多边形 (i=0, 1, , n)和 (j=0,1,2, ., m)组成的网称
14、为Bezier曲面 的控制网格,记为,浙江大学计算机学院,控制网格 是 的大致形状勾画;是对 的逼近。 Bezier 曲面,浙江大学计算机学院,2性质Bezier曲面 具有以下性质:1)端点位置: 四个端点分别是 这是因为2)边界曲线 的四条边界线分别是以为控制多边形的Bezier曲线。,浙江大学计算机学院,3)端点的切平面 三角形 所在的平面分别在点 与曲面相切 4)端点法线方向 由端点的切平面知是 在点的法线方向;其余各端点的法向情况也类似,浙江大学计算机学院,5)凸包性 曲面 位于其控制顶点 的凸包性。6)几何不变性 曲面 的形状和位置与坐标系的选取无关,仅仅与各控制顶点的位置有关 7)
15、 变差递减性对于Bezier曲面,空间任意条直线与其交点的个数不多于该直线与其控制多边形的交点个数;,浙江大学计算机学院,3Bezier曲面的De Casteljau算法假定已知 个点构成的Bezier曲面 以及参数下面的De Casteljau算法可计算出相应的曲面上的点坐标:首先对确定的 计算 ,也就是说利用De Casteljau算法计算控制顶点的第 J0行 ;利用(m+1)次 De Casteljau算法计算 ;再次对 计算 的值得到所求的点。,浙江大学计算机学院,DeCasteljauSurf(P, n, m, u, v, S) /* Compute a point on a Bez
16、ier surface */ /* Input : P , n, m, u, v */ /* Output : S */if(n=m)for(j=0;j=m;j+)DeCasteljau(Pj, n, u, Qj) DeCasteljau(Q, m, v, S) ;else for(i=0;i=n;i+)DeCasteljau(Pi, m, v, Qi) ;DeCasteljau(Q, n, u, S) ;,浙江大学计算机学院,4Bezier曲面的微分 阶的Bezier曲面 的偏微分5Bezier曲面的法矢量 Bezier曲面的法矢量等于两个偏微分的叉积;,浙江大学计算机学院,6Bezier曲
17、面的升阶 假设将 阶的Bezier曲面升阶为 ,则:采用Bezier曲线升阶类似的处理方法,得到:,浙江大学计算机学院,若升阶为 ,则:7Bezier曲面的几种表达形式 1)双一次Bezier曲面: 这是一双曲抛物面(马鞍面);2)双二次Bezier曲面,浙江大学计算机学院,该曲面的四条边界是抛物线 3)双三次Bezier曲面:该曲面的四条边界都是三次Bezier曲线;可通过控制内部的四个控制顶点 来控制曲面内部的形状;,浙江大学计算机学院,8Bezier曲面拼接 两块曲面拼接时,若在其公共边界上任一点的切平面重合,则称这两曲面沿其公共边界达到了G1连续。 设 阶Bezier曲面 和另一块 阶
18、曲面 拼接:,浙江大学计算机学院,如果下列条件满足其中k为常数,则 和 沿其公共边界 P(1,v)达到G1连续。,浙江大学计算机学院,浙江大学计算机学院,What Does OpenGL Support?,Evaluators: a general mechanism for working with the Bernstein polynomialsCan use any degree polynomialsCan use in 1-4 dimensionsAutomatic generation of normals and texture coordinatesNURBS support
19、ed in GLUQuadricsGLU and GLUT contain polynomial approximations of quadrics,浙江大学计算机学院,One-Dimensional Evaluators,Evaluate a Bernstein polynomial of any degree at a set of specified valuesCan evaluate a variety of variablesPoints along a 2, 3 or 4 dimensional curveColorsNormalsTexture CoordinatesWe c
20、an set up multiple evaluators that are all evaluated for the same value,浙江大学计算机学院,Setting Up an Evaluator,glMap1f(type,u_min,u_max,stride, order, pointer_to_array),what we want to evaluate,max and min of u,1+degree of polynomial,pointer to control data,separation between data points,Each type must b
21、e enabled by glEnable(type),浙江大学计算机学院,Example,Consider an evaluator for a cubic Bezier curve over (0,1),point data =.; * /3d data /*glMap1f(GL_MAP_VERTEX_3,0.0,1.0,3,4,data);,data are 3D vertices,cubic,data are arranged as x,y,z,x,y,zthree floats between data points in array,glEnable(GL_MAP_VERTEX_3
22、);,浙江大学计算机学院,Evaluating,The function glEvalCoord1f(u) causes all enabled evaluators to be evaluated for the specified uCan replace glVertex, glNormal, glTexCoordThe values of u need not be equally spaced,浙江大学计算机学院,Example,Consider the previous evaluator that was set upfor a cubic Bezier over (0,1),S
23、uppose that we want to approximate the curve with a 100 point polyline,glBegin(GL_LINE_STRIP) for(i=0; i100; i+) glEvalCoord1f( (float) i/100.0);glEnd();,浙江大学计算机学院,Equally Spaced Points,Rather than use a loop, we can set up an equally spaced mesh (grid) and then evaluate it with one function call,gl
24、MapGrid(100, 0.0, 1.0);,sets up 100 equally-spaced points on (0,1),glEvalMesh1(GL_LINE, 0, 99);,renders lines between adjacent evaluated points from point 0 to point 99,浙江大学计算机学院,Bezier Surfaces,Similar procedure to 1D but use 2D evaluators in u and vSet up withglMap2f(type, u_min, umax, u_stride, u
25、_order, v_min, v_max, v_stride, v_order, pointer_to_data)Evaluate with glEvalCoord2f(u,v),浙江大学计算机学院,Example,bicubic over (0,1) x (0,1),point data44=;glMap2f(GL_MAP_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, data);,Note that in v direction data pointsare separated by 12 floats since arraydata is stor
26、ed by rows,浙江大学计算机学院,Rendering with Lines,for(j=0;j100;j+) glBegin(GL_LINE_STRIP); for(i=0;i100;i+) glEvalCoord2f(float) i/100.0, (float) j/100.0); glEnd();glBegin(GL_LINE_STRIP); for(i=0;i100;i+) glEvalCoord2f(float) j/100.0, (float) i/100.0); glEnd();,must draw in both directions,浙江大学计算机学院,Renderi
27、ng with Quadrilaterals,for(j=0; j99; j+) glBegin(GL_QUAD_STRIP); for(i=0; i100; i+) glEvalCoord2f (float) i/100.0, (float) j/100.0); glEvalCoord2f (float)(i+1)/100.0, (float)j/100.0); glEnd():,We can form a quad mesh and render with lines,浙江大学计算机学院,Uniform Meshes,We can form a 2D mesh (grid) in a si
28、milar manner to 1D for uniform spacingglMapGrid2(u_num, u_min, u_max, v_num, v_min, v_max)Can evaluate as before with lines or if want filled polygonsglEvalMesh2( GL_FILL, u_start, u_num, v_start, v_num),浙江大学计算机学院,Rendering with Lighting,If we use filled polygons, we have to shade or we will see sol
29、id color uniform renderingCan specify lights and materials but we need normalsLet OpenGL find themglEnable(GL_AUTO_NORMAL);,浙江大学计算机学院,OpenGL中的Bezier曲线曲面,二次曲面创建二次曲面对象GLUquadricObj*gluNewQuadric() ;void gluDeleteQuadric(GLUquadric *qobj) ;指定二次曲面绘制的方法和状态Void gluQuadricDrawStyle(GLUquadric* qobj,Glenum
30、drawstyle) ;GLU_FILL,GLU_LINE,GLU_POINT,GLU_SILHOUETTEVoid gluQuadricNormals(GLUquadric* qobj,GLenum normals) ;Void gluQuadricOrientation(GLUquadric* qobj,GLenum orientation) ;Void gluQuadricTexture(GLUquadric* qobj,GLenum textureCoords) ;,浙江大学计算机学院,二次曲面,绘制二次曲面球体Void gluSphere(GLUquadric* qobj,GLdou
31、ble radius,GLint slices, Glint stacks) ;园柱Void gluCylinder(GLUquadric* qobj,GLdouble baseRadius,GLdouble topRadius,GLdouble height,GLint slices, Glint stacks) ;圆盘Void gluDisk(GLUquadric* qobj,GLdouble innerRadius,GLdouble outerRadius, GLint slices, Glint stacks) ;部分圆盘Void gluPartialDisk(GLUquadric*
32、qobj,GLdouble innerRadius,GLdouble outerRadius, GLint slices, GLint loops, GLdouble startAngle,Gldouble sweepAngle) ;,浙江大学计算机学院,OpenGL中的二次曲面,二次曲面的绘制请见quadric.c,浙江大学计算机学院,OpenGL中的Bezier曲线,#include #include GLfloat ctrlpoints43 = -4.0, -4.0, 0.0, -2.0, 4.0, 0.0, 2.0, -4.0, 0.0, 4.0, 4.0, 0.0;void init
33、(void) glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, ,浙江大学计算机学院,OpenGL中的Bezier曲线,void display(void) int i; glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINE_STRIP); for (i = 0; i = 30; i+) glEvalCoord1f(GLfloat) i/30.0); glEn
34、d(); /* The following code displays the control points as dots. */ glPointSize(5.0); glColor3f(1.0, 1.0, 0.0); glBegin(GL_POINTS); for (i = 0; i 4; i+) glVertex3fv(,浙江大学计算机学院,OpenGL中的Bezier曲线,void reshape(int w, int h) glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadId
35、entity(); if (w = h) glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0); else glOrtho(-5.0*(GLfloat)w/(GLfloat)h, 5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();,浙江大学计算机学院,OpenGL中的Bezier曲线,void keyboard(unsigned char k
36、ey, int x, int y) switch (key) case 27: exit(0); break; int main(int argc, char* argv) glutInit(,浙江大学计算机学院,OpenGL中的Bezier曲面,#include #include GLfloat ctrlpoints443 = -1.5, -1.5, 4.0, -0.5, -1.5, 2.0, 0.5, -1.5, -1.0, 1.5, -1.5, 2.0, -1.5, -0.5, 1.0, -0.5, -0.5, 3.0, 0.5, -0.5, 0.0, 1.5, -0.5, -1.0,
37、-1.5, 0.5, 4.0, -0.5, 0.5, 0.0, 0.5, 0.5, 3.0, 1.5, 0.5, 4.0, -1.5, 1.5, -2.0, -0.5, 1.5, -2.0, 0.5, 1.5, 0.0, 1.5, 1.5, -1.0;,浙江大学计算机学院,OpenGL中的Bezier曲面,void display(void) int i, j; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glPushMatrix (); glRotatef(85.0, 1.0, 1
38、.0, 1.0); for (j = 0; j = 8; j+) glBegin(GL_LINE_STRIP); for (i = 0; i = 30; i+) glEvalCoord2f(GLfloat)i/30.0, (GLfloat)j/8.0); glEnd(); glBegin(GL_LINE_STRIP); for (i = 0; i = 30; i+) glEvalCoord2f(GLfloat)j/8.0, (GLfloat)i/30.0); glEnd(); glPopMatrix (); glFlush();,浙江大学计算机学院,OpenGL中的Bezier曲面,void
39、init(void) glClearColor (0.0, 0.0, 0.0, 0.0); glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, ,浙江大学计算机学院,OpenGL中的Bezier曲面,void keyboard(unsigned char key, int x, int y) switch (key) case 27: exit(0); break; int main(int argc, char* argv) glutInit(,浙江大学计算机学院,OpenGL中的Bezier曲面,#include #include GLfl
40、oat ctrlpoints443 = -1.5, -1.5, 4.0, -0.5, -1.5, 2.0, 0.5, -1.5, -1.0, 1.5, -1.5, 2.0, -1.5, -0.5, 1.0, -0.5, -0.5, 3.0, 0.5, -0.5, 0.0, 1.5, -0.5, -1.0, -1.5, 0.5, 4.0, -0.5, 0.5, 0.0, 0.5, 0.5, 3.0, 1.5, 0.5, 4.0, -1.5, 1.5, -2.0, -0.5, 1.5, -2.0, 0.5, 1.5, 0.0, 1.5, 1.5, -1.0;,浙江大学计算机学院,OpenGL中的B
41、ezier曲面,void initlights(void) GLfloat ambient = 0.2, 0.2, 0.2, 1.0; GLfloat position = 0.0, 0.0, 2.0, 1.0; GLfloat mat_diffuse = 0.6, 0.6, 0.6, 1.0; GLfloat mat_specular = 1.0, 1.0, 1.0, 1.0; GLfloat mat_shininess = 50.0; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_POSITION, position); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);,