1、1一、实验目标1. CohenSutherland 线段裁剪;2. LiangBarsky 线段裁剪;3. SutherlandHodgeman 多边形裁剪;二、实验内容一、实验内容在给定的 MFC 程序模板中添加 Cohen_Sutherland 线段裁剪、Liang_Barsky x 线段裁剪、Sutherland_Hodgeman 多边形裁剪,生成新的程序窗口中要有Cohen_Sutherland 线段裁剪、Liang_Barsky x 线段裁剪、Sutherland_Hodgeman 多边形裁剪的菜单按钮,点击按钮分别弹出 Cohen_Sutherland 线段裁剪、Liang_Bar
2、sky 线段裁剪、Sutherland_Hodgeman 多边形裁剪的窗口,通过点击鼠标操作实现裁剪框和线段以及多边形的定义和裁剪。 二、实验原理 1. Cohen_Sutherland 线段裁剪该算法也称为编码算法,首先对线段的两个端点按所在的区域进行分区编码,根据编码可以迅速地判明全部在窗口内的线段和全部在某边界外侧的线段。只有不属于这两种情况的线段,才需要求出线段与窗口边界的交点,求出交点后,舍去窗外部分。对剩余部分,把它作为新的线段看待,又从头开始考虑。两遍循环之后,就能确定该线段是部分截留下来,还是全部舍弃。 编码延长裁剪边框将二维平面分成九个区域,每个区域各用一个四位二进制代码标识
3、。各区代码值如图中所示。四位二进制代码的编码规则是:(1)第一位置 1:区域在左边界外侧 (2)第二位置 1:区域在右边界外侧(3)第三位置 1:区域在下边界外侧 (4)第四位置 1:区域在上边界外侧2裁剪窗口内(包括边界上)的区域,四位二进制代码均为 0。设线段的两个端点为 P1( x1,y1)和 P2(x2,y2),根据上述规则,可以求出 P1 和 P2所在区域的分区代码 C1 和 C2。 判别根据 C1 和 C2 的具体值,可以有三种情况:(1)C1=C2 0,表明两端点全在窗口内,因而整个线段也在窗内,应予保留。(2)C1Invalidate(true);7void CcgdemoVi
4、ew:OnLiangBarsky()/ TODO: Add your command handler code herem_drawstyle = LIANG_BARSKY;Invalidate(true);void CcgdemoView:OnSutherlandHodgeman()/ TODO: Add your command handler code herem_drawstyle = SUTHERLAND_HODGEMAN;Invalidate(true);4. 在 cgdemoView.cpp 的最后分别编写Cohen_Sutherland 线段裁剪的程序:void CohenSu
5、therland(CDC* pDC, CPoint P_begin, CPoint P_end);Liang_Barsky 线段裁剪的程序:void LiangBarsky(CDC* pDC, CPoint P_begin, CPoint P_end);Sutheland_Hodgeman 多边形裁剪程序:void SutherlandHodgeman(CDC* pDC, CArray5. 运行调试程序。四、实验遇到的问题及其解决方法(1) 在调试程序时发现程序运行完并正确达到裁减效果,可是窗口点击放大后,裁剪画面消失;为此将画图的程序语句放在裁剪程序框架外,以解决此问题。(2) 在 Cohe
6、nSutherland 线段裁剪程序编写时,由于k = float (P_end.y - P_begin.y) / float (P_end.x - P_begin.x);求斜率的程序语句未添加 float 将 k 整型,使得线段短点逐渐靠近裁剪框交点的过程中,误差变化越来越大,裁减效果不是预期想要的效果。(3) 在 LiangBarsky 线段裁剪程序编写时,在根据最后得到的 U1 和 U2求新端点坐标的程序语句编写如下:P_begin.x = P_begin.x - u1 * (P_begin.x - P_end.x);P_begin.y = P_begin.y - u1 * (P_beg
7、in.y - P_end.y);P_end.x = P_begin.x - u2 * (P_begin.x - P_end.x);8P_end.y = P_begin.y - u2 * (P_begin.y - P_end.y);由于求新的裁剪后线段终点坐标时,受到上面已经改变的新的起点坐标的影响,使得第二个点求的不正确,在程序运行效果时候表现为:第二个裁剪点明显不符合预期的效果。后更改程序如下,则求新的起始点和新的终点坐标互不影响,程序运行正常P1.x = P_begin.x - u1 * (P_begin.x - P_end.x);P1.y = P_begin.y - u1 * (P_be
8、gin.y - P_end.y);P2.x = P_begin.x - u2 * (P_begin.x - P_end.x);P2.y = P_begin.y - u2 * (P_begin.y - P_end.y);(4) 在SutherlandHodgeman 多边形裁剪的程序编写时:if (i =0)point_pre = arr_ptn-1; / 当前顶点的前一个点else point_pre = arr_pti-1; / 当前顶点的前一个点由于将 if判断语句 if (i = 0) 误写为if (i = 0),使得程序运行出现错误五、实验结论和收获1. 通过本次实验进一步加深了对 VS2008 的编程环境的了解以及 MFC 编程的流程更加熟悉;2. 通过编写程序加深了对 Cohen_Sutherland 线段裁剪、 Liang_Barsky x 线段裁剪、Sutherland_Hodgeman 多边形裁剪的算法原理的理解。