计算机图形学 第5章 裁剪
计算机图形学-图形变换与裁剪-二维线段裁剪
❖ 顺序连接。 几点说明: 裁剪算法采用流水线方式,适合硬件实现。 可推广到任意凸多边形裁剪窗口
32
Sutherland-Hodgman算法-4/4
存在的问题
❖ 逐边裁剪要求裁剪窗口为凸多边形,那么凹多边形窗口怎么办?
❖ 逐边裁剪法对凹多边形裁剪时,裁剪后分裂为几个多边形, 这几个多边形沿边框产生多余的线段?
裁剪算法的线段可见性测试方法,直至找到每段线段与窗口边界线的 交点或分割子段的长度充分小可视为一点为止
❖ 取中点Pm=(P1+P2)/2。
P2
P2
P1
从P1点出发找距P1最近的可见点
Pm
P1
用P1Pm代替P1P2
P2 Pm
P1
用PmP2代替P1P2
18
1.直线段裁剪(13/18) 中点分割法
❖ 优点:
裁剪结果区域的边界由两部分构成:
1. SP的部分边界
2. CP的部分边界
且在交点处,边界发生交替
即由SP边界转至CP边界
或由CP边界转至SP边界
36
Weiler-Atherton算法-4/7
如果SP与CP有交点,则交点成对出现,
它们被分为如下两类:
❖进点:SP边界由此进入CP
如,I1,I3, I5, I7, I9, I11
当前裁剪边
当前裁剪边
当前裁剪边
当前裁剪边
可见一侧 Pi+1
可见一侧
可见一侧
可见一侧
Pi
Pi+1
Pi I
Pi
Pi+1
Pi+1
Pi
I
窗口
(a) 输出Pi+1
chapt 6-1 裁剪——计算机图形学课件PPT
code1&code2≠0,对直线段可简弃之,转(7);当上述两条均 不满足时,进行步骤(4)。 (4)确编保码p。1在窗口外部:若p1在窗口内,则交换p1和p2的坐标值和 (5)按左、右、上、下的顺序求出直线段与窗口边界的交点,并 用分可以该为去交二掉点,p的并1s坐去。标掉转值p(21s)替。这换一p段1的。坐考标虑值到。p也1是即窗在口交外点的s一处点把线,段因一此 (6)用直线扫描转换算法画出当前的直线段p1p2。 (7)算法结束。
延长线与窗口矩形边界的交点
A
实交点
实交点 H
I 虚交点
G
F
窗口
虚交点 JD
实交点
E
B
虚交点
C
图6-25 实交点与虚交点
计算机图形学
1. Cohen-Sutherland算法
基本思想:对每条直线段p1(x1,y1)p2(x2,y2)分三种情况处理: (1) 直线段完全可见,“简取”之。 (2) 直线段完全不可见,“简弃”之。 (3) 直线段既不满足“简取”的条件,也不满足“简弃”
计算机图形学
5.2 二维裁剪
• 在二维观察中,需要在观察坐标系下对窗口进行裁剪,即只保留 窗口内的那部分图形,去掉窗口外的图形。
• 假设窗口是标准矩形,即边与坐标轴平行的矩形,由上 (y=wyt)、下(y=wyb)、左(x=wxl)、右( 1 点的裁剪 x=wxr)四条边描述。
• 5.2.1 点的裁剪
vxl
vxr X
(b)屏幕坐标系中的视区
计算机图形学裁剪技术
求交测试顺序固定(左右下上) 最坏情形,线段求交四次。
裁剪
直线段裁剪
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)的条件,则在交点处把线段
分为两段。其中一段完全在窗口外,可弃之。然后对另一段 重复上述处理。
如何实现上述的处理呢?
实现方法:采用下面的编码方法
第五章 二维图形的裁剪
5.2.3 Cohen-Sutherland线段裁剪 线段裁剪
它的大概步骤如下所述. 它的大概步骤如下所述. 步骤1 判断线段的两个端点是否都在窗口内,如果是, 步骤 判断线段的两个端点是否都在窗口内,如果是, 则线段完全可见,显示该线段,裁剪结束; 则线段完全可见,显示该线段,裁剪结束;否则进入步 骤2 . 步骤2 判断线段是否为显然不可见,即线段的两个端 判断线段是否为显然不可见, 步骤 点均落在窗口某边所在直线的外侧,如果是, 点均落在窗口某边所在直线的外侧,如果是,删除该线 裁剪结束;否则进入步骤3. 段,裁剪结束;否则进入步骤 . 步骤3 求线段与窗口边所在直线的交点, 步骤 求线段与窗口边所在直线的交点,这个交点将待 裁剪的线段分成两部分,其中一部分显然不可见, 裁剪的线段分成两部分,其中一部分显然不可见,删除 对余下的另一部分线段重复步骤1, ,直至结束. 之;对余下的另一部分线段重复步骤 ,2,直至结束.
(d) 关于窗口右边裁剪
2010-7-21
(e) 关于窗口下边裁剪
16
计算机图形学
5.3.2 Weiler-Atherton算法 算法
在实际应用中,不仅待裁剪多边形是任意的,而且 在实际应用中,不仅待裁剪多边形是任意的, 要求裁剪窗口也需要是任意的,如图5.13所示. 所示. 要求裁剪窗口也需要是任意的,如图 所示
P5 P4 P3
P 1
P2
(a) 待裁剪多边形
(b) 关于窗口左边裁剪
(c) 关于窗口上边裁剪
2010-7-21
计算机图形学
15
5.3.1 Sutherland-Hodgman算法 算法
经窗口的右边裁剪后, 经窗口的右边裁剪后,得到多边形 PPPPPPPP P ,如图 0 1 2 3 4 5 6 7 0 5.12(d)所示;经窗口的下边裁剪后,得到最终的结果多边形 所示; 所示 经窗口的下边裁剪后, P PP P P P P P P ,如图 如图5.12(e)所示. 所示. (e)所示 0 1 2 3 4 5 6 8 0
第五章 裁剪
A
A G 8
1
1 K
G J H I 9 8
H 3 4 5
D
7 6
F
3
D
4 5 7 6
输入:A134D56FGH 输出:A134D5678GH (c)用右边界裁剪
输入:A134D5678GH 输出:K34D56789IHJ (d)用上边界裁剪
3 多边形裁剪算法
只需把被裁剪多边形依次用裁剪窗口 的边来裁剪;
第五章 裁剪( Clipping)
裁剪:确定图形中哪些部分落在显示区之
内,哪些落在显示区之外,以便只显示落在 显示区内的那部分图形。这个选择过程称 为裁剪。 在使用计算机处理图形信息时,计算机内 部存储的图形往往比较大,而屏幕显示的 只是图的一部分。
5.1 线段裁剪
线段裁剪算法是复杂图元裁剪的基础。复杂的曲 线可以通过折线段来近似,从而裁剪问题也可以 化为线段的裁剪问题。 所谓线段裁剪就是把线段位于裁剪区域的部分找 出来,而把位于裁剪区域之外的部分去掉。 最常见的裁剪区域是长方形。
求交: 计算线段P1(x1,y1)P2(x2,y2)与窗口边界的交点
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);}
计算机图形学裁剪算法
一、实验目标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,表明两端点必定处于某一边界的同一外侧,因而整个线段全在窗外,应予舍弃。
计算机图形学实用教程第5章 图形变换与裁剪2
4
三维图形显示的基本问题(3/5)
3. 如何反映遮挡关系?
物体之间或物体的不同部分之间存在相互遮挡关系 遮挡关系是空间位置关系的重要组成部分 解决方法----消除隐藏面与隐藏线
5
三维图形显示的基本问题(4/5)
4. 如何产生真实感图形
何谓真实感图形? 逼真的 示意的 人们观察现实世界产生的真实感来源于
y
0 0 Tw 0 0 0 0 0 cos90 sin 90 1 0 0 sin 90 cos90 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 x L 0 0 0 1 0 0 0 1 0 0 0 1
3
三维图形显示的基本问题(2/5)
2. 如何表示三维物体?
二维形体的表示----直线段,折线,曲线段,多边形区域 二维形体的输入----简单(图形显示设备与形体的维数一致)
三维形体的表示----空间直线段、折线、曲线段、多边形、
曲面片 三维形体的输入、运算、有效性保证----困难 解决方法----各种用于形体表示的理论、模型、方法
10
平面几何投影(4/15)
投影线 从投影中心向物体上各点发出的射线 直线—光线 曲线—喷绘 平面几何投影
投影面是平面
投影线为直线 投影变换
投影过程
投影的数学表示
11
平面几何投影(5/15)
投影分类
投影中心与投影平面之间的距离为有限
投影中心与投影平面之间的距离为无限 是透视投影的极限状态
R yx
1 0 T R yx 0 0
0 1 0 0
0 0 0 0
计算机图形学--第五讲 裁剪的基本概念与直线裁剪
12直线生成算法圆与椭圆的绘制算法5图元的概念436区域填充算法裁剪反走样技术4.5 裁剪—4.5 裁剪—4.5 裁剪—4.5 裁剪—4.5 裁剪—4.5 裁剪—算法实现◆第一步◆第二步4.5 裁剪—编码实现(第一步)九个区域,每一个区域采用四位编码对于任一端点左),赋予一个◆左:若◆右:若◆下:若◆上:若4.5 裁剪—编码实现(第一步)对要被裁剪的线段的两个端点,如果其所在的区域的编码均是如果两个编码的见的,可简弃之;如果两个编码的少一个端点非在交点处把线段一分为二,其中必有一段完全在窗口外,可弃之。
再对另一段重复进行上述处理,直到该线段完全被舍弃或找到位于窗口内的一段线段为止。
4.5 裁剪—析出点。
求出其交点见的,因而只要对上述处理步骤。
y=裁剪结束。
算法步骤界坐标:code2(0100)之,转则交换段与窗口边界的交点除p算法的编码实现到另一端点间的线段重复上述过程直到接受或拒绝;计算线段if(LEFT&codeelse if(RIGHT&codeelse if(BOTTOM&code {y=YB;else if(TOP & code !=0) {y=YT;Cohen-SutherlandNicholl et al. An efficient new algorithm for 2-D line clipping: its4.5 裁剪—4.5 裁剪—4.5 裁剪—(((4.5 裁剪—)界L上;要条件A和该处内法向量P(t)4.5 裁剪—)。
4.5 裁剪—)终点组:N i ⋅(P 2-P 1)<0 起点组:N i ⋅(P 2-P 1)>0 特殊情况:N i ⋅(P 2-P 1)=0这时,,P 1P 2与对应边平行, 这时有两种情况:线段在区域外侧或内侧:前一种情况对应于N i ⋅(P 2-P 1)<0,可直接判断线段在多边形之外前一种情况对应于N i ⋅(P 2-P 1)>0,则不于考虑,继续处理其他边。
第5章 观察变换和裁剪
yB≤y≤yT (4-18) 则,该点在窗内应为可见被显示;否则不可见被裁剪 掉。
23
5.2.2 直线段裁剪
1. 直线段与窗口的相对位置
与凸多边形窗口相交的任何直线段最多只有一 段处于其边界内。 线段与窗口的三种相对位置 关系:完全不可见、完全可见和部分可见。
5
3. 观察坐标系(Viewing Coordinate System) VC是与物理设备无关的,用于设置观察窗口观察 和描述用户感兴趣的区域内部分对象,其取值范围 由用户确定。 观察坐标系采用左手直角坐标系, 可以在用户坐标 系中的任何位置、任何方向定义。其中有一坐标轴 与 观察方向重合同向并与观察平面垂直。
27
四位代码CTCBCRCL 含义如下:
CL=1(端点在XL左); =0(端点在XL右) CR=1(端点在XR右); =0(端点在XR左) CB=1(端点在YB下); =0(端点在YB上) CT=1(端点在YT上); =0(端点在YT下)
28
YT
1001
1000
1010
0001
0000
0100
0010 0110
图形变换到设备坐标系中,并在指定视区内显示的过 程。
在2维空间中的观察变换又称为窗口视区变换。
10
2D观察控制流程:
WC: 定义 2D 对象
WC 到 VC 变换
VC: 窗口 裁剪
VC NDC 窗口 视区 变换
NDC 到 DC 变换
DC: 2D 图形 显示
11
5.1.3
WC到VC的变换
是指将对象描述从世界坐标系变换到观察坐 标系的过程。
计算机图形学基础教程(Visual C++版)第05章 二维图形变换与裁剪(清华大学出版社 孔令德)
y
5-19 设备坐标系
图形学中常用的坐标系
规格化设备坐标系(Normalized Device Coordinate,NDC) 将设备坐标系规格化到(0.0,0.0)到(1.0,1.0)的 范围内而定义的坐标系。 规格化设备坐标系独立于具体输出设备。 一旦图形变换到规格化设备坐标系中,只要作一个简 单的乘法运算即可映射到具体的设备坐标系中。
wyt (xw,yw) 0000 wyb
vyt (xv,yv) 0000 vyb
wxl
wxr
vxl
已知窗口内的一点P的坐标(xw,yw),求视区中 对应点P’的坐标(xv,yv) 这属于相对于任一参考点的二维几何变换
vxr
变换步骤为:
1.将窗口左下角点(wxl,wyb)平移到观察坐标系 原点
写成方程为:
xv S x xw vxl wxl S x yv S y yw vyb wyb S y
则窗视变换的展开式为:
令
xv a x w b yv c y w d
裁剪
图形变换到观察坐标系下,需要按照窗口进行 裁剪,即只保留窗口内的那部分图形,去掉窗 口外的图形 假设窗口是标准矩形,即边与坐标轴平行的矩 形,由 上(y=wyt)、 下(y=wyb)、 左(x=wxl)、 右(x=wxr) 四条边描述
30
裁剪——点的裁剪
点是构成图形的基本元素 点的裁剪:
wxl x wxr, 且wyb y wyt
把图形全部打散成点进行裁剪?
31
二维直线段的裁剪
直线的裁剪是二维图形裁剪的基础 裁剪的实质是判断直线是否与窗口相交,如相 交则进一步确定位于窗口内的部分
圆形窗口裁剪算法_计算机图形学实用教程(第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)
计算机图形学电子教案c5
1010 0010 0110
0100
对线段的两个端点的区号进行“位与”运算,可知这两个端点 是否同在窗口的同一侧(上、下、左、右); 如果两端点的编码均为0000,表示直线在窗口内。 如果两端点的编码相与不为0000,表示直线在窗口外。 如果两端点的编码不全为0000,但相与为0000,则该直线部 分可见,需计算直线段与窗口的交点,确定哪一部分可见。
6
5.1 直线段的裁剪
直线段裁剪:实质上就是快速判 断出线段与裁剪窗口的关系;
(1)线段完全可见; (2)显然不可见;
(3)其它。
然后对于可见部分,求出端点, 绘制线段。
为提高效率:
快速判断情形(1)、(2);
对于情形(3),如果部分可见,应设法快速求出线段和 裁剪窗口的交点。
7
1. 直接求交算法
2. Cohen-SutherLand算法
A C 1001
1000
1010
D
0001 B 0000 0100 0010
0101
0110
任何位赋值为1,代表端点落在相应的位置上, 否则该位为0。 例如:端点B:区域码为 0000;
端点A:区域码为 1001;
11
2. Cohen-SutherLand算法-原理
20
3. 中点分割算法
求距离P0最近可见点P P0 A P0可见?
N P0P1显然不可见? N Pm=(P0+P1)/2 Y P0P1不可见
Y
P=P0
Exit
Pm B P1
可见点一 定落在 P0Pm上
Y P=P m Exit N P =P 1 m
计算机图形学实验五直线段裁剪
计算机图形学实验报告黔南民族师范学院信息与计算科学撰写人姓名: __ 撰写时间:2010年5月5日审查人姓名:实验过程记录一、实验目的:1、通过实验,进一步理解和掌握直线段的裁剪算法;2、通直线段的裁剪。
二、实验内容:要求:•1 、进一步理解并掌握线段的裁剪算法,并可以实践至少一种线段的裁剪算法;•2、注意:本次作业要求学生不能直接使用系统提供的线段裁剪函数,但是可以调用相关的画点、画线函数。
三、实验设备及软件软件需求:windows98以上操作系统、Turbo C 2.0 、Turbo C++3.0、Visual C++软件、Microsoft Word 97或2000。
硬件需求:建议Pentium IV CPU处理器、64MB以上内存、1GB以上硬盘空间的计算机、激光打印机四、实验方法及步骤1 实验准备上该实验课前将针对解决实验内容问题的C语言程序编制好,在实验课上,对编制完的程序进行调试、修改和分析,熟悉TurboC2.0的菜单,以及编译,运行程序和调试程序的方法,并编写程序。
2. 调试程序;程序一:#define LEFT 1#define RIGHT 2#define BOTTOM 4#define TOP 8#define XL 150#define XR 350#define YB 150#define YT 300#include <math.h>#include"graphics.h"main(){ int gdriver=DETECT,gmode;initgraph(&gdriver,&gmode,"c:\\tc");setcolor(12);line(XL,YT,XR,YT);line(XL,YB,XR,YB);line(XL,YT,XL,YB);line(XR,YT,XR,YB);setcolor(9);draw_ett();getch();closegraph();}encode (x,y,code)int x,y;int *code;{ int c;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;return;}draw_ett(){ int x1,x2,y1,y2,x,y;int code1,code2,code;/* printf("XL=150,XR=350,YB=150,YT=300\n");scanf("%d,%d,%d,%d",&x1,&y1,&x2,&y2);*/x1=50;y1=210;x2=300;y2=100;setcolor(2);line(x1,y1,x2,y2);encode(x1,y1,&code1);encode(x2,y2,&code2);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);}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);}if (code==code1){ x1=x;y1=y;encode(x,y,&code1);}else{ x2=x;y2=y;encode(x,y,&code2);}}setcolor(14);line(x1,y1,x2,y2);return;}运行结果:程序二:请按书上P109的Cohen-Sutherland算法写出完整的程序,并运行出效果图,可参考以上程序一#define XL 150#define XR 350#define YB 150#define YT 300#define FALSE 0#define TRUE 1#include <math.h>#include"graphics.h"typedef struct{int xmin,xmax,ymin,ymax;}Rectangle;typedef int boolean;typedef struct{unsigned all;unsigned left,right,top,bottom;}OutCode;void CompOutCode(float x,float y,Rectangle *rect,OutCode *outCode){outCode->all=0;outCode->top=outCode->bottom=0;if(y>(float)rect->ymax){outCode->top=1;outCode->all+=1;}else if(y<(float)rect->ymin){outCode->bottom=1;outCode->all+=1;}outCode->right=outCode->left=0 ; if(x>(float)rect->xmax){outCode->right=1;outCode->all+=1;}else if(x<(float)rect->xmin){outCode->left=1;outCode->all+=1;}}void CSLineClip(float x0,float y0,float x1,float y1,Rectangle *rect){boolean accept,done;OutCode outCode0,outCode1;OutCode *outCodeOut;float x,y;accept=FALSE;done=FALSE;CompOutCode(x0,y0,rect,&outCode0);CompOutCode(x1,y1,rect,&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;elseoutCodeOut=&outCode1;if(outCodeOut->left){y=y0+(y1-y0)*(rect->xmin-x0)/(x1-x0);x=(float)rect->xmin;}else if(outCodeOut->top){x=x0+(x1-x0)*(rect->ymax-y0)/(y1-y0);y=(float)rect->ymax;}else if(outCodeOut->right){y=y0+(y1-y0)*(rect->xmax-x0)/(x1-x0);x=(float)rect->xmax;}else if(outCodeOut->bottom){x=x0+(x1-x0)*(rect->ymin-y0)/(y1-y0);y=(float)rect->ymin;}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){line((int)x0,(int)y0,(int)x1,(int)y1);}}main(){ int gdriver=DETECT,gmode;Rectangle rect;rect.xmin=XL;rect.xmax=XR;rect.ymin=YB;rect.ymax=YT;initgraph(&gdriver,&gmode,"c:\\tc"); setcolor(12);line(XL,YT,XR,YT);line(XL,YB,XR,YB);line(XL,YT,XL,YB);line(XR,YT,XR,YB);setcolor(2);line(100,100,300,400);setcolor(WHITE);CSLineClip(100,100,300,400,&rect);getch();closegraph();}成绩评定:指导教师:。
计算机图形学 第五章 裁剪、反走样方法
中点分割裁剪算法
基本思想:从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
计算机图形学-5
e旳交点I 否
(b)
输出I
退出
图(b)
用图(b)中旳算法对最终一条边PnP1作裁剪。裁 剪好一条边便输出一条边。
上述算法仅用一条裁剪边对多边形进行裁剪, 得到一种顶点序列,作为下一条裁剪边处理 过程旳输入。
裁剪成果旳顶点构成:裁剪边内侧旳原
顶点;多边形旳边与裁剪边旳交点。顺
e旳交点I 否
(a)
输出I SP
设封闭多边形旳顶点为 P1,P2,…Pn,框图中e是表达窗 口旳四条边中正在裁剪旳一条边,
每次裁剪时第一种点存储在F中, 以便对最终一条边裁剪时使用。
用图(a)中旳算法对边P1P2,
P2P3, …Pn-1Pn作裁剪。
是 输出S
S在e旳可见侧 否
退出
图(a)
取点F为P
怎样求窗口边界与线段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
(x w , y w)
yb
yv
Ow Yu
W xl 视图区
W xr
Xw
令பைடு நூலகம்
V yt
(x v , y v)
V yb
有
xv axw c
yv byw d
Ou
V xl
V xr
Xu
窗口与视图区的对应关系
本章内容
5.基本几何变换的齐次坐标表示
平移变换
1 y 1 0 Tx 0 1 Ty 0 0 1
x
比例变换
y 1 x
x
旋转变换
逆时针为正
y 1 x
S x y 1 0 0
0 Sy 0
0 0 1
x
y 1 x
cos sin 0 y 1 sin cos 0 0 1 0
当 S x S y时,变换前的图形与变换后的图形相似 当 S x S y 1时,图形将放大,并远离坐标原点 当 0 S x S y 1 时,图形将缩小,并靠近坐标原点 当 S x S y时,图形将发生畸变
3.旋转变换(rotation) 点P绕原点逆时针转θ度角 (设逆时针旋转方向为正方向)
指相对于原点的比例变换
S x 平行于x轴的方向上的缩放量 S y 平行于y轴的方向上的缩放量
x
y
几何关系
x' x S x y' y S y
y
相对于原点的比例变换
重心
矩阵形式
x
y x
S x y 0
0 Sy
计算机图形学-实验五直线和多边形的裁剪
大学实验报告学院:计算机科学与信息学院专业:软件工程班级:102班** 实验组实验时间指导教师成绩实验工程名称实验五直线和多边形的裁剪实验目的掌握直线段的裁剪算法以及多边形的裁剪算法实验要求熟练掌握直线段的裁剪算法以及多边形的裁剪算法的根本原理,并编写测试代码进展实验。
实验原理Cohen-Sutherland直线剪裁算法以区域编码为根底,将窗口及其周围的,8个方向以4 bit的二进制数进展编码。
右图所示的编码方法将窗口及其邻域分为5个区域:⑴域:区域(0000)。
⑵上域:区域(1001, 1000, 1010)。
⑶下域:区域(0101, 0100, 0110)。
⑷左域:区域(1001, 0001, 0101)。
⑸右域:区域(1010, 0010, 0110)。
当线段的两个端点的编码的逻辑"与〞非零时,线段为显然不可见的,对*线段的两个端点的区号进展位与运算,可知这两个端点是否同在视区的上、下、左、右;Cohen-Sutherland直线剪裁算法的算法思想是:对于每条线段P1P2分为三种情况处理。
〔1〕假设P1P2完全在窗口,则显示该线段P1P2简称"取〞之。
〔2〕假设P1P2明显在窗口外,则丢弃该线段,简称"弃〞之。
〔3〕假设线段既不满足"取〞的条件,也不满足"弃〞的条件,则在交点处把线段分为两段。
其while (code1 != 0 || code2 != 0) {if ((code1 & code2) != 0) {// 两端点的编码相与不为0,表示直线在窗口外return;}if (code1 != 0) {code = code1;} else {code = code2;}if ((LEFT & code) != 0) {// 直线的端点与矩形窗口的左边编码相与!=0* = *L;y = y1 + (y2 - y1) * (*L - *1) / (*2 - *1);// 求直线与矩形窗口的左边界的交点} elseif ((RIGHT & code) != 0) {// 直线的端点与矩形窗口的右边编码相与!=0* = *R;y = y1 + (y2 - y1) * (*R - *1) / (*2 - *1);// 求直线与矩形窗口的右边界的交点} elseif ((BOTTOM & code) != 0) {// 直线的端点与矩形窗口的下边编码相与!=0y = YB;* = *1 + (*2 - *1) * (YB - y1) / (y2 - y1);// 求直线与矩形窗口的下边界的交点} elseif ((TOP & code) != 0) {// 直线的端点与矩形窗口的上边编码相与!=0y = YT;* = *1 + (*2 - *1) * (YT - y1) / (y2 - y1);// 直线的端点与矩形窗口的上// 边编码相与!=0}if (code == code1) {*1 = *;y1 = y;code1 = encode(*, y);} else {*2 = *;y2 = y;code2 = encode(*, y);}}g.drawLine((int) (*1 + 0.5), (int) (y1 + 0.5), (int) (*2 + 0.5),(int) (y2 +0.5));}二、多边形裁剪的核心代码为:通过点集画直线或者多边形:privatevoid draw() {//通过点集画直线或者多边形for (int i = 1; i < points.size(); i++) {Point p1 = new Point();p1 = points.get(i);int *1 = (int) p1.get*();int y1 = (int) p1.getY();Point p2 = new Point();p2 = points.get(i - 1);int *2 = (int) p2.get*();int y2 = (int) p2.getY();g.drawLine(*1, y1, *2, y2);}}多边形的裁剪函数:private Point[] cutPicture(Point[] point, Point[] edge) {// 剪裁函数,参数为〔点集,边〕Point[] intersectPoint = new Point[20];//存放交点的集合for (int j = 0; j < 20; j++) {intersectPoint[j] = new Point();}Point s = new Point();Point p = new Point();Point t = new Point();int i = 0;int length = point.length;s = point[length - 1];for (int j = 0; j < length; j++) {p = point[j];if (inside(p, edge)) {// sp在窗口,情况1if (inside(s, edge)) {intersectPoint[i] = p;i += 1;} else {// s在窗口外,情况4t = intersect(s, p, edge);intersectPoint[i] = t;i += 1;intersectPoint[i] = p;i += 1;}} elseif (inside(s, edge)) {// s在窗口,p在窗口外,情况3t = intersect(s, p, edge);intersectPoint[i] = t;i += 1;}// 情况2没有输出s = p;}List<Point> tempList = new ArrayList<Point>();for (int k = 0; k < i; k++) {if (intersectPoint[k] != null) {Point pt = intersectPoint[k];tempList.add(pt);}}Point[] temp = new Point[tempList.size()];for (int j = 0; j < tempList.size(); j++) {temp[j] = new Point();temp[j] = tempList.get(j);}intersectPoint = temp;return intersectPoint;}判断点是否在裁剪边的可见侧:privateboolean inside(Point point, Point[] edge) {//判断点是否在裁剪边的可见侧// 裁剪边为窗口下边if ((edge[0].y == edge[1].y) && (edge[0].* < edge[1].*)) {if (point.y >= edge[0].y) {returntrue;}}// 裁剪边为窗口上边if ((edge[0].y == edge[1].y) && (edge[0].* > edge[1].*)) {if (point.y <= edge[0].y) {returntrue;}}// 裁剪边为窗口右边if ((edge[0].* == edge[1].*) && (edge[0].y < edge[1].y)) {if (point.* <= edge[0].*) {returntrue;}}// 裁剪边为窗口左边if ((edge[0].* == edge[1].*) && (edge[0].y > edge[1].y)) {if (point.* >= edge[0].*) {returntrue;}}returnfalse;}直线段与窗口边界求交:private Point intersect(Point s, Point p, Point[] edge) {//直线段与窗口边界求交,并返回交点Point t = new Point();if (edge[0].y == edge[1].y) {// 水平裁剪边t.y = edge[0].y;t.* = s.* + (edge[0].y - s.y) * (p.* - s.*) / (p.y - s.y);} elseif (edge[0].* == edge[1].*) {// 垂直裁剪边t.* = edge[0].*;t.y = s.y + (edge[0].* - s.*) * (p.y - s.y) / (p.* - s.*);}return t;}鼠标的监听类〔部类〕:class MouseMonitor e*tends MouseAdapter {//通过鼠标的单击获取点,并画出直线或者多边形publicvoid mouseClicked(MouseEvent e) {points.add(e.getPoint());if (points.size() > 1) {draw();}}}键盘的监听类〔部类〕:class KeyMonitor e*tends KeyAdapter {// 键盘控制publicvoid keyPressed(KeyEvent e) {switch (e.getKeyCode()) {case KeyEvent.VK_R:// 清空画布和点集panel.repaint();points.removeAll(points);break;case KeyEvent.VK_W://对裁剪窗口的处理g.setColor(Color.RED);g.drawRect(*L, YB, *R - *L, YT - YB);//存放裁剪窗口的边top = new Point[2];// 存放裁剪窗口的上边top[0] = new Point(*L, YB);top[1] = new Point(*R, YB);right = new Point[2];//存放裁剪窗口的右边right[0] = new Point(*R, YB);right[1] = new Point(*R, YT);bottom = new Point[2];//存放裁剪窗口的下边bottom[0] = new Point(*R, YT);bottom[1] = new Point(*L, YT);left = new Point[2];//存放裁剪窗口的左边left[0] = new Point(*L, YT);left[1] = new Point(*L, YB);break;case KeyEvent.VK_A://对直线段进展裁剪g.setColor(Color.GREEN);Point p1 = points.get(0);Point p2 = points.get(1);lineCut(p1.get*(), p1.getY(), p2.get*(), p2.getY()); break;case KeyEvent.VK_B://对多边形进展裁剪source = new Point[points.size()];//得到多边形的点for (int i = 0; i < points.size(); i++) {source[i] = points.get(i);}g.setColor(Color.GREEN);wT = cutPicture(source, top);//得到多边形与裁剪窗口上边的交点wR = cutPicture(wT, right);//得到多边形与裁剪窗口右边的交点wB = cutPicture(wR, bottom);//得到多边形与裁剪窗口下边的交点wL = cutPicture(wB, left);//得到多边形与裁剪窗口左边的交点第二种情况:线段在裁剪窗口的部,线段完全可见。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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)所示为止。
图5-12 逐次多边形裁剪
依次考虑多边形每条边的两个端点S、P,其中P是边 的终点,S是边的起点。边SP与裁剪线之间只有4种可 能的关系,且仅对点P进行裁剪,如图5-13所示。
图5-13 边与裁剪线之间的关系
例5.7 裁剪图5-14(a)多边形的过程图
图5-14 裁剪多边形的过程
5.1.8 Weiler-Atherton多边形裁剪算法
设线段端点p的坐标为(x, y),根据编码规则,可求 出其两个端点的编码:
若x < xL,则第1位置1,否则为0;若x > xR,则第2 位置1,否则为0;
若y < yB,则第3位置1,否则为0;若y > yT,则第4 位置1,否则为0。
2.直线裁剪方法
如图5-2所示,根据线段端点的区域编码,很容易对 一条线段的可见性进行测试:
5.1.6 凹多边形的分割算法
假定简单多边形顶点按逆时针方向给定,以单向链表 表示该多边形则算法可描述如下:
(1) 求出多边形顶点中的所有凹点。
(2) 从多边形的任一个顶点出发,沿单向链表搜索到 第1个凹点vi+1。
(3) 从凹点vi+1沿有向边vivi+1作射线,求它与多边形其 余各边的交点,取离vi+1最近的交点p1。
图5-1 二维规则裁剪窗口
点的裁剪十分简单,一个点P(x, y)位于裁 剪窗口之内的条件是: xL≤x≤xR yB≤y≤yT 其中,等号表示点(x, y)位于窗口边界上。
线段的裁剪有多种算法,但算法的基本思想都是基 于以下考虑: (1) 线段是否全不在窗口内,若是,则结束。 (2) 线段是否全在窗口内,若是,则转(4)。 (3) 计算该线段与窗口边界的交点,以此将线段分 成两部分;丢弃不可见的部分,对剩下的部分转(2)。
(4) 保留并显示该线段。
从图5-1中看到,线段ab完全可见,线段ij、kl完全不 可见,线段cd、ef 和gh都是部分可见,其中线段cd 与 窗口只有一个交点,经过一次求交点计算就可确定其 可见部分;而线段gh 和ef则必须经过两次求交计算才 能确定其可见部分。
5.1.1 Cohen-Sutherland端点编码算法
5.1.4 内裁剪与外裁剪
实际上,也可以把直线段相对于窗口外部进行裁 剪,决定线段的哪些部分位于窗口之外,保留并 显示这些位于窗口外面的部分,这样的裁剪是外 裁剪。例如,图5-8中,线段pl p2位于窗口之外的 参数值范围为 0 ≤ t < 3/11 和 9/10 < t ≤ 1 即从点(-2, 1)到(5/11, 17/11)和(61/10, 28/10)到(7, 3)的两段为可见段。
(1) 线段a:两端点编码为全0,是完全可见段; (2) 线段b:两端点编码按位逻辑与不为0,是显 然不可见段。 (3) 线段c:两端点编码按位逻辑与结果为0,用中 点分割法。
图5-6 中点分割
从p2开始,pa=p1,pb=p2,计算中点pm1,pm1pb为显 然不可见段,可抛弃,pm1代替pb;取其中点pm2, pm2pb不是显然不可见段,pm2代替pa;继续分割,直 至在给定精度下可把线段近似为一个点,然后求此 点的编码,可知该点不可见。 再从p1开始,同样得该点不可见,最终线段c为不可 见线段。
图5-7 Cyrus-Beck算法
t = - (ni· i)/(ni· w D), D 0,i = 1, 2,…, k
(5-6)
式(5-6)可用来计算直线段p1p2与窗口R各边交点的t 值。若t值位于[0, 1]之外,则可抛弃。否则把这些t 值分为两组,一组为下限组,它由ni· > 0决定,其t D 值分布于线段起点一侧;一组为上限组,它由ni· < D 0决定,其t值分布于线段终点一侧。然后,求出下 限组的最大t值tL,上限组的最小t值tu,那么,从点 p(tL)到点p(tu)的线段就是所求的可见线段。
5.1.3 凸多边形窗口的Cyrus-Beck线裁剪算法
考虑一个凸多边形裁剪窗口R,被裁剪线段p1p2。如 图5-7所示说明算法的思想方法。
线段plp2的参数方程为:
p(t) = p1 + (p2 - p1) t (0≤t≤1) (5-1)
t为参数,当t < 0或t > 1时,表明点p(t)位于直线段的 两端点之外,可以舍去。
当凸多边形是矩形窗口,且矩形的边平行于坐标轴 时,上述算法可简化为Liang-Barsky算法,如表5-2 所示。
表5-2 Liang-Barsky算法所用的量
边 左边x=xL 右边x=xR 下边y=yB 下边y=yT n (1,0) (-1,0) (0,1) (0,-1) f (xL ,y) (xR ,y) (x ,yB) (x ,yT) W (x1-xL ,y1 – y) (x1-xR ,y1 – y) (x1-x ,y1 –yB) (x1-x ,y1 –yT) t (x1-xL) / -(x2-x1) -(x1-xR)/ (x2-x1) (y1-yB) /-(y2-y1) -(y1-yT) / (y2-y1)
用一个有内孔的凹多边形去裁剪另一个也有内孔的凹 多边形。为了便于讨论,把被裁剪多边形简称为从属 多边形,裁剪窗口称为裁剪多边形。实际上,从属多 边形被裁剪多边形裁剪后所形成的新的边界就是裁剪 多边形边界的一部分,故无须再生成新的边界。
图5-15 从属多边形与裁剪多边形
图5-10 多重窗口裁剪
5.1.5 凸多边形的判定与内法线的确定
1.多边形凹凸性的判定
设多边形由顶点序列v1, v2,…, vn定义,则其边矢量vivi+1(i = 1, 2,…, n - 1)和vnv1,算法可描述如下: 计算多边形相邻两边矢量的叉积:vnv1 × v1v2,vivi+1 × vi+1vi+2(i=1, 2,…, n - 2)以及vn-1vn × vnv1,若各叉积模的符号: (1) 全部为0,则多边形各边共线。 (2) 一部分为正,一部分为负,则多边形为凹。 (3) 全部大于0或等于0,则多边形为凸,并且沿着边的正向, 内法线指向其左侧。 (4) 全部小于0或等于0,则多边形为凸,并且沿着边的正向, 内法线指向其右侧。 此外,也可取多边形的一顶点为基点,依次计算由该顶点至多 边形相邻两个顶点矢量的叉积,其判定规则与上述相同。
第5章 图 形 裁 剪
5.1 二维裁剪 图5-1所示给出了一个规 则裁剪窗口。裁剪窗口是 左(L)、右(R)、上(T)和 下(B)四条边定义的矩形, 左下角和右上角坐标分别 为(xL, yB)和(xR, yT)。图 形裁剪就是确定哪些点、 线段或线段的一部分位于 裁剪窗口之内。位于窗口 内的点、线段或线段的一 部分保留并显示,其他部 分则被裁去。
2.凸多边形边内法矢量的确定 设多边形边矢量ve = (vex vey),该边的法矢量为 n=
vey (nx ny) = - vex 1
n 将凸多边形顶点以顺时针方向编号, 取多边形顶点vi至vi+1,则边为vivi+1,若:
n·ivi+1 > 0,则n为内法矢量; v n·ivi+1 < 0,则n为外法矢量。 v
例5.5 Cyrus-Beck裁剪。 图5-8给出了一个五边形的裁剪窗口,其中V1(2, 0),V2(p1(-2, 1)到p2(7, 3)。
图5-8 凸多边形窗口的线裁剪
表5-1给出了Cyrus-Beck的完整结果。
表5-1 Cyrus-Beck的完整结果
(4) 取pa pb的中点pm,若pmpb为显然不可见段,则让pb = pm,否则让pa = pm。