1、计算机图形学实验一实验一 二维根本图元的生成与填充实验目的1.了解并掌握二维根本图元的生成算法与填充算法。2.实现直线生成的DDA算法、中点算法和Bresenham算法。3.实现圆和椭圆生成的DDA和中点算法, 对几种算法的优缺点有感性认识。二. 实验容和要求1.选择自己熟悉的任何编程语言, 建议使用VC+6.0。2.创立良好的用户界面,包括菜单,参数输入区域和图形显示区域。3.实现生成直线的DDA算法、中点算法和Bresenham算法。4.实现圆弧生成的中点算法。5.实现多边形生成的常用算法, 如扫描线算法,边缘填充算法。6.实现一般连通区域的基于扫描线的种子填充算法。7.将生成算法以菜单或
2、按钮形式集成到用户界面上。8.直线与圆的坐标参数可以用鼠标或键盘输入。6. 可以实现任何情形的直线和圆的生成。实验报告1用户界面的设计思想和框图。2各种实现算法的算法思想。3算法验证例子。4上交源程序。直线生成程序设计的步骤如下:为编程实现上述算法,本程序利用最根本的绘制元素如点、直线等,绘制图形。如图1-1所示,为程序运行主界面,通过选择菜单及下拉菜单的各功能项分别完成各种对应算法的图形绘制。图1-1 根本图形生成的程序运行界面2创立工程名称为“根本图形的生成单文档应用程序框架1启动VC,选择“文件|“新建菜单命令,并在弹出的新建对话框中单击“工程标签。2选择MFC AppWizard(ex
3、e),在“工程名称编辑框中输入 “根本图形的生成作为工程名称,单击“确定按钮,出现Step 1对话框。3选择“单个文档选项,单击“下一个按钮,出现Step 2对话框。4承受默认选项,单击“下一个按钮,在出现的Step 3Step 5对话框中,承受默认选项,单击“下一个按钮。5在Step 6对话框中单击“完成按钮,即完成“根本图形的生成应用程序的所有选项,随后出现工程信息对话框记录以上步骤各选项选择情况,如图1-2所示,单击“确定按钮,完成应用程序框架的创立。图1-2 信息程序根本3编辑菜单资源设计如图1-1所示的菜单项。在工作区的ResourceView标签中,单击Menu项左边“+,然后双击
4、其子项IDR_MAINFRAME,并根据表1-1中的定义编辑菜单资源。此时VC已自动建好程序框架,如图1-2所示。表1-1 菜单资源表菜单标题菜单项标题标示符ID直线DDA算法生成直线ID_DDALINEBresenham算法生成直线ID_BRESENHAMLINE中点算法生成直线ID_MIDPOINTLINE4添加消息处理函数利用ClassWizard建立类向导为应用程序添加与菜单项相关的消息处理函数,ClassName栏中选择CMyView,根据表1-2建立如下的消息映射函数,ClassWizard会自动完成有关的函数声明。表1-2 菜单项的消息处理函数菜单项ID消 息消息处理函数ID_D
5、DALINECONMMANOnDdalineID_MIDPOINTLINECONMMANOnMidpointlineID_BRESENHAMLINECONMMANOnBresenhamline5程序结构代码,在CMyView.cpp文件中相应位置添加如下代码:/ DDA算法生成直线void CMyView: OnDdaline()CDC* pDC=GetDC();/获得设备指针int xa=100,ya=300,xb=300,yb=200,c=RGB(255,0,0);/定义直线的两端点,直线颜色 int x,y; float dx, dy, k; dx=(float)(xb-xa), dy=
6、(float)(yb-ya); k=dy/dx, y=ya; if(abs(k)1) for (x=xa;xSetPixel (x,int(y+0.5),c); y=y+k; if(abs(k)=1) for (y=ya;ySetPixel (int(x+0.5),y,c); x=x+1/k; ReleaseDC(pDC);说明:1以上代码理论上通过定义直线的两端点,可得到任意端点之间的一直线,但由于一般屏幕坐标采用右手系坐标,屏幕上只有正的x, y值,屏幕坐标与窗口坐标之间转换知识请参考第3章。2注意上述程序考虑到当k 1的情形x每增加1,y最多增加1;当k1时,y每增加1,x相应增加1/k
7、。在这个算法中,y与k用浮点数表示,而且每一步都要对y进展四舍五入后取整。/中点算法生成直线void CMyView:OnMidpointline() CDC* pDC=GetDC();int xa=300, ya=200, xb=450, yb=300,c=RGB(0,255,0); float a, b, d1, d2, d, x, y; a=ya-yb, b=xb-xa, d=2*a+b; d1=2*a, d2=2* (a+b); x=xa, y=ya;pDC-SetPixel(x, y, c);while (xxb) if (dSetPixel(x, y, c); ReleaseDC(
8、pDC);说明:1其中d是xp, yp的线性函数。为了提高运算效率,程序中采用增量计算。具体算法如下:假设当前像素处于d0情况,那么取正右方像素P1(xp+1, yp),判断下一个像素点的位置,应计算d1=F(xp+2, yp+0.5)=a(xp+2)+b(yp+0.5)=d+a;,其中增量为a。假设d=0) s1=1; else s1=-1;if(y2-y1=0) s2=1; else s2=-1;if(deltaydeltax)temp=deltax;deltax=deltay;deltay=temp;interchange=1;else interchange=0;f=2*deltay-
9、deltax;pDC-SetPixel(x,y,c);for(i=1;i=0)if(interchange=1) x+=s1;else y+=s2;pDC-SetPixel(x,y,c);f=f-2*deltax; elseif(interchange=1) y+=s2;else x+=s1;f=f+2*deltay; 说明:1以上程序已经考虑到所有象限直线的生成。2Bresenham算法的优点如下: 不必计算直线的斜率,因此不做除法。 不用浮点数,只用整数。 只做整数加减运算和乘2运算,而乘2运算可以用移位操作实现。Bresenham算法的运算速度很快。圆弧生成程序设计的步骤如下:1创立应用
10、程序框架,以上面建立的单文档程序框架为根底。2编辑菜单资源。在工作区的ResourceView标签中,单击Menu项左边“+,然后双击其子项IDR_MAINFRAME,并根据表1-3中的定义添加编辑菜单资源。此时建好的菜单如图1-3所示。图1-3 程序主菜单表1-3 菜单资源表菜单标题菜单项标题标示符ID圆中点画圆ID_MIDPOINTCIRCLEBresenham画圆ID_BRESENHAMCIRCLE3添加消息处理函数。利用ClassWizard建立类向导为应用程序添加与菜单项相关的消息处理函数,ClassName栏中选择CMyView,根据表1-4建立如下的消息映射函数,ClassWiz
11、ard会自动完成有关的函数声明。表1-4 菜单项的消息处理函数菜单项ID消 息消息处理函数ID_MIDPOINTCIRCLECONMMANOnMidpointcircleID_BRESENHAMCIRCLECONMMANOnBresenhamcircle4程序结构代码,在CMyView.cpp文件中的相应位置添加如下代码。void CMyView:OnMidpointcircle() /中点算法绘制圆,如图1-4所示图1-4 中点算法绘制圆/ TODO: Add your command handler code hereCDC* pDC=GetDC(); int xc=300, yc=300
12、, r=50, c=0; int x,y; float d; x=0; y=r; d=1.25-r;pDC-SetPixel (xc+x),(yc+y),c); pDC-SetPixel (xc-x),(yc+y),c); pDC-SetPixel (xc+x),(yc-y),c); pDC-SetPixel (xc-x),(yc-y),c); pDC-SetPixel (xc+y),(yc+x),c); pDC-SetPixel (xc-y),(yc+x),c); pDC-SetPixel (xc+y),(yc-x),c); pDC-SetPixel (xc-y),(yc-x),c);while(x=y) if(dSetPixel (xc+x),(yc+y),c);pDC-SetPixel (xc-x),(yc+y),c); pDC-SetPixel (xc+x),(yc-y),c); pDC-SetPixel (xc-x),(yc-y),c); pDC-SetPixel (xc+y),(yc+x),c); pDC-SetPixel (xc-y),(yc+x),c); pDC-Se