多边形的扫描转换(X-扫描线算法)
一、两种表示方法
把多边形的顶点表示转换为点阵表示称为多边形的扫描转换。
二、X-扫描线算法
图1 图2
1.步骤
a. 求交
b. 排序:把所有交点按递增顺序排序
为何要进行排序?
答:扫描线的交点并非直观获得,而是从边表中按顺序取出边得交点,即P1P2,P2P3,P3P4,P4P5。若为图1,则边的交点顺序和递增顺序相同,不用排序。但是若为图2,此时P2P3,P3P4的交点顺序与x递增顺序相反,则需要排序。
c. 交点配对:确定填充区间
d. 区间填色
2.交点取舍(当扫描线与多边形顶点相交时,交点如何取舍?)
两边只取1,同边0或2。
三、X-扫描线算法的改进
1. 三方面的改进
a. 处理一条扫描线,仅对与它相交的多边形的边(有效边)进行求交运算。(也就是避免把所有的边都进行求交,因为大部分的边求交结果为空。所以设置一个表来记录有效边。即下面提到的AET)
b. 考虑边的连贯性:当前扫描线与各边的交点顺序与下一条扫描线与各边的交点顺序很可能相同或非常相似。
c. 多边形的连贯性:当某条边与当前扫描线相交时,它很可能也与下一条扫描线相交。
2.数据结构
通过引入新的数据结构来避免求交运算
(1)活性边表
a. 活性边表(AET):把和当前扫描线相交的边称为活性边,并把它们按交点x坐标递增的顺序存于一个链表中。
b. 结点内容
Δx=1/k,ymax 是为了知道何时达到边界
c. 举例
(2)新边表(NET)
建立AET需要知道与哪些边相交,所以定义NET来存储边的信息,从而方便AET的建立。
a. 构造一个纵向链表,长度为多边形占有的最大扫描线数。每个节点(称为吊桶)对应多边形覆盖的一条扫描线。
b. 结点内容
ymax:该边的y最大值
xmin:该边较低点的x坐标
c. NET挂在与该边较低端y值相同的扫描线吊桶中
此时NET也就记录了6条有效边
(3)NET与AET的使用流程
首先我们得明白,AET的目的是为了使用增量方法避免求交运算,而NET是用在构造AET的。
a. 所以第一步为构造NET。
方法:遍历所有扫描线,把ymin = i 的边放进NET[ i ]中,从而构造出整个NET。
b. 然后构造AET。
方法:循环取出扫描线,直接将此扫描线在NET中的边结点插入到AET中。此时AET就存储了哪些边是有效边了。
注意:我们来回看2个表里的结点可发现,NET里的1/k、xmin、ymax正好对应AET里的Δx、x、ymax。这也是能用NET构造AET的原因。
c. 区间填色。
方法:取第一条扫描线,在配对点区间中填色。当扫描线达到ymax时,舍弃此边结点。否则使用增量方法得到下一个配对结点的x坐标。取下一条扫描线,重复c操作。
那么到底是如何实现避免求交的?
答:第一个交点的x坐标是NET中传到AET的,也就是最低端的点,此点先渲染。然后根据两条边的斜率来进行增量方法得到下一对配对交点的x坐标,取下一条扫描线时,
根据x坐标和扫描线y值可得交点的具体坐标,从而用增量方法代替了求交运算。要注意的是:只要扫描线<ymax,那么它对应的NET都是相同的,因为NET挂在与该边较低
端y值相同的扫描线吊桶中。
伪代码: