您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 双三次Bezier曲面
实验六双三次Bezier曲面一、实验目的根据Bizer曲面的基础知识和数学基础,对其算法进行程序设计,验证算法的正确性,并通过程序结果加深对常用曲面数学模型的理解。二、实验任务(2学时)Bezier曲面算法及其程序设计。三、实验内容和实验步骤1、算法描述Bezier曲面是由Bezier曲线拓广而来,以两组正交的Bezier曲线控制点构造空间网格来生成曲面。m×n次张量积形式的Bezier曲面的定义如下(参照教材P200式7-20):(u,v)∈〔0,1〕×〔0,1〕双三次Bezier曲面定义如下(参照教材P201式7-21):(u,v)∈〔0,1〕×〔0,1〕展开上式,有代入得到:)()(),(m0i,,0,vBuBPvupnjminjji33,,3,3i00(,)()()ijijjpuvPBuBv0,30,00,10,20,31,31,01,11,21,30,31,32,33,32,02,12,22,32,33,03,13,23,33,3()()(,)()()()()()()BvPPPPBvPPPPpuvBuBuBuBuPPPPBvPPPPBv320,3321,3322,333,3()331()363()33()BuuuuBuuuuBuuuBuu320,3321,3322,333,3()331()363()33()BvvvvBvvvvBvvvBvv0,00,10,20,31,01,11,21,3322,02,12,22,33,03,13,23,313313630(,)133001000PPPPPPPPpuvuuuPPPPPPPP3213313630330010001vvv令则有:生成曲面时可以通过先固定u,变化v得到一簇Bezier曲线;然后固定v,变化u得到另一簇Bezier曲线,两簇曲线交织生成Bezier曲面。2、要求:根据给定的16个控制顶点:P00(200,20,0),P01(150,0,100),P02(50,-130,100),P03(0,-250,50);P10(150,100,100),P11(100,30,100),P12(50,-40,100),P13(0,-110,100);P20(140,280,90),P21(80,110,120),P22(30,30,130),P23(-50,-100,150);P30(150,350,30),P31(50,200,150),P32(0,50,200),P33(-70,0,100);使用斜等测投影绘制双三次Bizer网格曲面。3、程序实现步骤:(工程名:BezierCurve2)步骤1:创建“BezierCurve2”工程文件;步骤2:创建类class:“P2”及“P3”;注意:P2为二维点,含有两个成员变量“x,y”,P3含有三个成员变量“x,y,z”。单击右键-“newclass”-选择类型“GenericClass”名称为“P2”及“P3”,添加成员变量(添加至“classEACH_ENTRY{public:”之内):classP2{public:P2();virtual~P2();doublex;doubley;};classP3{public:P3();virtual~P3();321Uuuu321Vvvv1331363033001000beM0,00,10,20,31,01,11,21,32,02,12,22,33,03,13,23,3PPPPPPPPPPPPPPPPP(,)TTbebepuvUMPMVdoublex;doubley;doublez;};步骤3:包含头文件并定义顶点对象。1)在“classCBezierCurve2View:publicCview……”之前添加代码“#includeP3.h”及“#includeP2.h”;#includeP3.h//包含三维坐标点类#includeP2.h//包含二维坐标点类2)在“classCBezierCurve2View:publicCView……”内添加代码:P3P3[4][4];//三维顶点P2P2[4][4];//二维顶点步骤4:添加成员函数。1)Cmn的函数实现,定义成员函数,命名为Multiply_n。方法及过程参照“实验六曲线及曲面生成算法(一)”;2)伯恩斯坦多项式Bm,n(t)的函数实现,添加CBezierCurve2View::bernstein。方法及过程参照“实验六曲线及曲面生成算法(一)”;步骤5:在OnDraw()中添加代码:注意:添加头文件#includemath.h//数学头文件#defineRound(d)int(floor(d+0.5))//四舍五入宏定义上述两行代码添加至:类CBezierCurve2View的所有成员函数代码之前。1)窗口坐标变换,设置客户区中心为原点CBezierCurve2Doc*pDoc=GetDocument();ASSERT_VALID(pDoc);//TODO:adddrawcodefornativedatahereCRectrect;//定义客户区矩形GetClientRect(&rect);//获得客户区的大小pDC-SetMapMode(MM_ANISOTROPIC);//pDC自定义坐标系pDC-SetWindowExt(rect.Width(),rect.Height());//设置窗口范围pDC-SetViewportExt(rect.Width(),-rect.Height());//设置视区范围,x轴水平向右,y轴垂直向上pDC-SetViewportOrg(rect.Width()/2,rect.Height()/2);//客户区中心为原点rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);2)初始化16个控制顶点P3[0][0].x=20;P3[0][0].y=0;P3[0][0].z=200;//P00P3[0][1].x=0;P3[0][1].y=100;P3[0][1].z=150;//P01P3[0][2].x=-130;P3[0][2].y=100;P3[0][2].z=50;//P02P3[0][3].x=-250;P3[0][3].y=50;P3[0][3].z=0;//P03P3[1][0].x=100;P3[1][0].y=100;P3[1][0].z=150;//P10P3[1][1].x=30;P3[1][1].y=100;P3[1][1].z=100;//p11P3[1][2].x=-40;P3[1][2].y=100;P3[1][2].z=50;//p12P3[1][3].x=-110;P3[1][3].y=100;P3[1][3].z=0;//p13P3[2][0].x=280;P3[2][0].y=90;P3[2][0].z=140;//P20P3[2][1].x=110;P3[2][1].y=120;P3[2][1].z=80;//P21P3[2][2].x=30;P3[2][2].y=130;P3[2][2].z=30;//P22P3[2][3].x=-100;P3[2][3].y=150;P3[2][3].z=-50;//P23P3[3][0].x=350;P3[3][0].y=30;P3[3][0].z=150;//P30P3[3][1].x=200;P3[3][1].y=150;P3[3][1].z=50;//P31P3[3][2].x=50;P3[3][2].y=200;P3[3][2].z=0;//P32P3[3][3].x=0;P3[3][3].y=100;P3[3][3].z=-70;//P333)三维控制顶点投影(采用斜等测法)至二维点:for(inti=0;i4;i++)for(intj=0;j4;j++){P2[i][j].x=P3[i][j].x-P3[i][j].z/sqrt(2);P2[i][j].y=P3[i][j].y-P3[i][j].z/sqrt(2);}//以上代码实现:从三维到二维的斜等测投影(参照教材P173:式6-42)4)绘制控制多边形CPenNewPen,*pOldPen;NewPen.CreatePen(PS_SOLID,3,RGB(0,0,0));pOldPen=pDC-SelectObject(&NewPen);for(inti1=0;i14;i1++){pDC-MoveTo(Round(P2[i1][0].x),Round(P2[i1][0].y));for(intj1=1;j14;j1++)pDC-LineTo(Round(P2[i1][j1].x),Round(P2[i1][j1].y));}for(intj2=0;j24;j2++){pDC-MoveTo(Round(P2[0][j2].x),Round(P2[0][j2].y));for(inti2=1;i24;i2++)pDC-LineTo(Round(P2[i2][j2].x),Round(P2[i2][j2].y));}pDC-SelectObject(pOldPen);NewPen.DeleteObject();//以上代码绘制控制多边形5)控制顶点标注序号CStringstr;pDC-SetTextColor(RGB(0,0,255));for(inti3=0;i34;i3++){for(intj3=0;j34;j3++){str.Format(P%d,%d,i3,j3);pDC-TextOut(Round(P2[i3][j3].x+10),Round(P2[i3][j3].y+2),str);}}//以上代码实现“控制顶点标注序号”6)“曲面”生成CPenPenRed(PS_SOLID,1,RGB(255,0,0));//定义红色笔pDC-SelectObject(&PenRed);//选择红色笔绘制曲面doubledt1=0.01,dt2=0.01;doublex,y,u,v;doubleBU03,BU13,BU23,BU33;doubleBV03,BV13,BV23,BV33;//U,V两个方向,三次曲面,共8个基函数for(u=0;u=1;u=u+dt1)for(v=0;v=1;v=v+dt2)//对每一个u,v从0~1循环1/dt2+1次后,//生成一条由1/dt2+1个点用直线串起来的“曲线”//u从0~1循环1/dt2+1次后,生成1/dt1+1条“曲线”{BU03=bernstein(0,3,u);//计算B0,3(u)BV03=bernstein(0,3,v);//计算B0,3(v)BU13=bernstein(1,3,u);//计算B1,3(u)BV13=bernstein(1,3,v);//计算B1,3(v)BU23=bernstein(2,3,u);//计算B2,3(u)BV23=bernstein(2,3,v);//计算B2,3(v)BU33=bernstein(3,3,u);//计算B3,3(u)BV33=bernstein(3,3,v);//计算B3,3(v)//严格按照教材P201页,式7-21,为了简单起见,没有使用复杂的循环x=(BU03*P2[0][0].x+BU13*P2[1][0].x+BU23*P2[2][0].x+BU33*P2[3][0].x)*BV03+(BU03*P2[0][1].x+BU13*P2[1][1].x+BU23
本文标题:双三次Bezier曲面
链接地址:https://www.777doc.com/doc-5706703 .html