直线段的扫描转换-计算机专业-OpenGL实验-Exp

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

注:1、实验报告的内容:一、实验目的;二、实验原理;三、实验步骤;四、实验结果;五、讨论分析(完成指定的思考题和作业题);六、改进实验建议。2、各专业可在满足学校对实验教学基本要求的前提下,根据专业特点自行设计实验报告的格式,所设计的实验报告在使用前需交实践教学管理科备案。Exp-University实验报告课程名称计算机图形学实验实验项目直线段的扫描转换专业班级姓名Exp学号QQ:289065406指导教师成绩日期2011.11.22一、实验目的1、通过实验,进一步理解直线段扫描转换的DDA算法、中点bresenham算法以及改进bresenham算法的基本原理;2、掌握以上算法生成直线段的基本过程;3、通过编程,会在C/C++环境下完成用DDA算法、中点bresenham算法及bresenham算法对任意直线段的扫描转换。二、实验设备及实验环境1、计算机(每人一台)2、VC++6.0或其他C/C++语言程序设计环境三、实验学时2学时四、实验内容用DDA算法中点bresenham算法及bresenham算法实现任意给定两点的直线段的绘制(直线宽度和线型可自定)。五、实验步骤1、复习有关直线扫描转换算法的基本原理,明确实验目的和要求;2、依据算法思想,绘制程序流程图;3、设计程序界面,要求操作方便;4、用C/C++语言编写源程序并调试、执行;5、分析实验结果6、对程序设计过程中出现的问题进行分析与总结;7、打印源程序或把源程序以文件的形式提交;8、按格式要求完成实验报告。六、实验报告要求:1、各种算法的基本原理;2、各算法的流程图3、实验结果及分析(比较三种算法的特点,界面插图并注明实验条件)4、实验总结(含问题分析及解决方法)七、实验原理1、DDA算法(数值微分法)数值微分法(DDA法,DigitalDifferentialAnalyzer)是一种直接从直线的微分方程生成直线的方法。给定直线的两端点P0(x0,y0)和P1(x1,y1),得到直线的微分方程如下:DDA算法原理:由于直线的一阶导数是连续的,而且对于△x和△y是成正比的,故此可以通过在当前位置上分别加上二个小增量来求下一点的x,y坐标,如下图所示。则有:其中,ε=1/max(|△x|,|△y|)分两种情况讨论如下:(1)max(|△x|,|△y|)=|△x|,即|k|≤1的情况:(2)max(|△x|,|△y|)=|△y|,此时|k|≥1:注意:由于在光栅化的过程中不可能绘制半个像素点,因此对求出的xi+1,yi+1的值需要四舍五入。2、中点Bresenham算法给定直线的两个端点坐标,可以得到直线的方程为:此时直线将平面分成三个区域:对于直线上的点,F(x,y)=0;对于直线上方的点,F(x,y)0;对于直线下方的点,F(x,y)0,如下图所示。图5-2直线将平面分为三个区域基本原理:根据直线的斜率确定或选择变量在x或y方向上每次递增一个单位,而另一方向的增量为1或0,它取决于实际直线与相邻像素点的距离,这一距离称为误差项。如下图所示,假定0≤k≤1,x是最大位移方向。算法每次在x方向上加1,y方向上加0或加1。设当前点是P(xi,yi),则下一个点在Pu(xi+1,yi+1)和Pd(xi+1,yi)中选一。以M点表示Pu与Pd的中点,又设Q点是理想直线与垂线x=xi+1的交点,根据Q点与M点的位置判断选取哪一个点。图5-3Brensemham算法生成直线的原理构造判别式如下:当d0时,M在Q点下方,Pu距离Q点近,取Pu点;若d0,M在Q点上方,Pd距离Q点近,取Pd点;若d=0,M与Q点重合,Pu和Pd都合适,约定取Pd。故有:误差项递推:(1)当d0时,下一个候选点为(xi+1,yi+1),再下两个候选点为(xi+2,yi+1)和(xi+2,yi+2),他们的中点为(xi+2,yi+1.5),故有:此时,d的增量为1-k。(2)当d0时,下一个候选点为(xi+1,yi),再下两个候选点为(xi+2,yi)和(xi+2,yi+1),他们的中点为(xi+2,yi+0.5),故有:此时,d的增量为-k。初始值d的计算:但此时算法中仍然包含了浮点数运算,由于这里我们仅使用了判别式d的符号,所以可以用2d△x代替d来摆脱小数。用2d△x代替d,令D=2d△x则:3、改进Bresenham算法基本原理:假定直线段的0≤k≤1,如下图所示,过各行、各列像素中心构造一组虚拟网格线,按直线起点到终点的顺序计算直线与各垂直网格线的交点,交点与网格线的误差值为d。当d0.5时,直线更接近于像素点(x+1,y+1),当d0.5时,更接近于(x+1,y);当d=0.5时,约定取(x+1,y)。图5-4改进的Brensemham算法绘制直线的原理误差项d的初始值为0,每走一步有d=d+k,一旦y方向上走了一步,就要把d减去1。即有:改进1:令e=d-0.5改进2:用E=2e△x来替换e八、算法流程1、DDA算法(数值微分法)适用于任意斜率的直线2、中点Bresenham算法以下算法流程仅适用于斜率为0k1的直线对于斜率为k1的直线,只需交换x、y的地位即可。对于负斜率(包括-1k0和k-1),只需把对应的正斜率的扫描算法修正为“一个坐标递减而另一个坐标递增”即可。而对于水平、垂直、和k=±1的直线,无需使用扫描算法,直接绘制即可。3、改进Bresenham算法以下算法流程仅适用于斜率为0k1的直线对于斜率为k1的直线,只需交换x、y的地位即可。对于负斜率(包括-1k0和k-1),只需把对应的正斜率的扫描算法修正为“一个坐标递减而另一个坐标递增”即可。而对于水平、垂直、和k=±1的直线,无需使用扫描算法,直接绘制即可。九、实验结果及分析以下实验窗口所显示的直线为随机生成两端点后再绘制,并非通过鼠标点击输入端点。1、DDA扫描算法绘制效果由于描点较密集,通过拉伸窗体放大后可清晰看到“粒子”的效果:DDA算法的核心代码为:voidDDALine(intStrX,intStrY,intEndX,intEndY){intdx=EndX-StrX;intdy=EndY-StrY;doublex=(double)StrX;doubley=(double)StrY;intepsl=max(abs(dx),abs(dy));doublexIncre=(double)dx/(double)epsl;doubleyIncre=(double)dy/(double)epsl;/*描点*/glBegin(GL_POINTS);for(intk=0;k=epsl;k++){//原形:putpixel((int)(x+0.5),(int)(y+0.5),color);glVertex2i((int)(x+0.5),(int)(y+0.5));x+=xIncre;y+=yIncre;}glEnd();return;}通过按B键可改变绘制的像素点的半径,从而改变线粗。这部分功能主要利用OpenGL函数glPointSize()实现。显示效果如下(图片已放大)加粗像素点后,可明显地看到直线的锯齿效果:通过在OpenGL窗口上点击右键,会弹出菜单,选择对应的项可重新选择算法绘制同一条直线,用不同的颜色标识。菜单效果如下:创建菜单的主要代码如下:voidMenu(void){intMainMenu=glutCreateMenu(ProcessMenu);//创建主菜单glutAddMenuEntry(DDA(数值微分)算法扫描直线,1);glutAddMenuEntry(中点Bresenham算法扫描直线,2);glutAddMenuEntry(改进Bresenham算法扫描直线,3);glutAttachMenu(GLUT_RIGHT_BUTTON);//将主菜单与鼠标右键关联return;}2、中点Bresenham算法绘制效果通过菜单切换,可直接得到用中点Bresenham算法绘制同一条直线,绘制效果如下:中点Bresenham算法的核心代码为:voidMid_Bresenham(intStrX,intStrY,intEndX,intEndY){intk;intdetaX=EndX-StrX;intdetaY=EndY-StrY;intsign=detaX*detaY;if(StrX==EndX)//直线垂直于x轴,斜率不存在k=-10;elseif(StrY==EndY)//直线垂直于y轴,斜率k=0k=0;elseif(detaX==detaY)//y=x,k=1k=1;elseif(detaX==-detaY)//y=-x,k=-1k=-1;elseif(sign0&&abs(detaY)abs(detaX))//k1k=2;elseif(sign0&&abs(detaY)abs(detaX))//0k1k=3;elseif(sign0&&abs(detaY)abs(detaX))//k-1k=-2;elseif(sign0&&abs(detaY)abs(detaX))//-1k0k=-3;switch(k){case-10://斜率不存在{if(StrYEndY){Swap(StrX,EndX);Swap(StrY,EndY);}for(inty=StrY;y=EndY;y++){glBegin(GL_POINTS);glVertex2i(StrX,y);glEnd();}break;}case0://k=0{if(StrXEndX){Swap(StrX,EndX);Swap(StrY,EndY);}for(intx=StrX;x=EndX;x++){glBegin(GL_POINTS);glVertex2i(x,StrY);glEnd();}break;}case1://k=1{if(StrXEndX){Swap(StrX,EndX);Swap(StrY,EndY);}for(intx=StrX,y=StrY;x=EndX;x++,y++){glBegin(GL_POINTS);glVertex2i(x,y);glEnd();}break;}case-1://k=-1{if(StrXEndX){Swap(StrX,EndX);Swap(StrY,EndY);}for(intx=StrX,y=StrY;x=EndX;x++,y--){glBegin(GL_POINTS);glVertex2i(x,y);glEnd();}break;}case2://k1{if(StrYEndY){Swap(StrX,EndX);Swap(StrY,EndY);}intdx=EndX-StrX;intdy=EndY-StrY;intx=StrX;inty=StrY;intd=2*dx-dy;intLeftIncre=2*dx;intRightIncre=2*dx-2*dy;while(y=EndY){glBegin(GL_POINTS);glVertex2i(x,y);glEnd();y++;if(d=0){x++;d+=RightIncre;}elsed+=LeftIncre;}break;}case3://0k1{if(StrXEndX){Swap(StrX,EndX);Swap(StrY,EndY);}intdx=EndX-StrX;intdy=EndY-StrY;intx=StrX;inty=StrY;intd=dx-2*dy;intUpIncre=2*dx-2*dy;intDownIncre=-2*dy;while(x=EndX){glBegin(GL_POINTS);glVertex2i(x,y);glEnd();x++;if(d0){y++;d+=UpIncre;}elsed+=DownIncre;}break;}case-2://k-1{if(StrYEndY){Swap(StrX,E

1 / 24
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功