b样条曲面
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验四:B 样条曲面
一.实验目的
用多个B 样条曲线画出一个曲面,并能实现鼠标球滚动。
二.算法思想
B 样条曲面是B 样条曲线的拓广。一块m ⨯n 次B 样条曲面片的数学表示式:)()(),(,,00
w F u F
P w u P n j m
i m i n
j ij
∑∑===
w u , ∈[0,1] 式中,ij P (i =0,1,2,…..,m;
j
=0,1,2,…..n )是定义此曲面片的顶点位置向量矩阵,共计(m+1)
(n+1)个顶点。)()(,,w F u F n j m i 为B 样条基底函数,w u ,为参数。显然,m 与n 不一定相等,如m=n=3,则由4⨯4个顶点构成特征多面体,其相应的B 样条曲面片称为双三次B 样条曲面片。其中:
m i m i m k k m i k i m u c m u F )()1(!1)(10,--+-=+-=∑)!
1(!)!1(1
i m i m C i
m -++=+其中: 展开三次B 样条曲面数学表达式并写成矩阵
()()(
)
()
T
T s T
s W M w
w w w F w F w F w F UM u u u u F u F u F u F w F w F w F w F p p p p p p p p p p p p
p p p p u F u F u F u F w u Q =⎪⎪⎪⎪
⎪⎭
⎫
⎝⎛⎥⎥⎥⎥⎦⎤⎢
⎢⎢⎢
⎣⎡----=
=⎥⎥⎥⎥⎦
⎤⎢
⎢⎢⎢
⎣⎡----=⎥⎥⎥⎥⎦
⎤
⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡=10001133
3406313
3161)()()()(0141
030
303631331611
)()()()()()()()()()()()(),(2343212
3
432143213332
31302322212013121110
03020100
4321其中:
三.程序主要代码
#include
#include
//控制点网络
GPoint3d **gCtrlGrid =NULL ; //
int gNumX=0;
int gNumY=0;
bool loadData(const char *fileName)
{
FILE *fp =fopen(fileName,"r");
if(fp == NULL)return false;
fscanf(fp,"%d %d",&gNumY,&gNumX);
printf("NumY=%d,NumX=%d\n",gNumY,gNumX);
int i,j;
float x,y,z;
gCtrlGrid = new GPoint3d *[gNumY];
for(i=0;i { gCtrlGrid[i]= new GPoint3d[gNumX]; for(j=0;j { fscanf(fp,"%f %f %f\n",&x,&y,&z); gCtrlGrid[i][j].set (x,y,z); printf("%.1f %.1f %.1f\t",x,y,z); } printf("\n"); } fclose(fp); return true; } void drawCtrlGrid() { int i,j; glColor3f(1,1,1); for(i=0;i { for(j=0;j { glBegin(GL_LINES); glVertex3dv(gCtrlGrid[i][j]); glVertex3dv(gCtrlGrid[i][j+1]); glEnd(); } } for(j=0;j { for(i=0;i { glBegin(GL_LINES); glVertex3dv(gCtrlGrid[i][j]); glVertex3dv(gCtrlGrid[i+1][j]); glEnd(); } } } GPoint3d cubicBSpline(int i0,int j0,GPoint3d **ctrlGrid,double u,double v) { double bu[4] ,bv[4]; bu[0]= (-u*u*u+3*u*u-3*u+1)/6.0; bu[1]= (3*u*u*u-6*u*u+4)/6.0; bu[2]= (-3*u*u*u+3*u*u+3*u+1)/6.0; bu[3]= (u*u*u)/6.0; bv[0]= (-v*v*v+3*v*v-3*v+1)/6.0; bv[1]= (3*v*v*v-6*v*v+4)/6.0; bv[2]= (-3*v*v*v+3*v*v+3*v+1)/6.0; bv[3]= (v*v*v)/6.0; int i,j,k; GPoint3d pt; for(k=0;k<3;k++) { pt[k]=0; for(i=0;i<4;i++) { for(j=0;j<4;j++) { pt[k]+=ctrlGrid[i0+i][j0+j][k]*bu[j]*bv[i]; } } } return pt; } void drawBSpline(GPoint3d **ctrlGrid,int ny,int nx) { int i,j,nu,nv,iu,iv; GPoint3d pt0,pt1,pt2,pt3; double u,du,v,dv; nu=10; du=1.0/nu; nv=10; dv=1.0/nv; glColor3f(1,1,0); glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); for(i=0;i { for(j=0;j { for(iv=0,v=0;iv { for(iu=0,u=0;iu { pt0=cubicBSpline(i,j,ctrlGrid,u,v); pt1=cubicBSpline(i,j,ctrlGrid,u,v+dv); pt2=cubicBSpline(i,j,ctrlGrid,u+du,v+dv); pt3=cubicBSpline(i,j,ctrlGrid,u+du,v); glBegin(GL_QUADS); glVertex3dv(pt0); glVertex3dv(pt1); glVertex3dv(pt2); glVertex3dv(pt3); glEnd(); } }