实验五 裁剪原理
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验五裁剪原理
一、实验目的
1.掌握几种常用二维线段裁剪原理;
1.熟悉多边形裁剪算法。
二、实验环境
计算机、Turbo C、C++等其他语言程序设计环境
三、实验学时
4学时,必做实验。
四、实验内容
1. 线段的裁剪原理:编码法;中点分割法;梁友栋-Barsky算法
2. 多边形裁剪原理:逐边裁剪法,双边裁剪法。
五、算法描述
在二维观察中,需要对窗口进行裁剪,即只保留窗口内的那部分图形,去掉窗口外的图形。现假设窗口是标准矩形,即边与坐标轴平行的矩形,由上(y=wyt)、下(y=wyb)、左(x=wxl)、右(x=wxr)四条边描述。
(一)编码裁剪算法(Cohen-Sutherland 算法)
1.算法基本思想
对每条直线段 p1(x1,y1)p2(x2,y2)分三种情况处理:
(1) 直线段完全可见,“简取”之。
(2) 直线段完全不可见,“简弃”之。
(3) 直线段既不满足“简取”的条件,也不满足“简弃”的条件,需要对直线段
按交点进行分段,分段后重复上述处理。
2.算法步骤
(1) 编码
对于任一端点(x,y),赋予一个4 位的二进制码D3D2D1D0。
编码规则如下:
若x 若x>wxr,则D1=1,否则D1=0; 若y 若y>wyt,则D3=1,否则D3=0。 (2) 裁剪 先求出端点p1 和p2 的编码code1 和code2,然后: 若code1|code2=0,对直线段应简取之。 若code1&code2≠0,对直线段可简弃之 若上述两条件均不成立。则需求出直线段与窗口边界的交点。在交点处把线段 一分为二,其中必有一段完全在窗口外,可以弃之。再对另一段重复进行上述 处理,直到该线段完全被舍弃或者找到位于窗口内的一段线段为止。 (3) 求交 假定直线的端点坐标为(x1,y1)和(x2,y2) 左、右边界交点的计算 上、下边界交点的计算 3.算法实现 (1) 输入直线段的两端点坐标:p1(x1,y1)、p2(x2,y2),以及窗口的四条边界坐标:wyt、wyb、wxl 和wxr。 (2) 对p1、p2 进行编码:点p1 的编码为code1,点p2 的编码为code2。 (3)若code1|code2=0,对直线段应简取之,转(6);否则,若code1&code2≠0,对直线 段可简弃之,转(7);当上述两条均不满足时,进行步骤(4)。 (4) 确保p1 在窗口外部:若p1 在窗口内,则交换p1 和p2 的坐标值和编码。 (5) 按左、右、上、下的顺序求出直线段与窗口边界的交点,并用该交点的坐标值替换 p1 的坐标值。也即在交点s 处把线段一分为二,并去掉p1s 这一段。考虑到p1 是窗口外的一点,因此可以去掉p1s。转(2)。 (6) 用直线扫描转换算法画出当前的直线段p1p2。 (7) 算法结束。 4.算法特点:适合特大或特小窗口。 (二)中点分割算法 1.算法基本思想: 设要裁剪的线段是P0P1。中点分割算法可分成两个平行的过程进行,即从P0 点出发找 出离P0 最近的可见点,和从P1 点出发找出离P1 最近的可见点。这两个可见点的连线就是原线段的可见部分。 ——二分逼近思想 中点分割算法的核心思想是通过二分逼近来确定直线段与窗口的交点。 2.算法步骤: (1) 若code1|code2=0,简取之,结束;否则,简弃之,结束;当这两条均不满足时,进 行步骤(2)。 (2) 找出该直线段离窗口边界最远的点和该直线段的中点。判中点是否在窗口内:若中 点不在窗口内,则把中点和离窗口边界最远点构成的线段丢掉,以线段上的另一点和该中点再构成线段求其中点;如中点在窗口内,则又以中点和最远点构成线段,并求其中点,直到中点与窗口边界的坐标值在规定的误差范围内相等,则该中点就是该线段落在窗口内的一个端点坐标。 (3) 如另一点在窗口内,则经(2)即确定了该线段在窗口内的部分。如另一点不在窗口内,则该点和所求出的在窗口上的那一点构成一条线段,重复步骤(2),即可求出落在窗口内的另一点。 (三)梁友栋-Barsky 算法(Liang-Barsky 算法) 1. 算法的基本思想 以直线的参数方程为基础,对不同情况下的裁剪求得相应的参数值。 2. 算法的推导过程 情形一 p k=0 (1)p1=p2=0 若q1<0 或q2<0,则可删除直线段 若q1>=0 且q2>=0,则进一步判断 u=qk/pk(k=3,4) 令 u1=max(0,u|pk<0) u2=min(1,u|pk>0) 若u1>u2,则可删除直线段 若u1<=u2,将u1,u2 代入直线方程,得到直线段的两个可见端点。 (2)p3=p4=0 若q3<0 或q4<0,则可删除直线段 若q3>=0 且q4>=0,则进一步判断 u=qk/pk(k=1,2) 令 u1=max(0,u|pk<0) u2=min(1,u|pk>0) 若u1>u2,则可删除直线段 若u1<=u2,将u1,u2 代入直线方程,得到直线段的两个可见端点。 情形二 p k 不为0 u=qk/pk(k=1,2,3,4) 令 u1=max(0,u|pk<0,u|pk<0) u2=min(1,u|pk>0, u|pk>0) 若u1>u2,则可删除直线段 若u1<=u2,将u1,u2 代入直线方程,得到直线段的两个可见端点。 3. 算法步骤 (1)输入直线段的两端点坐标以及窗口的四条边界坐标。 (2)若Δx=0,则p1=p2=0。进一步判断是否满足q1<0 或q2<0,若满足,则该直线段不在窗口内,转(7)。否则,满足q1>0 且q2>0,则进一步计算u1 和u2。转(5)。 (3)若Δy=0,则p3=p4=0。进一步判断是否满足q3<0 或q4<0,若满足,则该直线段不在窗口内,转(7)。否则,满足q1>0 且q2>0,则进一步计算u1 和u2。转(5)。 (4)若上述两条均不满足,则有p k≠0(k=1,2,3,4)。此时计算u1 和u2。 (5)求得u1 和u2 后,进行判断:若u1>u2,则直线段在窗口外,转(7)。若u1 (6)利用直线的扫描转换算法绘制在窗口内的直线段。 (7)算法结束。 六、参考代码 1、编码裁剪算法(Cohen-Sutherland 算法) /*编码法线段裁剪*/ #include #include int xw_min,xw_max,yw_min, yw_max; main() { int driver,mode; int x1,y1,x2,y2; xw_min=150; yw_min=100; xw_max=500; yw_max=300; driver=DETECT; initgraph(&driver,&mode,""); draw_win(3); x1=60;y1=120;x2=580;y2=270; line(x1,480-y1,x2,480-y2); getch();