(9)有序边表填充算法

来源:互联网 发布:淘宝代销宝贝怎么发货 编辑:程序博客网 时间:2024/05/22 06:28

基本思想

对于一个给定的多边形,用一组水平扫描线进行扫描,对每一条扫描线均可求出与多边形的交点,这些交点将扫描线分割成落在多边形内部的区间和落在多边形外部的区间,并且两者相间排序。用要求的颜色显示这些区间的像素,即可完成填充工作。


多边形顶点处的扫描线交点的处理:

情况1:扫描线2与P6相交,若交点算一个,求得交点(x 坐标升序)序列P6 ,E,F。这将导致[P6, E]区间内的像素被填充(而该区间的像素属于多边形外部,不需要填充)。

情况2:扫描线7与P1相交,若交点算两个,求得交点(x坐标升序)序列P1, P1,G。这将导致[P1, G]区间内的像素不被填充(而该区间的像素属于多边形内部,需要填充)。 


处理方法:扫描线交于一个顶点,检查共享该顶点的两条边的另外两个端点的y值。按这两个y值中大于交点y值的个数是0、1、2来决定交点个数是取0个、1个、还是2个。


例如:扫描线1 交顶点P4,共享该顶点的两条边的另外两个端点均高于扫描线,故取交点P4两次。这使得像素P4用多边形颜色填充。而扫描线9 与P2相交时,由于P1和P3均在扫描线9下方,所以交点算0个,该点不予填充。 


活化边与活化边表:
 在处理扫描线与多边形的边进行求交运算时,由于边的连贯性,当一条扫描线
yi与多边形的某条边相交时,其相邻扫描线yi+1可能也与该条边相交(除非扫描线yi+1超出了该边所在区间),并且扫描线yi+1与该边的交点可以从前一条扫描线yi与该边的交点递推求得:
                       
xi+1=xi+ 1/k     (k为边的斜率)

活化边:把与当前扫描线相交的边称为活化边。
  活化边表:把活化边按与扫描线交点x坐标递增的顺序存放在一个链表中,称此链表为活化边表。

活化边表的每个结点的数据结构定义如下:


xjiao:当前扫描线与边的交点的x值;
1/k:从当前扫描线到下一条扫描线之间的x增量(边斜率的倒数);


活化边表的更新包括:
  更新旧边:在处理完当前扫描线后转入下一条扫描线之前,要对交点x坐标(xjiao)进行更新(+1/k);
 插入新边;
 把那些与当前扫描线有交,而与下一条扫描线不再相交的边,从活化边表中删除(通过检查当前扫描线y值是否等于各边的ymax值来确定)。 

有序边表:
 为每条扫描线建立一个有序边表,用于存放在该扫描线第一次出现的边。即若扫描线的y值正好等于某条边的较低端点的y值(ymin),则该边就放在扫描线为ymin的有序边表中。

有序边表中每个结点的数据结构与活化边表中每个结点的数据结构大致相同。其结点的数据结构定义如下:



以边P3P4为例:
该边的有序边表数据为:x0=7,1/k=3/5,ymax=6
该边的活化边表数据为:
当扫描线1时:该边的活化边表数据与有序边表数据相同 
当扫描线2时:xjiao=7+3/5=7.6,1/k=3/5,ymax=6
当扫描线3时:xjiao=7+2×3/5=8.2,1/k=3/5,ymax=6
…………



整个有序边表数据等同于多边形边数据的集合:
Polygon = {P1P2,P2P3,P3P4,P4P5,P5P6,P6P1}


注意:有序边表中的结点也按 x 值升序排序。


有序边表与活化边表的区别:
 有序边表为静态的边表,只要多边形的顶点坐标给定,有序边表便随之确定,它与扫描线的运行状态无关。
 活化边表为动态的边表,它的存在与扫描线的运行状态密切相关,即随扫描线的变化而不断改变。 


交点配对和区间填色:
为使交点正确配对,要使活化边表中的结点按交点的x值升序排序。
为实现区间填色,令指针从活化边表中第一个结点到第二个结点遍历一次,对每个像素进行写操作。然后令指针从活化边表中第三个结点到第四个结点遍历一次,对每个像素进行写操作。如此反复,直至当前扫描线全部填充完毕。


多边形区域的有序边表填充算法步骤:

①输入多边形的顶点个数及其顶点坐标。这里,顶点数为实际顶点数+1,最后一个顶点坐标与第一个顶点坐标相同。

②计算多边形所有顶点坐标中y的最大值和最小值,以此作为扫描线的处理范围。

③对处理范围内的每条扫描线建立有序边表。 

④对处理范围内的每条扫描线,重复下列步骤:

A.用有序边表建立当前扫描线的活化边表;
B.从活化边表中依次取出一对交点,对这两个交点之间的像素进行填色;
C.为下一条扫描线更新活化边表,即增加交点的x值和删除不再相交的边;
D.重排活化边表。

 

1 0
原创粉丝点击