《图形学实验报告直线段的裁剪算法.docx》由会员分享,可在线阅读,更多相关《图形学实验报告直线段的裁剪算法.docx(7页珍藏版)》请在三一办公上搜索。
1、图形学实验报告直线段的裁剪算法实 验 报 告 Experimentation Report of Taiyuan teachers College 报 告 内 容 一、 实验目的 四、实验方法 二、 实验原理 五、实验记录及数据处理 三、 实验仪器及材料 六、误差分析及讨论 系 部 计算机系 年 级 三年级 课 程 图形学 姓 名 同组者 日 期 项 目 直线段的裁剪算法 一、实验目的: 1.熟悉图形裁剪的基本知识 2.掌握Cohen-Sutherland 直线裁剪算法 二、实验内容: 在矩形窗口的裁剪算法中,考虑到构成图形的基本元素就是线段,曲线可看成是有很多小线段逼近而成的,因此,讨论线段
2、的裁剪算法更为实用,即Cohen-Sutherland裁剪算法。 Cohen-Sutherland裁剪算法具体思路如下。 任意平面线段和矩形窗口的位置关系只会有如下3种: 完全落在窗口内。 完全落在窗口外。 部分落在窗口内,部分落在窗口外。 要想判断线段和窗口的位置关系,只要找到线段的两端点相对于矩形窗口的位置即可, 线段的两端点相对于矩形窗口的位置可能会有如下几种情况: 线段的两个端点均在窗口内,这时线段全部落在窗口内,完全可见,应予以保留。 线段的两个端点均在窗口边界线外同侧,这时线段全部落在窗口外,完全不可见,应予以舍弃。 线段的一个端点在窗口内,另一个端点在窗口外,这时线段部分可见,应
3、求出线段与窗口边界线的交点,从而得到线段在窗口内的可见部分。 续页 线段的两个端点均不在窗口内,但不处于窗口边界线外同侧,这时有可能线段是部分可见的,也可能是完全不可见的。 Cohen-Sutherland裁剪算法就是按照上述思路来对线段进行裁剪的,只是在线段的两端点相对于矩形窗口的位置上,巧妙地运用了编码的思想。 首先,延长窗口的四条边界线,将平面划分成9个区域,然后,用四位二进制数C3C2C1C0对这9个区域进行编码,编码规则如下: 第0位C0:当线段的端点在窗口的左边界之左时,该位编码为1,否则,该位编码为0。 第1位C1:当线段的端点在窗口的右边界之右时,该位编码为1,否则,该位编码为
4、0。 第2位C2:当线段的端点在窗口的下边界之下时,该位编码为1,否则,该位编码为0。 第3位C3:当线段的端点在窗口的上边界之上时,该位编码为1,否则,该位编码为0。 于是算法步骤可描述如下: 步骤1:根据上述编码规则,对线段的两个端点进行编码。 步骤2:根据线段的两端点编码判断线段相对于窗口的位置关系,从而决定对线段如何剪取。 两端点编码全为0000时,说明线段完全位于窗口内,是完全可见的,于是显示此线段。 两端点编码逐位逻辑与不为0时,说明线段的两个端点位于窗口外同侧,即此线段完全位 于窗口外,是完全不可见的,于是全部舍弃,不显示此线段。 两端点编码逐位逻辑与为0时,说明此线段或者部分可
5、见,或者完全不可见。此时需要计 算出线段与窗口某一边界线或边界线的延长线的交点,若交点在窗口边界线的延长线上, 则说明该线段完全位于窗口外,不予以显示;若交点在窗口边界线上,则对以其中一个 交点为分割点的两端线段,再分别对其端点进行编码,并按照上述和所示的 方法进行测试,从而舍弃完全位于窗口外的一段线段,保留并显示完全位于窗口内的一段线段。 三、实验代码: Cohen-SutherLand实现裁剪直线的两个关键函数 /计算点 x,y的编码 void CCohenSutherLandView:CompOutCode(float x,float y,CRect* rect,OutCode* out
6、Code) outCode-all = 0; outCode-top = outCode-bottom =0; if (y top) outCode-top = 1; outCode-all += 1; 续页 else if (y rect-bottom) outCode-bottom = 1; outCode-all += 1; outCode-right = outCode-left = 0; if (x rect-right) outCode-right = 1; outCode-all += 1; else if(x left) outCode-left = 1; outCode-al
7、l += 1; /Cohen-SutherLand线段裁剪算法 void CCohenSutherLandView:CohenSutherLineClip(CDC* pDC,float x0,float y0,float x1,float y1, CRect* rect) BOOL accept,done; OutCode outCode0,outCode1; OutCode *outCodeOut; float x,y; accept = FALSE; done = FALSE; CompOutCode(x0,y0,rect,&outCode0); CompOutCode(x1,y1,rec
8、t,&outCode1); do if (outCode0.all = 0 & outCode1.all = 0) /完全可见 accept = TRUE; done = TRUE; else if (outCode0.all & outCode1.all) != 0) /显然可见 done = TRUE; 续页 else /进行求交测试 if (outCode0.all != 0) outCodeOut = &outCode0; else outCodeOut = &outCode1; if (outCodeOut-left) y = y0 + (y1 - y0) * (rect-left
9、- x0) / (x1 - x0); /线段与窗口左边求交 x = (float)rect-left; else if (outCodeOut-top) x = x0 + (x1 - x0) * (rect-right - y0) / (y1 - y0); /线段与窗口上边求交 y = (float) rect-top; else if (outCodeOut-right) y = y0 + (y1 - x0) * (rect-right - x0) / (x1 - x0); /线段与窗口右边求交 x = (float)rect-right; else if (outCodeOut-botto
10、m) x = x0 + (x1 - x0) * (rect-bottom - x0) / (y1 - y0); /线段与窗口下边求交 y = (float)rect-bottom; if (outCodeOut -all = outCode0.all) x0 = x; /以交点为界,将线段位于窗口所在的直线的外侧的部分丢弃 y0 = y; /剩下的继续 CompOutCode(x0,y0,rect,&outCode0); else 续页 x1 = x; y1 = y; CompOutCode(x1,y1,rect,&outCode1); while(!done); if (accept) pDC-MoveTo(int(x0),int(y0); pDC-LineTo(int(x1),int(y1); 四、实验总结 通过本次实验了解到Cohen-Sutherland 直线裁剪算法特点是用编码方法可快速判断完全可见或完全不可见的线段,因此特别适合窗口特别大或者窗口特别小的情形。在编写本算法时,一开始总是有些图形可以运行,有些图形不能运行,后来经过不断完善,最后克服了此缺陷。