您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 其它文档 > 贝塞尔曲线屏保设计与实现
-0-《计算机图形学》设计报告题目:贝塞尔曲线屏保的设计与实现班级:学号:姓名:教师:完成时间:-1-一、引言贝塞尔曲线又称贝兹曲线或贝济埃曲线,一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋。贝塞尔曲线是计算机图形图像造型的基本工具,是图形造型运用得最多的基本线条之一。它通过控制曲线上的四个点(起始点、终止点以及两个相互分离的中间点)来创造、编辑图形。贝塞尔曲线屏保是Windows早期通常自带的屏幕保护程序,它主要是通过运行变幻着的多条贝塞尔曲线,以防止显示器因长时间保持一个画面而造成老化。VisualC++提供了一个支持屏幕保护的开发库scrnsave.lib,这个库已经定制了一个屏幕保护程序的框架结构,开发者只需要在完成相应的函数和提供相应的资源就可以写出自己的屏幕保护程序。因此,通过VC实现贝塞尔曲线屏保的设计不是难题。二、功能分析1.创建贝塞尔MDI子窗口:HWNDFARCreatePolyWindow();2.实现主窗口中的多重贝塞尔曲线示例窗口功能:LONGAPIENTRYPolyProc();3.demo应用程序:BOOLPolyCreateProc();4.处理多重贝赛尔曲线命令:BOOLPolyCommandProc();5.重新描绘贝塞尔曲线窗口(实现窗口,重置贝塞尔曲线对象):VOIDPolyPaintProc();6.删除多重贝塞尔曲线示例:VOIDPolyDestroyProc();7.获取速度(贝赛尔曲线的每个点都是随机生成;终点的速度要比中间点的速度快。):-2-intPolyNewVel();8.窗口的初始化:VOIDPolyInitPoints();9.重置贝塞尔曲线,重绘多重贝塞尔曲线对象区域:VOIDPolyRedraw();三、概要设计1.贝塞尔曲线数学表达式:Bezier曲线是由多项式调和函数推导出来的,通常n+1个顶点定义一个n次多项式,其参数向量表达式为:,0()()niiniPtPBt(01)t(4-11)在(4-11)中,iP为各定点的位置向量,,()inBt为伯恩斯坦基函数,也就是Bezier多边形的个顶点位置向量之间的调和函数。该函数的表达式为:!,()(1)(1)!()!iniiininnBintttCttini(4-12)如果规定00和0!均为1,那么,当t=0时:00,11,22,,(0)(0)(0)(0)(0)nnnnnnPPBPBPBPB(4-13)在t=0时除第一项外其余各项均为0,所以:000000!(0),()0(10)1!()!nnPPBntPPni(4-14)当t=1时:00,11,22,,(1)(1)(1)(2)(1)nnnnnnPPBPBPBPB在t=1时除最后一页外其余各项均为0,所以:00!(1),(1)1(11)1!()!nnnnPPBnPnPnni(4-15)总上所述,贝塞尔曲线在两端点处的切矢方向是与贝塞尔多边折线的第一条边和最后一条边相一致的,且我们只要确定m个顶点,可以定义一条m-1次的贝塞尔曲线。2.贝塞尔曲线生成算法贝赛尔曲线的每一个顶点都有两个控制点,用于控制在该顶点两侧的曲线的弧度。所以本函数的顶点数组的记录方式是:控制点+顶点+控制点+-3-控制点+顶点+控制点+……。所以两个顶点之间的曲线是由两个顶点以及两个顶点之间的控制点来决定的。doublepowi(doublev,intk){doubletemp=1.0;if(k==0||v==0)return1;else{for(inti=1;i=k;i++)temp=temp*v;}returntemp;}longfac(intm){intI;longtemp=1;if(m==0)return1;else{for(i=2;i=m;i++)temp=temp*I;}returntemp;}voidBezier(POINT*p,intn){intx,y,I,j,k=100;doublet=1.0/k,t1,u,v;doubletemp,temp1,temp2,bi;moveto(p[0].x,p[0].y);for(j=1;jk;j++){t1=j*t;u=t1;v=1-u;x=0;y=0;for(i=0;i=n;i++){temp=double(fac(n)/fac(i)/fac(n-i));temp1=powi(u,i);temp2=powi(v,n-i);bi=temp*temp1*temp2;x=x+bi*p[i].x;y=y+bi*p[i].y;}lineto(x,y);}Lineto(p[n].x,p[n].y);}四、详细设计1.创建贝塞尔MDI子窗口HWNDFARCreatePolyWindow(HWNDhWndClient,intnItem){HANDLEhInstance;MDICREATESTRUCTmcs;staticcharbuffer[256];hInstance=GETINSTANCE(hWndClient);LoadString(hInstance,POLYTITLE,buffer,256);-4-mcs.szClass=POLYCLASS;mcs.szTitle=buffer;mcs.hOwner=hInstance;mcs.x=CW_USEDEFAULT;mcs.y=CW_USEDEFAULT;mcs.cx=CW_USEDEFAULT;mcs.cy=CW_USEDEFAULT;mcs.style=0l;mcs.lParam=(LONG)nItem;return((HWND)SendMessage(hWndClient,WM_MDICREATE,0,(LONG)(LPMDICREATESTRUCT)&mcs));}2.主窗口中的多重贝塞尔曲线示例窗口功能LONGAPIENTRYPolyProc(HWNDhWnd,UINTwMsg,WPARAMwParam,LONGlParam){switch(wMsg){caseWM_CREATE:PolyCreateProc(hWnd);break;caseWM_COMMAND:PolyCommandProc(hWnd,wParam,lParam);break;caseWM_MOVE:PolyRedraw(hWnd);break;caseWM_TIMER:PolyDrawBez(hWnd);break;caseWM_PAINT:PolyPaintProc(hWnd);break;caseWM_DESTROY:PolyDestroyProc(hWnd);break;default:return(DefMDIChildProc(hWnd,wMsg,wParam,lParam));}return(0l);}3.demo应用程序BOOLPolyCreateProc(HWNDhWnd){-5-PPOLYDATAppd;if(AllocWindowInfo(hWnd,sizeof(POLYDATA))){if(ppd=(PPOLYDATA)LockWindowInfo(hWnd)){ppd-nBezTotal=20;ppd-nBezCurr=0;ppd-nColor=0;ppd-hBezBuffer=GlobalAlloc(GHND,(DWORD)(sizeof(BEZBUFFER)*MAX_BEZIER));UnlockWindowInfo(hWnd);PolyInitPoints(hWnd);SetTimer(hWnd,1,50,NULL);return(TRUE);}FreeWindowInfo(hWnd);}return(FALSE);}4.处理多重贝赛尔曲线命令BOOLPolyCommandProc(HWNDhWnd,WPARAMwParam,LONGlParam){hWnd=hWnd;wParam=wParam;lParam=lParam;return(TRUE);}5.重新描绘贝塞尔曲线窗口(实现窗口,重置贝塞尔曲线对象)VOIDPolyPaintProc(HWNDhWnd){HDChDC;PAINTSTRUCTps;if(hDC=BeginPaint(hWnd,&ps))EndPaint(hWnd,&ps);PolyRedraw(hWnd);return;}6.删除多重贝塞尔曲线示例VOIDPolyDestroyProc(HWNDhWnd){PPOLYDATAppd;KillTimer(hWnd,1);if(ppd=(PPOLYDATA)LockWindowInfo(hWnd)){GlobalFree(ppd-hBezBuffer);-6-UnlockWindowInfo(hWnd);}FreeWindowInfo(hWnd);return;}7.获取速度(贝赛尔曲线的每个点都是随机生成;终点的速度要比中间点的速度快。)intPolyNewVel(inti){intnRet;if((i==1)||(i==2))nRet=(int)((lRandom()%VELMAX)/3)+VELMIN;elsenRet=(int)(lRandom()%VELMAX)+VELMIN;return((nRet0)?-nRet:nRet);}8.窗口的初始化VOIDPolyInitPoints(HWNDhWnd){//曲线数组PPOLYDATAppd;LPBEZBUFFERlpBez;intidx;RECTrect;//分配点数组if(ppd=(PPOLYDATA)LockWindowInfo(hWnd)){if(lpBez=(LPBEZBUFFER)GlobalLock(ppd-hBezBuffer)){GetClientRect(hWnd,&rect);//设置结束点和控制点坐标for(idx=0;idxBEZ_PTS-1;idx++){lpBez-pPts[idx].x=lRandom()%rect.right;lpBez-pPts[idx].y=lRandom()%rect.bottom;ppd-pVel[idx].x=PolyNewVel(idx);ppd-pVel[idx].y=PolyNewVel(idx);}GlobalUnlock(ppd-hBezBuffer);}UnlockWindowInfo(hWnd);}return;}-7-9.重置贝塞尔曲线,重绘多重贝塞尔曲线对象区域VOIDPolyRedraw(HWNDhWnd){PPOLYDATAppd;LPBEZBUFFERlpBez,lpCurr;HDChDC;inti,j;RECTrect;if(ppd=(PPOLYDATA)LockWindowInfo(hWnd)){if(lpBez=(LPBEZBUFFER)GlobalLock(ppd-hBezBuffer)){if(hDC=GetDC(hWnd)){lpCurr=lpBez+ppd-nBezCurr;*lpBez=*lpCurr;ppd-nBezCurr=0;for(j=1;jppd-nBezTotal;j++){for(i=0;iBEZ_PTS;i++){(lpBez+j)-pPts[i].x=-1;(lpBez+j)-pPts[i].y=0;}}GetClientRect(hWnd,&rect);BitBlt(hDC,0,0,rect.right,rect.bottom,(HDC)0,0,0,0);ifdefined(_WIN32)&&defined(WIN32)PolyBezier(hDC,lpBez-pPts,BEZ_PTS);elsePolyline(hDC,lpBez-pPts,BEZ_PTS);endifReleaseDC(hWnd,hDC);}GlobalUnl
本文标题:贝塞尔曲线屏保设计与实现
链接地址:https://www.777doc.com/doc-2077548 .html