计算机图形学 5.5裁剪算法

合集下载

计算机图形学基础教程

计算机图形学基础教程

若直线既不满足“简取”也不满足 “简弃”的条件,直线必然与窗口相交, 需要计算直线与窗口边界的交点。交点 将直线分为两段,其中一段完全位于窗 口外,可“简弃”之。对另一段赋予交 点处的区域编码,再次测试,再次求交, 直至找到确定完全位于窗口内的直线段 为止。 实现时,一般按固定顺序左 (x=wxl),右(x=wxr)、下(y=wyb)、 上(y=wyt)求解窗口与直线的交点。
规格化设备坐标系是将设备坐标系规格化到(0.0, 0.0)到(1.0,1.0)的范围内而定义的坐标系。规格化 设备坐标系独立于具体输出设备。一旦图形变换到规格 化设备坐标系中,只要作一个简单的乘法运算即可映射 到具体的设备坐标系中。由于规格化设备坐标系能统一 用户各种图形的显示范围,故把用户图形变换成规格化 设备坐标系中的统一大小标准图形的过程叫作图形的逻 辑输出。把规格化设备坐标系中的标准图形送到显示设 备上输出的过程叫作图形的物理输出。有了规格化设备 坐标系后,图形的输出可以在抽象的显示设备上进行讨 论,因而这种图形学又称为与具体设备无关的图形学。
在计算机图形学术语中,窗口最初是指 要观察的图形区域。但是随着Windows的出
现,窗口概念已广泛用于图形系统中,泛指
任何可以移动,改变大小、激活或变为无效
的屏幕上的矩形区域。在本章中,窗口回归
到其的原始定义,是在观察坐标系中确定输
出图形范围的矩形区域。
5.4.3 窗视变换矩阵
窗口和视区的边界定义如图5-23所示,假 定把窗口内的一点P(xw,yw)变换为视区中的 一点P’(xv,yv)。这属于相对于任一参考点 的二维几何变换,变换步骤为:
码RC=C4C3C2C1。
wyt 窗口 0000 wyb
1001
1000

计算机图形学-实验报告三-图形裁剪算法

计算机图形学-实验报告三-图形裁剪算法

计算机图形学-实验报告三-图形裁剪算法实验题目:实验三图形裁剪算法1.实验目的:理解区域编码(Region Code,RC)设计Cohen-Sutherland直线裁剪算法编程实现Cohen-Sutherland直线裁剪算法2.实验描述:设置裁剪窗口坐标为:wxl=250;wxr=850;wyb=250;wyt=450;裁剪前如下图所示:裁剪后结果为:3.算法设计:Cohen-Sutherland 直线裁剪算法:假设裁剪窗口是标准矩形,由上(y=wyt)、下(y=wyb)、左(x=wxl)、右(x=wxr)四条边组成,如下图所示。

延长窗口四条边形成9个区域。

根据被裁剪直线的任一端点P(x,y)所处的窗口区域位置,可以赋予一组4位二进制区域码C4C3C2C1。

编码定义规则:第一位C1:若端点位于窗口之左侧,即X<Wxl,则C1=1,否则C1=0。

第二位C2:若端点位于窗口之右侧,即X>Wxr,则C2=1,否则C2=0。

第三位C3:若端点位于窗口之下侧,即Y<Wyb,则C3=1,否则C3=0。

第四位C4:若端点位于窗口之上侧,即Y>Wyt,则C4=1,否则C4=0。

裁剪步骤:1. 若直线的两个端点的区域编码都为0,即RC1|RC2=0(二者按位相或的结果为0,即RC1=0 且RC2=0),说明直线两端点都在窗口内,应“简取”。

2. 若直线的两个端点的区域编码都不为0,即RC1&RC2≠0(二者按位相与的结果不为0,即RC1≠0且RC2≠0,即直线位于窗外的同一侧,说明直线的两个端点都在窗口外,应“简弃”。

3. 若直线既不满足“简取”也不满足“简弃”的条件,直线段必然与窗口相交,需要计算直线与窗口边界的交点。

交点将直线分为两段,其中一段完全位于窗口外,可“简弃”。

对另一段赋予交点处的区域编码,再次测试,再次求交,直至确定完全位于窗口内的直线段为止。

4. 实现时,一般按固定顺序左(x=wxl)、右(x=wxr)、下(y=wyb)、上(y=wyt)求解窗口与直线的交点。

计算机图形学裁剪技术

计算机图形学裁剪技术


求交测试顺序固定(左右下上) 最坏情形,线段求交四次。
裁剪
直线段裁剪
Cohen-Sutherland算法 中点分割算法 参数化裁剪算法 Liang-Barskey算法
多边形裁剪
Sutlerland_Hodgman算法
Weiler-Athenton算法
字符裁剪
裁剪

裁剪:确定图形中哪些部分落在显示区之内, 哪些落在显示区之外 , 以便只显示落在显示区 内的那部分图形。这个选择过程称为裁剪。在 进行裁剪时,画面中对应于屏幕显示的那部分 区域称为窗口。
Cohen-Sutherland算法

将区域码的各位从右到左编号,则坐标区 域与各位的关系为:
任何位赋值为1,代表端点落在相应的位置上,否则该 位为0。若端点在剪取矩形内,区域码为0000。如果端 点落在矩形的左下角,则区域码为0101。
直线段裁剪

裁剪线段与窗口的关系:(1)线段完全可见;(2) 显然不可见;(3)其它 提高裁剪效率: 快速判断情形(1)(2), 对于情形(3),设法减 少求交次数和每次求 交时所需的计算量。
常用的线段裁剪方法三种:

Cohen-Sutherland算法 中点分割算法 参数化裁剪算法
Cohen-Sutherland裁剪

基本思想:
对于每条线段P1P2分为三种情况处理: (1)若P1P2完全在窗口内,则显示该线段P1P2。 (2)若P1P2明显在窗口外,则丢弃该线段。
(3)若线段不满足(1)或(2)的条件,则在交点处把线段
分为两段。其中一段完全在窗口外,可弃之。然后对另一段 重复上述处理。

如何实现上述的处理呢?
实现方法:采用下面的编码方法

计算机图形学(简单多边形裁剪算法)

计算机图形学(简单多边形裁剪算法)

简单多边形裁剪算法摘要:多边形裁剪算法与线性裁剪算法具有更广泛的实用意义,因此它是目前裁剪研究的主要课题。

本文主要介绍了一种基于多边形顶点遍历的简单多边形裁剪算法,它有效降低了任意多边形裁剪复杂度。

通过记录交点及其前驱、后继信息,生成结果多边形,该算法简化了交点的数据结构,节省了存储空间,降低了算法的时间复杂度,具有简单、易于编程实现、运行效率高的特点。

关键词:多边形裁剪;交点;前驱;后继;矢量数组一、技术主题的基本原理简单多边形裁剪算法综合考虑现有多边形裁剪算法的优缺点,它是一种基于多边形顶点遍历来实现简单多边形裁剪工作的。

其主要的原理是遍历多边形并把多边形分解为边界的线段逐段进行裁剪,输出结果多边形。

二、发展研究现状近年来,随着遥感绘图、CAD辅助设计、图象识别处理技术的发展,图形裁剪算法从最初在二维平面上线和图形的裁剪扩展到三维空间里体和场的裁剪,国内外相继提出不少行之有效的算法,但越来越复杂的图形和计算也对算法的速度和适用性提出了越来越高的要求。

因此,不断简化算法的实现过程,完善细节处理,满足大量任意多边形的裁剪也就成了当今算法研究的焦点之一。

以往多边形裁剪算法不是要求剪裁多边形是矩形,就是必须判断多边形顶点的顺时针和逆时针性,即存在不实用或者是增加了多边形裁剪算法的难度。

为了解决现在的问题,我们研究现在的新多边形算法,其中,裁剪多边形和被裁剪多边形都可以是一般多边形,且不需要规定多边形输入方向。

它采用矢量数组结构,只需遍历剪裁多边形和被裁剪多边形顶点即完成多边形的裁剪,具有算法简单、运行效率高的特点。

三、新算法设计1、算法的思想本算法是为了尽量降低任意多边形裁剪算法复杂度而提出的,其主要思想是采用矢量数组结构来遍历裁剪多边形和被裁多边形顶点,记录裁剪多边形和被裁减多边形交点及其前驱、后继信息,并通过记录相邻交点的线段,然后通过射线法选择满足条件的线段,之后进行线段连接,输出对应的裁剪结果。

计算机图形学第四讲

计算机图形学第四讲
第一位为1:端点处于上边界的上方 第二位为1:端点处于下边界的下方 第三位为1:端点处于右边界的右方 第四位为1:端点处于左边界的左方 否则,相应位为0
11
1001 0001
xL
A
B
C
1000 0000 E 裁剪窗口 0100
xR
第4讲 图形裁剪算法
1010 D yT 0010
7
第4讲 图形裁剪算法
直线裁减的效率策略
首先,通过方法来快速判断完全在窗口内和完全 在窗口外的直线 若是部分在窗口内的情况,则设法减少直线的求 交次数和每次的求交计算量
8
第4讲 图形裁剪算法
直线裁剪算法
Cohen-Sutherland裁剪算法 中点分割算法 梁友栋-Barsky裁剪算法
9
第4讲 图形裁剪算法
Cohen-Sutherland裁剪算法(编码裁剪法)
基本思想:对于每条待裁剪的线段P1P2分三种情 况处理
若P1P2完全在窗口内,则显示该线段 若P1P2完全在窗口外,则丢弃该线段 若线段不满足上述条件,则求线段与窗口边界的交点, 在交点处把线段分为两段,其中一段完全在窗口外, 可舍弃之,然后对另一段重复上述处理
P1
P1
P1
A
Pm
A Pm A B B P2
B Pm
18
P2
P2
第4讲 图形裁剪算法
算法特点
对分辨率为2N×2N的显示器,上述二分过程至多 进行N次 主要过程只用到加法和除法运算,适合硬件实现, 它可以用左右移位来代替乘除法,这样就大大加 快了速度
19
第4讲 图形裁剪算法
梁友栋-Barsky裁剪算法
13
第4讲 图形裁剪算法

计算机图形学 第5章 裁剪

计算机图形学 第5章 裁剪

3.直线裁剪实例 例5.1 用编码算法裁剪如图5-3(a)所示中的直线段 AB。
图5-3 AB线段的裁剪过程
例5.2 用编码算法裁剪如图5-4(a)所示中的直线段MN。
图5-4 MN线段的裁剪过程
5.1.2 中点分割算法 算法步骤:输入线段端点p1,p2;对于端点p2: (1) p2是否可见,若可见,则它为离p1最远的可见点, 处理结束。 (2) plp2是否全不可见,若是,没有输出,处理结束。 (3) 让pa = p1,pb = p2。
边 V1V2 V2V3 V3V4 V4V5 V5V1 n (1,1) (4,-3) (-1,-2) (-4,3) (0,1) f (2,0) (3,6) (3,6) (4,0) (2,0) w [-4,1] [-5,-5] [-5,-5] [-6,1] [-4,1] w· n -3 -5 15 27 1 D· n 11 30 -13 -30 2 -1/2 tL 3/11 1/6 15/13 9/10 tu
外裁剪有两个重要的应用。
(1) 应用于凹多边形裁剪窗口的线段裁剪。如图5-9 所示线段p1p2相对于凹多边形vlv2v3v4v5v1进行裁剪。 连接v2v4,v1v2v4v5v1为凸多边形,应用Cyrus-Beck算 法,先将p1p2对此凸多边形作内裁剪得到,再将对多 边形v2v3v4v2作外裁剪,最后得到窗口内部分为和。
(4) 沿vi+1p1将多边形一分为二,一个多边形由vi+1, vi+2,…, p1vi+1组成,另一个多边形由vip1及其余顶点组 成。 (5) 对分割的两个多边形递归地重复以上步骤,直到 所有新产生的多边形均为凸,算法结束。
5.1.7 Sutherland-Hodgman逐次多边形裁剪算法 多边形由顶点表p1, p2,…, pn所定义,于是边表为p1p2, p2p3,…, pn-1pn和pn p1。算法的基本思想是将原多边形和 每次裁剪所生成的多边形逐次对裁剪窗口的每一条边 界进行裁剪。考虑图5-12(a)原多边形被窗口左边界所 裁剪,如图5-12(b)所示;生成的多边形又被窗口顶边 所裁剪,如图5-12(c)所示;继续这一过程,生成的中 间多边形被窗口的右边界,如图5-12(d)所示,直至下 边界裁剪完,如图5-12(e)所示为止。

计算机图形学之裁剪算法

计算机图形学之裁剪算法

窗口特别小的场合。
2、中点裁剪法
中点分割裁剪法是将Cohen-Sutherland 算法中求线段与窗口边界的交点的过程用折 半查找(即求中点)的方法来代替。仍然采 用对线段端点进行编码的方式判断完全可见 和显然完全不可见的线段,对于与窗口有交 点的线段,该算法分别求离两个端点最近 (或最远)的可见点。这两个可见点之间的 线段即是原线段的可见部分。
计算P1P2的最近可见点Pma和 Pmb : (一)直线段P1P2的一个端点可见, P1 另一个端点不可见。 只需解算不可见端点的最近的 可见点。 1)设P1不可见,计算P1P2的中点Pm1。
P1
pm
P2
P2
判断中点Pm1如果落在(接近)窗口边上,则 确定该中点为最近可见点。裁剪结束。否则,
2)判断Pm1是否可见: 如果Pm1可见,以Pm1取代P2 ,返回到 1)计算 P1Pm1的中点Pm2,判断Pm2 如果Pm1不可见,以Pm1取代P1 ,返回到 1)计 算Pm1P2的中点Pm2,判断Pm2
关键: 根据多边形的边表,逐 次对每一段边与裁剪线 (窗口边直线)比较,判 别输入顶点的个数和坐 标,并联结成封闭多边 形。
不可见侧
2
多边形边与裁剪线相对位置的四种
情况与处理方法: (1) 位于可见一侧:输出终点作 为新多边形顶点 (2) 位于不可见一侧:不输出 (3) 由可见到不可见:输出与裁剪
P2
两种线段裁剪算法的比较
Cohen-Sutherland算法是最早的、使用最广泛的线
段裁剪算法之一。在裁剪窗口很大,大部分线段完全
可见,或裁剪窗口很小,大部分线段完全不可见的情 况下,该算法特别有效;在一般情况下,该算法有时 要做不必要的求交运算,因而效率不是太高.

计算机图形学 图形裁剪

计算机图形学 图形裁剪
弃线段还是改变交点的参数.
一 当p<0时,参数r用于更新u0: u0=max u0,rk 二 当p>0时,参数r用于更新u一: u一=min u一,rk 三 如果更新了u0或u一后,使u0>u一,则舍弃该线段 四 当p=0且q<0时,因为线段平行于边界并且位于边界之外,则舍
弃该线段.
四、p、q的四个值经判断后,如果该线段未被舍弃,则裁
16
Cohen-Sutherland裁剪算法
求交
将两个端点的编码CtCbCrCl进行逻辑或操作, 根据其结果中一的位置来确定可能相交的窗口边 求交按照固定的顺序来进行 左右下上或上下右左 一条线段与窗口最多求交四次
A 一0一0 FD
E C B 0一0一
17
Cohen-Sutherland裁剪算法
1001
1000
1010
0001
0000
0010
utherland裁剪算法
先排除简单情形:
若某线段两个端点的四位二进制编码全为0000 线段位于窗口内,显示之
若对两端点的四位二进制编码进行逻辑与运算 & 结果
不为0 线段位于窗口外,直接舍弃
1001
不仅在于求出新的顶点,删去界外顶点,还在于形成 正确的顶点序列
36
多边形的描述方式
多边形可以描述为一组顶点按一定顺序连接而成的 有向点列
一般可将多边形的顶点按逆时针方向顺序形成有向 线段,进而连接成一个环来描述多边形的组成
数据结构上,可用链表结构来描述
2
1
3 4
37
多边形裁剪的特点
多边形的各条边是顺次连接 直线裁剪
10
Cohen-Sutherland裁剪算法

计算机图形学的裁剪算法

计算机图形学的裁剪算法

计算机图形学的裁剪算法
计算机图形学的裁剪算法是图形学的一种重要算法,它的基本思想是将一个完整的几何图形(如线段、多边形、圆圈等)按照指定的裁剪窗口(矩形)进行裁剪,只保留在窗口内的部分,而把窗口外的部分抛弃掉。

由于裁剪算法的应用非常广泛,像图形显示系统、图形设备接口(GDI)和图形处理器(GPU)等都广泛使用裁剪算法。

计算机图形学的裁剪算法可以分为两种:2D裁剪算法和
3D裁剪算法。

2D裁剪算法是基于二维空间的,它将一个几何
图形投影到一个平面上,然后按照指定的窗口裁剪;而3D裁
剪算法是基于三维空间的,它将一个几何图形投影到一个三维空间,然后按照指定的窗口裁剪。

2D裁剪算法的基本步骤如下:首先,将要裁剪的几何图
形投影到平面上;其次,计算出投影后的几何图形以及裁剪窗口之间的交点;最后,将裁剪窗口内的部分保留,而把窗口外的部分抛弃掉。

3D裁剪算法的基本步骤如下:首先,将要裁剪的几何图
形投影到三维空间;其次,计算出投影后的几何图形以及裁剪窗口之间的交点;最后,将裁剪窗口内的部分保留,而把窗口外的部分抛弃掉。

计算机图形学的裁剪算法在图形处理中有着重要的作用,它不仅能够有效减少图形处理时间,而且还可以节约存储空间。

此外,它还可以有效提高图形处理效率,提高图形显示效果。

但是,它也存在着一定的局限性,比如,当几何图形的运动变得复杂时,它就会变得费时费力,这就对性能产生了一定的影响。

总之,计算机图形学的裁剪算法是图形学的重要算法,它的应用非常广泛,在图形处理中有着重要的作用。

虽然它也存在着一定的局限性,但是它仍然是一种有效的图形处理算法。

计算机图形学-NLN线段剪裁算法

计算机图形学-NLN线段剪裁算法

3、点p1的第三种状态
• 点p1在裁剪窗口的左上角区域,这种状态又将p1的位置 分为两种进行讨论,即靠近上边界的和靠近左边界的两 种位置。如图 p1
p1 L2 L2
L1
L3 L4 L4
L3
L1
P1位置判别
kp1a>kab,p1为下图a所示; Kp1a<kab,p1为下图b所示;
如果靠近上边界
• • • • 如果靠近上边界,那么 (1)当k>=k1 && k<=k2时, 当p2在裁剪窗口的内部,求交点 y=YT; x=(y-y1)/(y2-y1)*(x2-x1) ;交点 (x,y),那么点p2与交点的连线就是我们的 裁剪结果 • 当p2在裁剪窗口的外部,此时我们需要求 两个交点 • x0=XR; y0 =(y2-y1)/(x2-x1) *(x0-x1);交 点(x0,y0) • y=YT; x=(y-y1)/(y2-y1)*(x2-x1) ;交点 (x,y),那么两个交点的连线就是我们的裁 剪结果。
2、点p1在裁剪窗口的正左边
L1 L2
p1
p2
L3
L4
• 端点p2的位置有两种选择,在裁剪窗口内部或在裁剪窗口的外 面,利用点p2的编码来判断,即如果codep2==0,那么点p2在 裁剪窗口内部;否则点p2在裁剪窗口外部。???????? • (1)当k>=k2 && k<=k1时, • 当p2在裁剪窗口的内部,求交点 • x=XL;y =k*(x-x1);交点是(x,y),那么点p2与交点的连线就是 的裁剪结果; • 当p2在裁剪窗口的外部,此时我们需要求两个交点 • x0=XL; y0 =k*(x0-x1);交点(x0,y0) • y=YT; x=k*(x2-x1) ;交点(x,y),两个交点的连线就是裁剪结 果。

计算机图形学裁剪算法

计算机图形学裁剪算法

一、实验目标1.了解Cohen-SutherLand线段裁剪算法、Liang-Barsky线段裁剪算法、SutherLand-Hodgeman多边形裁剪算法的基本思想;2.掌握Cohen-SutherLand线段裁剪算法、Liang-Barsky线段裁剪算法、SutherLand-Hodgeman多边形裁剪算法的算法实现;二、实验内容本次实验主要是实现Cohen-SutherLand线段裁剪算法、Liang-Barsky线段裁剪算法、SutherLand-Hodgeman多边形裁剪算法。

Cohen-sutherland线段裁剪算法思想:该算法也称为编码算法,首先对线段的两个端点按所在的区域进行分区编码,根据编码可以迅速地判明全部在窗口内的线段和全部在某边界外侧的线段。

只有不属于这两种情况的线段,才需要求出线段与窗口边界的交点,求出交点后,舍去窗外部分。

对剩余部分,把它作为新的线段看待,又从头开始考虑。

两遍循环之后,就能确定该线段是部分截留下来,还是全部舍弃。

Cohen-sutherland线段裁剪算法步骤:1、分区编码延长裁剪边框将二维平面分成九个区域,每个区域各用一个四位二进制代码标识。

各区代码值如图中所示。

四位二进制代码的编码规则是:(1)第一位置1:区域在左边界外侧(2)第二位置1:区域在右边界外侧(3)第三位置1:区域在下边界外侧(4)第四位置1:区域在上边界外侧裁剪窗口内(包括边界上)的区域,四位二进制代码均为0。

设线段的两个端点为P1(x1,y1)和P2(x2,y2),根据上述规则,可以求出P1和P2所在区域的分区代码C1和C2。

2、判别根据C1和C2的具体值,可以有三种情况:(1)C1=C2=0,表明两端点全在窗口内,因而整个线段也在窗内,应予保留。

(2)C1&C2≠0(两端点代码按位作逻辑乘不为0),即C1和C2至少有某一位同时为1,表明两端点必定处于某一边界的同一外侧,因而整个线段全在窗外,应予舍弃。

计算机图形学实验报告实验2裁剪算法实验

计算机图形学实验报告实验2裁剪算法实验

一、实验目的:直线段的裁剪:编码裁剪算法,中点分割裁剪算法。

二、实验内容://BasicGraph.cpp//请将下列裁剪程序补充完整,并用注释说明是何种裁剪算法void Encode (int x,int y,int *code,int XL,int XR,int YB,int YT) {//请将此程序补充完整int c=0;if(x<XL) c=c|LEFT;else if(x>XR) c=c|RIGHT;if(y<YB) c=c|BOTTOM;else if(y>YT) c=c|TOP;(*code)=c;}//编码裁剪算法:void C_S_Line(POINT &p1,POINT &p2,int XL,int XR,int YB,int YT) {//请将此程序补充完整int x1,x2,y1,y2,x,y,code1,code2,code;x1=p1.x; x2=p2.x; y1=p1.y; y2=p2.y;Encode(x1,y1,&code1,XL,XR,YB,YT);Encode(x2,y2,&code2,XL,XR,YB,YT);while(code1!=0||code2!=0){if((code1&code2)!=0) return;code=code1;if(code1==0) code=code2;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);}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);}if(code==code1){x1=x;y1=y;Encode(x,y,&code1,XL,XR,YB,YT);}else{x2=x;y2=y;Encode(x,y,&code2,XL,XR,YB,YT);}}p1.x=x1;p1.y=y1;p2.x=x2;p2.y=y2;}int IsInArea(POINT point,int XL,int XR,int YB,int YT){//请将此程序补充完整if(point.x>=XL && point.x<=XR && point.y>YB && point.y<YT) return 1;else return 0;}int NotIntersect(POINT begin,POINT end,int XL,int XR,int YB,int YT) {//请将此程序补充完整int maxx,maxy,minx,miny;maxx=(begin.x>end.x)?begin.x:end.x;minx=(begin.x<end.x)?begin.x:end.x;maxy=(begin.y>end.y)?begin.y:end.y;miny=(begin.y<end.y)?begin.y:end.y;if(maxx<XL|| minx>XR||maxy<YB||miny>YT) return 1;else return 0;}//中点裁剪算法:POINT ClipMid(POINT begin,POINT end,int XL,int XR,int YB,int YT){//请将此程序补充完整POINT mid,temp;if(IsInArea(begin,XL,XR,YB,YT)) temp=begin;else if(NotIntersect(begin,end,XL,XR,YB,YT)) temp=begin;else{mid.x=(begin.x+end.x)/2;mid.y=(begin.y+end.y)/2;if(abs(mid.x-end.x)<=1&& abs(mid.y-end.y)<=1) temp=mid;else{if(NotIntersect(begin,mid,XL,XR,YB,YT))temp=ClipMid(mid,end,XL,XR,YB,YT);elsetemp=ClipMid(begin,mid,XL,XR,YB,YT);}}return temp;}//Liang-Barsky直线裁剪算法:void ClipParameter(POINT &p1,POINT &p2,int XL,int XR,int YB,int YT) {float u1=0.0,u2=1.0;float dx=p2.x-p1.x,dy=p2.y-p1.y;if(clipTest(-dx,p1.x-XL,&u1,&u2))if(clipTest(dx,XR-p1.x,&u1,&u2))if(clipTest(-dy,p1.y-YB,&u1,&u2))if(clipTest(dy,YT-p1.y,&u1,&u2)){if(u2<1.0){p2.x=p1.x+u2*dx;p2.y=p1.y+u2*dy;}if(u1>0.0){p1.x=p1.x+u1*dx;p1.y=p1.y+u1*dy;}}}int clipTest(float p,float q,float *u1,float *u2){float r;int remainFlag=1;if(p<0.0){r=q/p;if(r>*u2) remainFlag=0;else if(r>*u1) *u1=r;}else if(p>0.0){r=q/p;if(r<*u1) remainFlag=0;else if(r<*u2) *u2=r;}else //*p=0if(q<0.0) remainFlag=0;return remainFlag;}//逐边裁剪算法://typedef struct tRes { int yes,isIn; POINT pout;} Res;Res TestIntersect(int edge,int type,POINT p1,POINT p2){//判断p2是否在所裁剪的窗边edge的内侧,是否与p1点分别在窗边edge的异侧float dx,dy,m;Res res;int isIn=0,yes=0;POINT pout;dy=p2.y-p1.y;dx=p2.x-p1.x;m=dy/dx;switch(type){case 1: /*right*/if(p2.x<=edge){isIn=1;if(p1.x>edge)yes=1;}else if(p1.x<=edge)yes=1;break;case 2: /*bottom*/if(p2.y>=edge){isIn=1;if(p1.y<edge)yes=1;}else if(p1.y>=edge)yes=1;break;case 3: /*left*/if(p2.x>=edge){isIn=1;if(p1.x<edge)yes=1;}else if(p1.x>=edge)yes=1;break;case 4: /*top*/if(p2.y<=edge){isIn=1;if(p1.y>edge)yes=1;}else if(p1.y<=edge)yes=1;default: break;}if(yes){if((type==1) || (type==3)){ pout.x=edge;pout.y=p1.y+m*(pout.x-p1.x);}if((type==2) || (type==4)){ pout.y=edge;pout.x=p1.x+(pout.y-p1.y)/m;}}res.isIn=isIn;res.yes=yes;res.pout=pout;return res;}int clipSingleEdge(int edge,int type,int nin,POINT pin[50],POINT pout[50])/*对多边形pin与窗边edge进行裁剪,返回裁剪后的多边形pout及点数*/ {int i,k=0;POINT p;Res res;p.x=pin[nin-1].x;p.y=pin[nin-1].y;for(i=0;i<nin;i++){res=TestIntersect(edge,type,p,pin[i]);if(res.yes){ pout[k].x=res.pout.x;pout[k].y=res.pout.y;k++;} if(res.isIn){ pout[k].x=pin[i].x;pout[k].y=pin[i].y;k++;}p.x=pin[i].x;p.y=pin[i].y;}return k;}void ClipEdgePolygon(POINT ps[50],int &n,int XL,int XR,int YB,int YT) { /*对多边形ps进行逐边裁剪*/int n1=0,n2=0;POINT pt[50];n1=clipSingleEdge(XR,1,n,ps,pt);n2=clipSingleEdge(YB,2,n1,pt,ps);n1=clipSingleEdge(XL,3,n2,ps,pt);n2=clipSingleEdge(YT,4,n1,pt,ps);n=n2;}//多边形编码裁剪算法:void ClipEncodePolygon(POINT ps[50],int &n,int XL,int XR,int YB,int YT) {POINT tp[50];int k=0,m;int code1,code2,code;int x,y;for(int i=0;i<n-1;i++){Encode(ps[i].x,ps[i].y,&code1,XL,XR,YB,YT);Encode(ps[i+1].x,ps[i+1].y,&code2,XL,XR,YB,YT);code=code1;m=i;for(int j=0;j<2;j++){if((code1 & code2)!=0) //线段两端都在窗口外的同一侧{switch(code){case 1:x=XL;y=ps[m].y;break;case 2:x=XR;y=ps[m].y;break;case 4:x=ps[m].x;y=YB;break;case 5:x=XL;y=YB;break;case 6:x=XR;y=YB;break;case 8:x=ps[m].x;y=YT;break;case 9:x=XL;y=YT;break;case 10:x=XR;y=YT;break;}tp[k].x=x;tp[k].y=y;k++;}else if((code1 & code2)==0) //线段两端不在窗口的同一侧{if(code==0){tp[k]=ps[m];k++;}else if ((LEFT & code) !=0) //线段与左边界相交 {x=XL;y=ps[i].y+(ps[i+1].y-ps[i].y)*(XL-ps[i].x)/(ps[i+1].x-ps[i].x);if(y>YB && y<YT){tp[k].x=x;tp[k].y=y;k++;}}else if((TOP & code)!=0) //线段与上边界相交{y=YT;x=ps[i].x+(ps[i+1].x-ps[i].x)*(YT-ps[i].y)/(ps[i+1].y-ps[i].y);if(x>XL && x<XR){tp[k].x=x;tp[k].y=y;k++;}}else if((RIGHT & code)!=0) //线段与右边界相交 {x=XR;y=ps[i].y+(ps[i+1].y-ps[i].y)*(XR-ps[i].x)/(ps[i+1].x-ps[i].x);if(y>YB && y<YT){tp[k].x=x;tp[k].y=y;k++;}}else if((BOTTOM & code) != 0) //线段与下边界相交 {y=YB;x=ps[i].x+(ps[i+1].x-ps[i].x)*(YB-ps[i].y)/(ps[i+1].y-ps[i].y);if(x>XL && x<XR){tp[k].x=x;tp[k].y=y;k++;}}}code=code2;m++;}//for(j)}//for(i)for(i=0;i<k;i++)ps[i]=tp[i];n=k;}//函数的调用,裁剪窗口的调整//DrawView.cpp文件//裁剪窗口的调整CDrawView::CDrawView(){/************请在此函数中将裁剪窗口大小调整为长度100单位像素,宽度50单位像素的矩形********/// TODO: add construction code here//m_pWidth=1;m_pStyle=PEN_STYLE_SOLID;m_pColor=RGB(0,0,0);m_FFlag=0;m_FColor=RGB(0,0,0);m_HFlag=0;CurrentDraw=DRAW_VCLINE;m_Num=0;m_Drag=0;m_HCursor=AfxGetApp()->LoadStandardCursor(IDC_CROSS);//DrawType=0;ClipFlag=0;ClipType=-1;XL=200;XR=300;YB=150;YT=200;//XL=200;XR=500;YB=150;YT=400;ClipWindowColor=RGB(192,192,50);}void CDrawView::OnDraw(CDC* pDC){CDrawDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereif(ClipFlag){CPen NewPen,*pOldPen;NewPen.CreatePen(PS_DASH,1,ClipWindowColor);pOldPen=pDC->SelectObject(&NewPen);pDC->MoveTo(XL,YB);pDC->LineTo(XR,YB);pDC->LineTo(XR,YT);pDC->LineTo(XL,YT);pDC->LineTo(XL,YB);}int index;index=pDoc->GetShapeNumber();for(int i=0;i<index;i++)pDoc->GetShape(i)->Drawing(pDC);}void CDrawView::OnInitialUpdate(){CSize sizeTotal;sizeTotal.cx = 640; sizeTotal.cy = 480;SetScrollSizes(MM_TEXT, sizeTotal);// TODO: Add your specialized code here and/or call the base class }void CDrawView::OnLButtonDown(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultCClientDC dc(this);OnPrepareDC(&dc);dc.DPtoLP(&point);m_pPrev=point;m_pOrigin=point; //点击鼠标左键作为拖动绘图的第一点m_Drag=1;SetCapture();RECT rect;GetClientRect(&rect);ClientToScreen(&rect);ClipCursor(&rect);CScrollView::OnLButtonDown(nFlags, point);}//函数调用处void CDrawView::OnLButtonUp(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultif(m_Drag){m_Drag=0;ReleaseCapture();ClipCursor(NULL);CDrawDoc *pDoc=GetDocument();CShape *pShape;POINT p1,p2;if(CurrentDraw==DRAW_VCLINE || CurrentDraw==DRAW_DDALINE ||CurrentDraw==DRAW_MIDLINE || CurrentDraw==DRAW_BSHLINE){if(ClipFlag){switch(ClipType){/****************编码裁剪函数调用处*************/case CLIP_ENCODE:C_S_Line(m_pOrigin,m_pPrev,XL,XR,YB,YT); break; /****************中点分割裁剪函数调用处************/case CLIP_MIDPOINT: ClipMid(m_pPrev,m_pOrigin,XL,XR,YB,YT);p1=ClipMid(m_pPrev,m_pOrigin,XL,XR,YB,YT);p2=ClipMid(m_pOrigin,m_pPrev,XL,XR,YB,YT);m_pOrigin=p1;m_pPrev=p2;break;case CLIP_PARAMETER:ClipParameter(m_pOrigin,m_pPrev,XL,XR,YB,YT);break;}}pShape=newCLine(m_pOrigin,m_pPrev,m_pWidth,m_pStyle,m_pColor,DrawType);pDoc->AddShape(pShape);}if(CurrentDraw==DRAW_RECTANGLE){if(ClipType==CLIP_WINDOW){XL=m_pOrigin.x;XR=m_pPrev.x;YB=m_pOrigin.y;YT=m_pPrev.y;}else{pShape=newCRectangle(m_pOrigin,m_pPrev,m_pWidth,m_pStyle,m_pColor,m_FFlag,m_FColor,m_HFlag,m_Hatch);pDoc->AddShape(pShape);}}if( CurrentDraw==DRAW_VCCIRCLE || CurrentDraw==DRAW_MIDCIRCLE || CurrentDraw==DRAW_BSHCIRCLE){pShape=newCCircle(m_pOrigin,m_pPrev,m_pWidth,m_pStyle,m_pColor,m_FFlag,m_FColor,m_HFlag,m_Hatch,DrawType);pDoc->AddShape(pShape);}if(CurrentDraw==DRAW_VCELLIPSE || CurrentDraw==DRAW_MIDELLIPSE) {pShape=newCEllipse(m_pOrigin,m_pPrev,m_pWidth,m_pStyle,m_pColor,m_FFlag,m_FColor,m_HFlag,m_Hatch,DrawType);pDoc->AddShape(pShape);}pDoc->UpdateAllViews(NULL);}CScrollView::OnLButtonUp(nFlags, point);}三实验结果:四、实验总结通过这次试验使我了解到如何运用计算机程序对窗口进行剪裁,了解到编码剪裁算法直观方便,速度较快,中点分割剪裁算法不用进行乘除运算,剪裁效率高,Liang-Barsky直线裁剪算法更快。

计算机图形学-第三章-变换及裁剪

计算机图形学-第三章-变换及裁剪
xh hx, yh hy, h 0
(x,y)点对应的齐次坐标为三维空间的一条 直线
xh hx
yh
hy
zh h
7
齐次坐标的作用
1. 将各种变换用阶数统一的矩阵来表示。提供了用矩阵 运算把二维、三维甚至高维空间上的一个点从一个坐 标系变换到另一坐标系的有效方法。
2. 便于表示无穷远点。
例如:(x h, y h, h),令h等于0
25
3 规格化设备坐标系 用于用户的图形是定义在用户坐标系里,
而图形的输出定义在设备坐标系里,它依赖于 基体的图形设备。由于不同的图形设备有不同 的设备坐标系,且不同设备间坐标范围也不尽 相同, 例如:分辨率为1024*768的显示器其屏幕坐标的 范围:x方向为0~1023,y方向为0~767,分辨 率为640*480的显示器,其屏幕坐标范围为:x 方向0~639,y方向0~479
y 1),则
1 0 0
P'x' y' 1 x y 1 0 1 0 x
Tx1
Ty1
1
y 1Tt1
经第二次平移变换后的坐标为P*(x* y* 1)
P * x *
y * 1 x'
y'
1
1 0
0 0 1 0
Tx
2
Ty 2
1
1 0 0 1 0 0
x y 1 0 1 0 0 1 0 x y 1 Tt1Tt2
44
关于透视投影
一点透视投影
两点透视投影
三点透视投影
45
内容
二维变换 三维变换 裁剪
二维线裁剪 二维多边形裁剪 文本裁剪 三维裁剪 关于三维变换与裁剪
46
三维变换流程图

计算机图形学5.5裁剪算法

计算机图形学5.5裁剪算法
如何求窗口边界与线段P1P2的交点?
如何判定线段应该与窗口的哪条边求交呢?
编码中对应位为1的窗口边。
计算线段P1(x1,y1)P2(x2,y2)与窗口边界的交点 Code代表线段某个端点的编码。 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);}
P4 (1010)
上下右左 □□□□
P1 (1001)
Y=YT
P3: 0110 P4:& 1010
0010
X=XL
P1: 1001 P2:& 0010
0000
P2 (0010)
X=XR
Y=YB P3 (0110)
对于三维裁剪,需要6位编码。
一旦给定所有的线段端点的区域码,就可以快速 判断哪条直线完全在剪取窗口内,哪条直线完全在 窗口外。所以得到一个规律:
4.求交:假定直线的端点坐标为(x1, y1)和(x2, y2) (1)左、右边界交点的计算:y=y1+k(x-x1); (2)上、下边界交点的计算:x=x1+(y-y1)/k。
Cohen-Sutherland端点编码算法
优点:简单,易于实现。 特点:用编码方法可快速判断线段的完全可见和 显然不可见。

圆形窗口裁剪算法_计算机图形学实用教程(第3版)_[共2页]

圆形窗口裁剪算法_计算机图形学实用教程(第3版)_[共2页]

对于直线和圆不相交和相切两种情况,由于直线在圆内不可能有可见线段,因此,这两种情
况可以不考虑,只考虑直线与圆相交的情况即可。
设线段的方程为
直线的方程为
x y
= =
x1 y1
+ +
( (
x2 y2
− −
x1 )t y1 )t
0≤t ≤1
(5-52)
圆的方程为
x y
= =
x1 y1
+ +
( x2 ( y2
max(x1, x2 ) < xcw − R min(x1, x2 ) > xcw + R max( y1, y2 ) < ycw − R min( y1, y2 ) > ycw + R 步骤 2:计算参数 t 以及判别式 WD。
为计算直线与圆形窗口的交,将式(5-52)代入式(5-54)得
[(x2 − x1)2 + ( y2 − y1)2 ]t 2 + 2[(x1 − xcw ) ⋅ (x2 − x1) + ( y1 − ycw ) ⋅ ( y2 − y1)]t
第 5 章 图形变换与裁剪
5.5.2 圆形窗口裁剪算法
在实际应用中,如工程制图,经常会用到局部放大圆形窗口内图形的问题,因此,本节介绍
圆形窗口的裁剪方法。
将被裁剪的线段的方程代入圆的方程中,可得如下形式的方程。
at2 + bt + c = 0
< 0 ∆ = b2 − 4ac = 0
> 0
直线与圆不相交 直线与圆相切 直线与圆相交
− −
x1 )t y1 )t
−∞≤ t ≤∞
(5-53)

计算机图形学 第五章 裁剪、反走样方法

计算机图形学    第五章 裁剪、反走样方法

中点分割裁剪算法
基本思想:从P0点出发找出离P0最近的可见点,和从P1 点出发找出离P1最近的可见点.这两个可见点的连线 就是原线段的可见部分. 与Cohen-Sutherland算法一样首先对线段端点进行编 码,并把线段与窗口的关系分为三种情况,对前两种 情况,进行一样的处理;对于第三种情况,用中点分 割的方法求出线段与窗口的交点.A,B分别为距P0 , P1最近的可见点,Pm为P0P1中点.
非矩形窗口的线段裁剪
Cyrus-Beck扩充到凸多边形 思考: 凹多边形窗口的线段裁剪 圆和曲线窗口的线段裁剪
多边形裁剪
错觉:直线段裁剪的组合? 错觉 新的问题:1)边界不再封闭,需要用窗口边界的恰
当部分来封闭它,如何确定其边界?
多边形裁剪
2)一个凹多边形可能被裁剪成几个小的多边形,如何 确定这些小多边形的边界?
1
t2 t0 t1
t3
梁友栋-Barsky算法
始边和终边的确定及交点计算:
令 QL= QR= QB= QT= 交点为 Qi <0 Qi >0 Qi =0 - △x △x - △y △y ti= Di / Qi DL= DR= DB= DT= x0-xL xR-x0 y0-yB yT-y0 i=L,R,B,T
参数化算法(Cyrus-Beck)
因此,线段可见的交点参数: tl=max{0,max{ti: Ni (P2-P1) >0}} tu=min <= tu, [tl , tu]是可见线段的交点参数区 间,否则,线段不可见.
参数化算法的几何意义
梁友栋-Barsky算法
线段的参数表示
x=x0+t△x y=y0+t△y △x=x1-x0 0<=t<=1 △y=y1-y0

计算机图形学裁剪算法详解

计算机图形学裁剪算法详解

裁剪算法详解在使用计算机处理图形信息时,计算机内部存储的图形往往比较大,而屏幕显示的只是图的一部分。

因此需要确定图形中哪些部分落在显示区之内,哪些落在显示区之外,以便只显示落在显示区内的那部分图形。

这个选择过程称为裁剪。

最简单的裁剪方法是把各种图形扫描转换为点之后,再判断各点是否在窗内。

但那样太费时,一般不可取。

这是因为有些图形组成部分全部在窗口外,可以完全排除,不必进行扫描转换。

所以一般采用先裁剪再扫描转换的方法。

(a)裁剪前(b) 裁剪后图1.1 多边形裁剪1直线段裁剪直线段裁剪算法比较简单,但非常重要,是复杂图元裁剪的基础。

因为复杂的曲线可以通过折线段来近似,从而裁剪问题也可以化为直线段的裁剪问题。

常用的线段裁剪方法有三种:Cohen-Sutherland,中点分割算法和梁友栋-barskey算法。

1.1 Cohen-Sutherland裁剪该算法的思想是:对于每条线段P1P2分为三种情况处理。

(1)若P1P2完全在窗口内,则显示该线段P1P2简称“取”之。

(2)若P1P2明显在窗口外,则丢弃该线段,简称“弃”之。

(3)若线段既不满足“取”的条件,也不满足“弃”的条件,则在交点处把线段分为两段。

其中一段完全在窗口外,可弃之。

然后对另一段重复上述处理。

为使计算机能够快速判断一条直线段与窗口属何种关系,采用如下编码方法。

延长窗口的边,将二维平面分成九个区域。

每个区域赋予4位编码CtCbCrCl.其中各位编码的定义如下:图1.2 多边形裁剪区域编码图5.3线段裁剪裁剪一条线段时,先求出P1P2所在的区号code1,code2。

若code1=0,且code2=0,则线段P1P2在窗口内,应取之。

若按位与运算code1&code2≠0,则说明两个端点同在窗口的上方、下方、左方或右方。

可判断线段完全在窗口外,可弃之。

否则,按第三种情况处理。

求出线段与窗口某边的交点,在交点处把线段一分为二,其中必有一段在窗口外,可弃之。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
5.5 裁剪算法
5.1.1 线段裁剪算法
5.1.2 多边形裁剪算法
确定图形中哪些部分落在显示区之内,哪些落在显
示区之外,以便只显示落在显示区内的那部分图形,
这个选择过程称为裁剪。
该显示区被称为裁剪窗口。
5.5.1 线段裁剪算法
点的位置是裁剪中最基本的问题 假设矩形窗口的左下角坐标 为(xL,yB),右上角坐标为 <= x <= xR 否则,P点就在窗口外。

因为在图形学中,多边形被认为是一个封闭的区
域,它把平面分为多边形内和多边形外。
多边形的裁剪
• 对一个多边形的裁剪结果仍要求是多边形,且原来是多边 形内的点也在裁剪后的多边形内。
(c)正确的裁剪结果

一部分窗口的边界可能成为裁剪后的多边形的边界,一个
凹多边形裁剪后可能成为几个多边形。
• 多边形裁剪算法的输出应该是定义裁剪后的多边形边界的
p
S p (2)
可 见 一 侧
p
可 见 一 侧
可 见 一 p 侧
S (1)
S (3)
S (4)
取点P 否 是否第一点? 是 F P
Sutherland-Hodgman算法的框图
是 SP和e相交? e的交点I 否 (a) 计算SP和 输出I
S
P
设封闭多边形的顶点为 P1,P2,…Pn,框图中e是表示窗口 的四条边中正在裁剪的一条边, 每次裁剪时第一个点存放在F中, 以便对最后一条边裁剪时使用。 用图(a)中的算法对边P1P2, P2P3, …Pn-1Pn作裁剪。
(xR,yT ) P
(xL,yB )
和 yB <= y <= yT
5.5.1 线段裁剪算法
直线段裁剪算法是复杂图形裁剪的基础。复
杂的曲线可以通过折线段来近似,从而裁剪问
题也可以化为直线段的裁剪问题。
常用的线段裁剪方法
Cohen-Sutherland、
中点分割算法、
梁友栋-barskey算法。
Sutherland-Hodgman基本 思想
基本思想:是一次用窗口的一条边裁剪多边形。
考虑窗口的一条边以及延长线构成的裁剪线该线把 平
面分成两个部分:可见一侧;不可见一侧 多边形的各条边的两端点S、P。它们与裁剪线的位 置
关系只有四种:
可 见 一 侧
p
S p (2)
可 见 一 侧
p
可 见 一 侧
是 S在e的可见侧
输出S 否 退出
图(a)
取点F为P 是 SP和e相交? 否 计算SP和 e的交点I
输出I
退出
(b)
图(b)
用图(b)中的算法对最后一条边PnP1作裁剪。裁剪
好一条边便输出一条边。

上述算法仅用一条裁剪边对多边形进行裁剪, 得到一个顶点序列,作为下一条裁剪边处理 过程的输入。
裁剪结果的顶点构成:裁剪边内侧的原 顶点;多边形的边与裁剪边的交点。顺 序连接。
P2
P4
P5
P1 P3
裁剪一条线段时,先求出端点p1和p2的编码code1和code2, 然后 (1)若code1|code2=0,对直线段应简取之。 (2)若code1&code2≠0,对直线段可简弃之。 (3)若上述两条件均不成立。则需求出直线段与窗口边界 的交点。在交点处把线段一分为二,其中必有一段完全在 窗口外,可以弃之。再对另一段重复进行上述处理,直到 该线段完全被舍弃或者找到位于窗口内的一段线段为止。 4.求交:假定直线的端点坐标为(x1, y1)和(x2, y2) (1)左、右边界交点的计算:y=y1+k(x-x1); (2)上、下边界交点的计算:x=x1+(y-y1)/k。
P1’’
例题:
P’’’1
P2
P1 ’
P1
(1) 求左边交点,得P’1P2; P’1:(-1,1/2); 编码(0000) 判别知非完全可见,且P’1在窗口内, 因此交换P’1P2得新线段P1P2; P1:(1/2, 3/2);编码 (1000) P2:(-1, 1/2); 编码 (0000)
(2) 求右边交点,得 P’’1(1, 11/6) P2(-1, 1/2); 并编码, 判别之不可见 (3) 求上边交点,得 P’’’1(-1/4, 1) P2(-1, 1/2); 并编码, 两端点编码全部为0, 线段完全可见,程序结束
Cohen-Sutherland端点编码算法
优点:简单,易于实现。 特点:用编码方法可快速判断线段的完全可见和 显然不可见。 如何求窗口边界与线段P1P2的交点?
如何判定线段应该与窗口的哪条边求交呢?
编码中对应位为1的窗口边。 计算线段P1(x1,y1)P2(x2,y2)与窗口边界的交点 Code代表线段某个端点的编码。 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);}
顶点序列。于是,需要构造能产生一个或多个封闭区域的多 边形裁剪算法。
5.1 .2 Sutherland-Hodgman逐次多边形裁剪算法
对多边形裁剪的Sutherland-Hodgman算法是一种 简便的方法,只要对多边形用窗口的四条边依次裁 剪四次,便可得到裁剪后的多边形。
Sutherland-Hodgman算法
点相对于裁剪矩形边界的位置。
线段的端点编码
• 区域码为: 上 下 右 左 X X X X 任何位赋值为1,代表端点落在相应的位置上,否 则该位为0。这一编码的特点是对于窗口的某一条 边外侧的三个区域的四位编码中有一位全为1。
y
1001
yT
1000 0000
1010
0010 0110
xB x
0001
yB
0101
xL
0100
线段的各端点编码?
P4
(1010)
上下右左 □□□□
P1 (1001) Y=YT P2 (0010) X=XL Y=YB X=XR P3 (0110)
P3: 0110 P4:& 1010 0010
P1: 1001 P2:& 0010 0000
对于三维裁剪,需要6位编码。
一旦给定所有的线段端点的区域码,就可以快速 判断哪条直线完全在剪取窗口内,哪条直线完全在 窗口外。所以得到一个规律: 若P1P2完全在窗口内:code1=0,且code2=0,则“取” 若P1P2明显在窗口外:code1&code2≠0,则“弃” 否则,在交点处把线段分为两段。其中一段完全在 窗口外,可弃之。然后对另一段重复上述处理。
可 见 一 侧
p
S (1)
S (3)
S (4)
Sutherland-Hodgman基本思想
假设当前处理的边为SP,顶点S在上一轮中已经 处 理。 对于情况(1)仅输出顶点P; 情况(2)输出0个顶点; 情况(3)输出线段SP与裁剪线的交点I; 情况(4)输出线段SP与裁剪线的交点I和终点P 可
见 一 侧
P1:(-3/2, 1/6);编码 (0001) P2:(1/2, 3/2);编码 (1000)
x=x1+(y-y1)*(x2-x1)/(y2-y1) y=y1+(x-x1)*(y2-y1)/(x2-x1)
多边形的裁剪
多边形的裁剪

对多边形的裁剪不等于把多边形的每一条边进行
裁剪。
(a)裁剪前
(b)直接采用直线段 裁剪的结果
5.5.1.1 Cohen-Sutherland 端点编码算法
它又称为Sutherland-Cohen分割线算法. 它是最早最流行的裁剪算法, 可以扩展为三维裁剪. 1.线段的端点编码 将矩形窗口的四边分别延长后,得到九个区域,每 一个区域都用一个四位二进制数标识,直线的端点
都按其所处区域赋予相应的区域码,用来标识出端
裁剪线段与窗口的关系:
(1) 线段完全可见; (2) 显然不可见; (3) 线段至少有一端点在窗口之 外,但非显然不可见。 b c
a
如何提高裁剪效率?
快速判断情形(1)(2),对于情 形(3),设法减少求交次数和 每次求交时所需的计算量。
线段裁剪有多种算法,但基本思想都是:
(1)线段是否全不在窗口内,是则结束。 (2)线段是否全在窗口内,是则显示该线段, 结束。 (3)计算该线段与窗口边界延长线的交点, 以此将线段分成两部分;丢弃不可见的部分; 对剩下的部分转(2)。
Cohen-Sutherland端点编码算法
(1)若线段P1P2两端点的四位编码均为0,则两端点均在窗口内, 该线段完全可见,显示该线段,算法结束; (2) 若线段P1P2两端点的四位编码按位“与”结果为非0,则 该线段完全不可见,算法结束。 (3)若线段两端点的四位编码按位“与”结果为0, 找到P1P2 在窗口外的一个端点P1(或P2),用窗口相应的边与P1P2的交 点取代该端点P1(或P2), 返回(1)步。 P6
流水线过 程(左上右 下):
亦称逐边裁 剪算法
相关文档
最新文档