夏天/isummer

Sun of my life !Talk is cheap, Show me the code! 追风赶月莫停留,平芜尽处是春山~

博客园 首页 新随笔 联系 管理

多边形填充算法之扫描线填充算法

  多边形填充可以是凸多边形、凹多边形、或者是可以是带孔的多边形。扫描线填充算法是一种常用的填充算法。

1. 多边形填充过程一般可以分为四个步骤

  (1)求交:计算扫描线与多边形各边的交点;

  (2)排序:把所有交点按照递增的顺序进行排序;

  (3)交点配对:1与2, 3与4等配对处理,每对代表扫描线与多边形的一个相交的区间;

  (4)区间填充:把这些相交的区间内的像素设置成多边形颜色,填充区间之外的像素设置背景色。

2. 需要解决的问题

  (1)扫描线与多边形相交时,交点的取舍问题;

  (2)多边形边界的像素取舍问题。

3. 问题解决

  

   (1) 扫描线交于多变型的顶点时,根据顶点的对应的两条边的另一个顶点的位置来判断取舍。

  ① 如果另外两个顶点都高于扫描线,则取这个顶点算取2次,即此顶点可以填充,已经作为填充区间;

  ② 如果另外两个顶点都低于扫描线,则这个交点算取0个,即此顶点不进行填充;

  ③ 如果另外两个顶点一个在扫描线之上,另一个在扫描线之下,则这个交点算取1次,需要与另一个交点进行配对组成填充区间。

  (2) 多边形填充区间的边界取舍问题:遵循“左下闭,右上开”的原则,来避免填充区域扩大的问题。

  即落在左下边界的像素进行填充,而落在右上的像素不进行填充,简单解释就是,如果扫描线交点是1和9,则实际填充的区间是[1,9),即不包括x坐标是9的那个点。

  具体实现时,对扫描线取左闭右开。

  由以上两个策略,综合效果是实现“左下闭,右上开”。

4. 填充算法的4个中的问题

  了解几个“连贯性”的概念:

  “边的连贯性”:多边形与扫描线相交的边,在一定的范围内,相交的边保持一定的不变性,也可以理解为,当一条便于当前扫描新相交时,其也可能与下一条扫描线相交;

  “扫描线的连贯性”:扫描线与多边形相交的交点,由于其连贯性,新的交点序列与之前的交点序列(交点的排序)基本保持一致,最多有几个个别的交点的位置需要调整,整体上都是按照交点X值得递增的顺序排列,在程序实现上,可以借助这个特定实现排序效率的提高;

  “扫描区间的连贯性”:对确定好的扫描线的填充区间,即区间内的开始点X值到区间结束X值,同一区间上的像素填充颜色相同。可以直接绘制一条区间内的填充色的线段,提高渲染效率。

 (1)求扫描线与多边形的求交运算问题,如果扫描线分别对所有的边进行求交判定,这样处理效率非常低,其中大量的判定计算都是徒劳的;

  为了提高求交运算的效率,设定“AET活性边界表”。

  “AET活性边表”:把于扫描线相交的边称为活性边,并把他们按照与扫描线交点的X坐标递增的顺序放在一个链表中,这样的链表称为“AET(Active Edge Table)活性边表”。

  活性编标的

 

 (2)

5. 算法步骤

 1 算法过程:
 2 void polyfill (polygon, color)
 3 int color;多边形 polygon;
 4 {
 5 for (各条扫描线i )
 6 {    初始化新边表头指针NET [i];
 7     把y min = i 的边放进边表NET [i];
 8      }
 9    y = 最低扫描线号;
10      初始化活性边表AET为空;
11   for (各条扫描线i )
12     {    把新边表NET[i]中的边结点用插入排序法插入AET表,使之按x坐标递增顺序排列;
13          遍历AET表,把配对交点区间(左闭右开)上的象素(x, y),
14       用drawpixel (x, y, color) 改写象素颜色值;
15          遍历AET表,把ymax= i 的结点从AET表中删除,并把ymax > i结点的x值递增Dx;
16          若允许多边形的边自相交,则用冒泡排序法对AET表重新排序;
17     }
18 } /* polyfill */

   注意问题

  (1)初始化新边表数组时,各个数据项中的节点按照X递增的顺序排列;

  ()

  ()把判定如有新的表插入时,则将新的列表中的节点,通过“插入排序”进行插入操作;

  ()

 

 

 

  由以上

posted on 2015-12-17 10:40  夏天/isummer  阅读(11901)  评论(0编辑  收藏  举报