实验7-2一、实验题目在屏幕上使用鼠标绘制任意控制点的控制多边形,基于deCasteljau算法绘制如图7-48所示的Bezier曲线。二、实验思想Bezier曲线上的点,可以使用Bezier曲线方程直接计算,但使用deCasteljau递推算法则要简单的多。1.递推公式给定空间n+1个控制点Pi(i=0,1,2n)及参数t,deCasteljau递推算法表述为:当n=3时,有三次Bezier曲线递推如下第一级递推:第二级递推:第三级递推:)()()1()(111tPttPttPririri]1,0[;,1,0;,2,1trninr0,31,0,22,1,0,1iririr)()()1()()()()1()()()()1()(030212020111010010tPttPttPtPttPttPtPttPttP)()()1()()()()1()(121121111020tPttPttPtPttPttP)()()1()(212030tPttPttP其中:规定:定义Bezier曲线的控制点编号为其中,r为递推次数。deCasteljau已经证明,当r=n时,表示曲线上的点。根据式(7-16)可以绘制n次Bezier曲线。三、实验代码voidCTestView::OnMENUBezierCurve(){//TODO:AddyourcommandhandlercodehereRedrawWindow();MessageBox(单击左键绘制特征多边形,单击右键绘制曲线,提示,MB_OK);pt=newCPoint[N_MAX_POINT];Flag=true;CtrlPoint=0;}voidCTestView::DrawBezier()//绘制Bezier曲线{CClientDCdc(this);intrate=500,n;n=CtrlPoint-1;doublex,y;doublepx[N_MAX_POINT],py[N_MAX_POINT];for(intk=0;k=n;k++){px[k]=pt[k].x;py[k]=pt[k].y;}for(doublet=0;t=1;t+=0.01/rate){x=DeCasteliau(t,px);y=DeCasteliau(t,py);dc.SetPixel(ROUND(x),ROUND(y),RGB(0,0,255));}}doubleCTestView::DeCasteliau(doublet,doublep[])//德卡斯特里奥函数{doublepp[N_MAX_POINT][N_MAX_POINT];intn=CtrlPoint-1;for(intk=0;k=n;k++){pp[k][0]=p[k];}for(intr=1;r=n;r++){for(inti=0;i=n-r;i++)iiPtP)(0riPnP0{pp[i][r]=(1-t)*pp[i][r-1]+t*pp[i+1][r-1];}}return(pp[0][n]);}voidCTestView::DrawCharPolygon()//绘制控制多边形{CClientDCdc(this);CPenNewPen,*OldPen;NewPen.CreatePen(PS_SOLID,3,RGB(0,0,0));OldPen=dc.SelectObject(&NewPen);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(OldPen);NewPen.DeleteObject();}voidCTestView::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-1)CtrlPoint++;elseFlag=false;DrawCharPolygon();}}voidCTestView::OnRButtonDown(UINTnFlags,CPointpoint)//调用绘制函数{//TODO:Addyourmessagehandlercodehereand/orcalldefaultif(CtrlPoint!=0){Flag=FALSE;DrawBezier();}CView::OnRButtonDown(nFlags,point);}四、实验结果截图