
非均匀有理B样条.docx
21页非均匀有理B样条(学习记录和上机练习)非均匀有理 B 样条,通常简称为 NURBS(Non-Uniform Rational B-Splines)NURBS 是 非有理B样条、有理以及非有理Bezier曲线曲面的推广一、 Bezier 曲线1、 Bezier 曲线一条n次Bezier曲线可以表示为C (u) = £ B (u) Pi ,n ii=0OW u wi其中,基函数(也称为混合函数)'(u)1是著名的n次Bernstein多项式,i,n(i)其定义为B (u ) =i,nn!i!(n - i)!ui (1 一 u) n-i2)(1) 式中的几何系数& 1称为控制点i//计算参数U的n次基函数值并存在B[]中 void Bernstein(int n,double u,float B[]){double u1;int j,k;B[O]=1.O;u1=1.O-u;for(j=1;j<=n;j++){float saved=O.O;for(k=O;k i图 1 、3 次 Bezier 曲线图 3 、n=3 Bernstein 图形图 5 、Bezier 双三次曲面片二、B样条基函数1、 B 样条基函数的定义和性质图2、3次有理Bezier曲线图 4、 n=9 Bernstein 图形图6、有理Bezier双三次曲面片令U二{uo,ui,…,叮是一个实数序列,即吓u.+i,i二0丄…,m-1其中,U称为节点,U称为节点矢量,用N (u)表示第i个p次(p+1阶)B样条基函数,其定义为: .,pu -u u -uN (u)二 —N (u) + 3 N (u) (4).,p u — u i,p-1 u — u i+1,p-1i+p i i + p+1 i+1由此可知:(1) N (u)是一个阶梯函数,它在半开区间u e [u ,u )外都为零;i,0 i i+1(2) 当p>0时,N (u)是两个p-1次基函数的线性组合;i,p(3) 计算一组基函数时需要事先指定节点矢量U和次数p;( 4)上式中可能出现 0/0,我们规定 0/0=0;(5) N (u)是定义在整个实数轴上的分段多项式函数,它在区间[u ,u ]上有意义;i , p 0 m(6) 半开区间[u ,u )称为第i个节点区间,它的长度可以为零,因为相邻节点可以i i+1是相同的;(7) 计算p次基函数的过程生成一个三角阵列。 性质:1局部支撑性,如果u电[u ,u ),则N (u) =0i i + p +1 i , p2非负性,对于所有的i,p和u,有N (u)三0i,p3规范性,对于任意的节点区间[u ,u ),当u e [u ,u )时丈N (u) = 1i i +1 i i +1 j , pj=i - p4可微性,在节点区间内部,N (u)是无限次可微的(在每个节点区间内部,它是一i,p个多项式),在节点处N (u)是p-k次连续可微的,其中k是节点的重复度i,p2、B样条基函数的导数1 基函数的求导公式为:N' = p N (u) + p N (u) (5)i,p u -u i,p-1 u - u i+1,p-1i+p i i+ p+1 i+1对基函数求导得到一般的求导公式:N (k) = p i,pN (k -1) i, p-1N(k-1)i+1: p—1u - ui+ p iu — ui+p+1 i+1为了完整性,另一个计算B样条基函数各阶导数的公式(参考[Butt76]):N (k)=i, p p - kN (k) —i, p—1u 一 ui+p+1 N (k)i+1, p—1丿k 二 0,1,7)u - ui + p +1 i +1// 〃计算所有非零B样条基函数并返回其值〃i为参数u所在的节点区间下标void BasisFunction(int i,int p,float u,float U[],float N[]){int j,di,dp,k;float tul,tur,left,right;float tmpN[50][50]; for(k=0;k<=p;k++){dp=0;for(di=i+p-k;di>=i-k;di--){ if(u>=U[di]&&u2void DerBasisFunc(int i,int p,float u,float U[],float NP[]){int j,di,dp,k;float tul,tur,left,right,saved,dl,dr;float tmpN[50][50];for(k=0;k<=p;k++){dp=0;for(di=i+p-k;di>=i-k;di--){if(u>=U[di]&&u
i i, p除非另外声明,我们假定a=0,b=1,并且a和b的个数为(p+1)个2 性质:(1)如果 n=p, U={0,...,0,1,...,1},那么 C(u)是 Bezier 曲线(如下图所示)P0P1 八 P2 7图8、定义在U[]={0,0,0,/1,1*};上的三次B样条曲线是三次Bezier曲线(2) C(u)是分段多项式曲线曰严;插是分段多项式函数);次数P,控制点个 数n+1和节点个数m+1满足关系:m=n+P+13) 端点插值性:C(0)=P0,C(1)=P*/(4) 仿射不变性:对B样条曲线进行仿射变换,所得曲线不变5) 强凸包性:曲线C(u)包含在它的控制多边形的凸包内6) 局部修改性:移动P只改变C(u)在区间[u ,u )上的形状这是因为对于如i i i+1(9) C(u)在节点区间内部是无限次可微的10) 变差减少性:任何一个平面与曲线的交点个数不多于它和控制多边形的交点 个数11) 利用重控制顶点是可能的3 B 样条曲线的导矢C(k)(u) = £ N(k)(u)P (9)i, p ii=0〃计算样条曲线的1阶导矢(u所对应的所有点)保存在Der[]中//n=m-p-1//p 为曲线的次数void BSplineDer(int n,int p,float U[],float P[],float Der[]){float N[100],tmp;int i,j;for(i=p+1;i<=n;i++){DerBasisFunc(i,p,U[i],U,N);tmp=0;for(j=i;j>=i-p;j--) tmp+=N[j]*P[j];Der[i-p]=tmp;}}〃计算曲线上的点(u所对应的所有点)保存在Poi[]中//n=m-p-1//p 为曲线的次数void BSplinePoint(int n,int p,float U[],float P[],float Poi[]){float N[100],tmp;int i,j; for(i=p+1;i<=n;i++){BasisFunction(i,p,U[i],U,N);tmp=0; for(j=i;j>=i-p;j--) tmp+=N[j]*P[j];Poi[i-p]=tmp;}}4 B 样条曲面的定义B样条曲面由两个方向的控制点网格,两个节点矢量和单变量B样条基函数的乘积来定 义,其方程为S(u,v)=埜"N (u)N (v)P (10)i,p j,q i, ji=0 j =0节点矢量为和U中含有r+1个节点,V中含有s+1个节点(r=n+p+1 , s=m+q+1 ) 。 图10、双三次B样条曲面5 上机练习下面用双二次B样条曲面生成一个简单飞机模型为例说明曲面生成的过程图11、双二次B样条曲面生成的飞机模型实物图图12、双二次B样条曲面生成的飞机模型网格图程序源如下:#include "glut.h"#include "math.h"//飞机机身头部数据float hx[]={-360,-360,-360,-360,-360,-360,-360,-350,-350,-350,-350,-350,-350,-350,-300,-300,-300,-300,-300,-300,-300,-250,-250,-250,-250,-250,-250,-250,-200,-200,-200,-200,-200,-200,-200,-50,-50,-50,-50,-50,-50,-50, 0,0,0,0,0,0,0};float hy[]={0,0,0,0,0,0,0,0,20,20,0,-20,-20,0,0,40,40,0,-40,-40,0,0,60,60,0,-60,-60,0,0,120,120,0,-60,-60,0,0,110,110,0,-60,-60,0, 0,100,10。
