您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 其它文档 > 计算机图形学实验4-----Hermite-Bezier-B样条三种曲线的绘制
实验四HermiteBezierB样条三种曲线的绘制一、实验目的了解和学习Hermite、Bezier、B样条三种曲线算法掌握基于Win32、VisualC++环境MFC绘制图形配置过程制过程编程实现Hermite、Bezier、B样条三种曲线的绘制二、实验原理三次参数曲线1.曲线段可以用端点、切向量和曲线段之间的连续性等约束条件来定义2.两个端点和两端点处的切向量定义Hermite曲线;3.两个端点和另外两个控制端点切向量的点定义的Bezier曲线;4.由四个控制顶点定义的样条曲线。三、实验关键代码voidCDrawYTQXView::Hermite()//绘制Hermite三次插值样条{inta[4][4]={{2,-2,1,1},{-3,3,-2,-1},{0,0,1,0},{1,0,0,0}};//Mh矩阵系数intb[4][2];//边界点for(inti=0;i4;i++){b[0][0]=p1[i][0];b[0][1]=p1[i][1];//起点的坐标b[1][0]=p1[i+1][0];b[1][1]=p1[i+1][1];//终点的坐标b[2][0]=p2[i][0];b[2][1]=p2[i][1];//起点的导数b[3][0]=p2[i+1][0];b[3][1]=p2[i+1][1];//终点的导数Caculate(a,b);CClientDCdc(this);CPenMyPen,*pOldPen;MyPen.CreatePen(PS_SOLID,1,RGB(0,0,255));pOldPen=dc.SelectObject(&MyPen);dc.MoveTo(p1[i][0],p1[i][1]);for(doublet=0.0;t=1;t+=1.0/400){intx=ROUND(pow(t,3)*result[0][0]+pow(t,2)*result[1][0]+t*result[2][0]+result[3][0]);inty=ROUND(pow(t,3)*result[0][1]+pow(t,2)*result[1][1]+t*result[2][1]+result[3][1]);dc.LineTo(x,y);}dc.SelectObject(pOldPen);MyPen.DeleteObject();}}voidCDrawYTQXView::Caculate(inta[4][4],intb[4][2])//矩阵相乘{inti,j,k;for(i=0;i4;i++)for(j=0;j2;j++)result[i][j]=0;//矩阵清零for(i=0;i2;i++)for(j=0;j4;j++)for(k=0;k4;k++)result[j][i]+=a[j][k]*b[k][i];}voidCDrawYTQXView::DrawBezier()//绘制Bezier曲线{CClientDCdc(this);doublex,y;intrate=400,n;n=CtrlPoint-1;for(doublet=0;t=1;t+=1.0/rate){x=0;y=0;for(inti=0;i=n;i++){x+=pt[i].x*Cnk(n,i)*pow(t,i)*pow(1-t,n-i);y+=pt[i].y*Cnk(n,i)*pow(t,i)*pow(1-t,n-i);}dc.SetPixel(ROUND(x),ROUND(y),RGB(0,0,255));//曲线颜色}}doubleCDrawYTQXView::Cnk(constint&n,constint&i)//Bernstein第一项{returndouble(Factorial(n)/(Factorial(i)*Factorial(n-i)));}intCDrawYTQXView::Factorial(intm)//阶乘函数{intf=1;for(inti=1;i=m;i++)f*=i;returnf;}voidCDrawYTQXView::DrawB3_curves()//绘制B样条曲线{CClientDCdc(this);inti,rate=10,m;longlx,ly;m=CtrlPoint-(3+1);doubleF03,F13,F23,F33;lx=ROUND((pt[0].x+4.0*pt[1].x+pt[2].x)/6.0);//t=0的起点x坐标ly=ROUND((pt[0].y+4.0*pt[1].y+pt[2].y)/6.0);//t=0的起点y坐标dc.MoveTo(lx,ly);CPenMyPen2,*pOldPen2;MyPen2.CreatePen(PS_SOLID,2,RGB(0,0,255));//颜色设置pOldPen2=dc.SelectObject(&MyPen2);for(i=1;im+2;i++)//m+1段三次样条曲线{for(doublet=0;t=1;t+=1.0/rate){F03=(-t*t*t+3*t*t-3*t+1)/6;//计算F0,3(t)F13=(3*t*t*t-6*t*t+4)/6;//计算F1,3(t)F23=(-3*t*t*t+3*t*t+3*t+1)/6;//计算F2,3(t)F33=t*t*t/6;//计算B3,3(t)lx=ROUND(pt[i-1].x*F03+pt[i].x*F13+pt[i+1].x*F23+pt[i+2].x*F33);ly=ROUND(pt[i-1].y*F03+pt[i].y*F13+pt[i+1].y*F23+pt[i+2].y*F33);dc.LineTo(lx,ly);}}dc.SelectObject(pOldPen2);MyPen2.DeleteObject();}voidCDrawYTQXView::DrawCharPolygon()//绘制控制多边形{CClientDCdc(this);CPenMyPen,*pOldPen;MyPen.CreatePen(PS_SOLID,2,RGB(0,0,0));//控制多边形pOldPen=dc.SelectObject(&MyPen);for(inti=0;iCtrlPoint;i++){if(i==0){dc.MoveTo(pt[i]);dc.Ellipse(pt[i].x-2,pt[i].y-2,pt[i].x+2,pt[i].y+2);}else{dc.LineTo(pt[i]);dc.Ellipse(pt[i].x-2,pt[i].y-2,pt[i].x+2,pt[i].y+2);}}dc.SelectObject(pOldPen);MyPen.DeleteObject();}voidCDrawYTQXView::OnLButtonDown(UINTnFlags,CPointpoint)//获得屏幕控制点坐标{//TODO:Addyourmessagehandlercodehereand/orcalldefaultCView::OnLButtonDown(nFlags,point);if(Flag){pt[CtrlPoint].x=point.x;pt[CtrlPoint].y=point.y;if(CtrlPointN_MAX_POINT)CtrlPoint++;elseFlag=false;DrawCharPolygon();}elseDrawCharPolygon1();}voidCDrawYTQXView::OnRButtonDown(UINTnFlags,CPointpoint)//调用绘制函数{//TODO:Addyourmessagehandlercodehereand/orcalldefaultFlag=false;if(Sign==0)Hermite();if(Sign==1)DrawBezier();if(Sign==2)DrawB3_curves();CView::OnRButtonDown(nFlags,point);}四、实验结果1、绘制Hermite曲线2、绘制Bezier曲线3.绘制B样条曲线五、心得体会通过实验进一步学习和了解MFC的菜单的实现及其响应函数的实现,并设置鼠标的左键激活绘制多边形,右键激活绘制Hermite、Bezier、B样条三种曲线。掌握了三个齐次坐标矩阵以及它们各自点的平移,旋转,缩放,错切变换的坐标矩阵。再做实验的同时又很好的复习了考试的内容,一举两得!
本文标题:计算机图形学实验4-----Hermite-Bezier-B样条三种曲线的绘制
链接地址:https://www.777doc.com/doc-5422974 .html