二维图形裁剪
一、点
窗口矩形的大小与位置定义为(xl,yb)与(xr,yt)。
对于任意一点p(x,y),只要满足:xl≤x≤xr且yb≤y≤yt
则点p在矩形窗口内;否则,点p在矩形窗口之外。
二、直线
1.Cohen-Sutherland代码裁剪算法
(1)编码规则
每条线段的端点赋以四位二进制码D3D2D1D0(上下右左),称为区域码,用来标识出端点相对于裁剪矩形边界的位置。编码规则如下:
若x<xl,则 D0=1,否则D0=0;
若x>xr,则D1=1,否则D1=0;
若y<yb,则D2=1,否则D2=0;
若y>yt, 则D3=1,否则D3=0。
(2)解题思路
用区域检测的方法可以有效识别1全在窗口内(0000)——>[即全部可见] 和 2全在窗口上(10XX)OR下(01XX)OR右(XX01)OR左(XX10) ——> [即全部不可见] 的线段。3除此之外的情况需要计算交点
(3)算法过程
<1> 将P1和P2转化为编码形式code1和code2
<2> 进行处理
1若code1=0且code2=0,则该线段在窗口内,取之;
2若code1和code2按位进行与运算,code1 & code2≠0,则两端点必在窗口外的同一部位,弃之;
3若以上两逻辑式都不成立,需要求出直线段与窗口边界的交点,在交点处把线段一分为二,其中必有一段完全在窗口以外,弃之。根据交点位置赋予新的四位编码,直到code1=0且code2=0为止。
PS: 按位进行与运算
运算规则:0&0=0;0&1=0;1&0=0;1&1=1;
#define LEFT 1
#define RIGHT 2
#define BOTTOM 4
#define TOP 8
if ((LEFT & code) != 0)
{x=XL;
y=y1+(y2-y1)*(XL-x1)/(x2-x1);}
else if ((RIGHT & code) != 0)
{x=XR;
y=y1+(y2 -y1)*(XR-x1)/(x2-x1); }
else if ((BOTTOM & code) != 0)
{y=YB;
x=x1+(x2-x1)*(YB-y1)/(y2-y1);}
else if ((TOP & code) != 0)
{y=YT;
x=x1+(x2-x1)*(YT-y1)/(y2-y1); }
2.中点分割裁剪算法(对分法)*
(1)解题思路
与代码裁剪算法一样,首先对直线段端点进行编码,并把
线段与窗口的关系一般分为3种情况:全在、完全不在、线段和窗口有交点,并对前两种情况进行一样的处理。
对于第3种情况,则用中点分割的方法简单地把线段等分
为两段,对两段重复上述测试处理,直至每条线段完全在窗口内和完全在窗口外。
(2)算法过程
p1p2的中点为pm(p2=pm),处理p1p2,p1p2的中点为pm(p1=pm),处理p1p2 ……直至找到距离p1点最近的
可见点A
从p1出发,找出离p1最近的可见点A;
从p2出发,找出离p2最近的可见点B;
AB为p1p2的可见部分。
3.矢量裁剪算法*
4.Liang-Barsky算法
例
5.Sutherland-Hodgman逐边裁剪法
6.边界裁剪算法
在裁剪过程中利用窗口的有效边界,以窗口的有效边界段
和处于窗口内的多边形边线段组成新的裁剪后的多边形。
(1)解题思路
① 把要被裁剪的多边形顶点按逆时针方向排列成一个顶点
序列环;同时把窗口的四个顶点也排列成同方向的环。
② 从该多边形顶点环中的任何一个顶点出发,顺着环的方
向搜索多边形顶点中位于窗口内的顶点,以及多边形边
与窗口有效边的交点。
③ 整个处理过程以搜索路径返回到原多边形的起点结束。