第五讲_区域填充

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
对多边形进行填充,关键是找出多边形内的像素。即首要问 题是判断一个像素是在多边形内还是多边形外。
8 7 P 1 6 5 4 3 2 1 0 1 A P6 B
P2
多边形内点的判别准则

P3 P5 C D

按照扫描线顺序进行扫描,由 于多边形是封闭的,扫描线与 多边形的交点成对出现(如扫 描线 y=3,y=7 )。成对出现的 交点之间的点属于多边形内点。 奇异点的处理
表1 中的数据表明,改进算法的平均填充时间、最小填充时间、最 大填充时间都要明显好于原始算法,算法改进取得了预想的效果
与原始算法相比,这是一种动态发现活性边的机制。算法经过这样改进 之后,取得了以下几点显著效果: (1)无需对多边形进行预处理以建立活性边邻近表,从而节省了计算 时间和存储活性边的空间。 (2)不必在每一条扫描线处都检查上一条扫描线的活性边数组,省去 了大量的判断和处理过程,整个填充过程变得更加流畅。 (3)经过排序后,在上下两个多边形顶点之间,由于不存在活性边结 点,避免了原始算法中多活性边结点的冗余判断,进一步提高了算法 效率。
那么该如何正确地填充自相交的多边形,原始算法并不针对自相交 多边形,对这部分内容,文献中也很少有介绍。基于此,本文提出一种 简单有效的多边形自相交点探测方法,以实现对自相交多边形的正确填 充。自相交多边形是指不共端点的边存在相交情形的多边形,边的交点 即为多边形的自相交点。正确填充自相交多边形,其关键在于能准确发 现自相交点。一种简单的方法是对多边形边进行两两求交,其时间复杂 度为O(n2) ,涉及到边的相交检测和交点计算,过程麻烦。本文提出一 种新的方法,如图2,在自相交处之前,点A 在点B 的前面,而在自相 交之后,点A′ 在点B′ 的后面,因此,只需在自相交处交换两个活性 边结点的前后顺序即可,这样在扫描线填充时就能正确完成交点配对, 实现对自相交多边形的正确填充。理论上讲,在自相交处,两条多边形 边的X 坐标应该相等,但由于计算机存储数据时舍入误差的存在,交点 通过X 值相等或X 值之差的绝对值小于某一误差限的方法很难以被探测。 此时,将方案调整如下:扫描过程中处理活性边结点时,比较当前结点 的X 坐标与前面结点的X 坐标,如果小于或等于前面结点的X 坐标值, 则表明当前处在自相交点或刚刚经过自相交点,这时交换这两个结点的 前后位置即可。
P3 P5 C D
P4
2 3 4 5 6 7 8 9
#define MAX 100 Typedef struct { int PolygonNum; // 多边形顶点个数 Point vertexces[MAX] //多边形顶点数组 } Polygon // 多边形结构 void FillPolygonPbyP(Polygon *P,int polygonColor) { int x,y; for(y = ymin;y <= ymax;y++) for(x = xmin;x <= xmax;x++) if(IsInside(P,x,y)) PutPixel(x,y,polygonColor); else PutPixel(x,y,backgroundColor); }/*end of FillPolygonPbyP() */
P4
2 3 4 5 6 7 8 9
当扫描线通过多边形的顶点时上 述准则失效。 存在两种类型的顶点: 局部极值点 ( P2,P4,P5,P6 )看成 两个点 非极值点(P1,P3)看成一个点

多边形P的顶点可分为两类:极值奇点和非极值奇点。如 果 (yi-1 - yi)(yi+1 - yi)≥0 ,则称顶点 Pi 为极值点;否 则称Pi为非极值点。
事实上,传统算法对多边形顶点信息利用不够:根据顶点编号的连续性和多 边形边的邻接关系,不需要事先存储活性边表,活性边总能在扫描线移动到新 的顶点处时被发现。可以对多边形各顶点按逆时针顺序编号,将顶点编号存入 一个数组,并将数组按顶点的Y 坐标升序排列。填充时,沿Y 轴自下而上扫描 多边形。开始时活性边表为空,每到一个新的顶点处时,通过多边形顶点编号 及其连续性即可找到邻接该顶点的两条边,如果边的Ymax大于当前扫描线的Y 值,则将该边加入活性边表,保持按X 升序排列;否则,表明该活性边已处理 完毕,将其从活性边表删除。然后求取当前扫描线与各活性边的交点,对交点 进行两两配对,填充配对点之间的区域。扫描线不断上移,直到到达Y 最大值 处的多边形顶点。
因此,区域填充算法的一般步骤如下: 确定那些像素位于填充图元的内部; 确定以什么颜色填充这些像素;

多边形填充
边界由闭合的线段(多边形)组 成,一般由多边形的顶点序列 来表示多边形。
种子填充
边界由边界色给出。
填充条件
多边形的顶点序列(Pi,i=0,1,…,n)、填充色。
多边形内点的判别准则
该算法充分利用多边形的边相关性,使用ET表对多边形的非水 平边进行登记;用AET表的建立和更新来支持填充,大大地减少了求 交点的计算量,有效地提高了填充速度。
一种改进的活性边表区域填充算法
传统的活性边表算法在扫描之前需要先建立关于整个多边形的邻接表以存储 初始活性边,在填充阶段又要对每一条扫描线的前一条扫描线对应的活性边列 表进行判断和处理,过程较为麻烦。当多边形较复杂时,需要较大的空间开销 和时间开销。
Table)
用来对边(除水平边外)进行登记,建立边的记录。边的记录定义为: 第一项:某边的最大y值(ymax)。注意要进行奇异点处理:对于非极值点 应该ymax=ymax-1。 第二项:某边的最小的y对应的x值。 第三项:某边斜率的倒数:1/m。 第四项:指针。用来指向同一条扫描线相交的其它边。如果其它边不存在, 则该项置空。
需要说明的是,在面对较为复杂的多边形自相交情形时,多边形的内 部和外部甚至变得难于确定。本Baidu Nhomakorabea对自相交多边形的内部和外部并不作特 别规定,仍是基于普通多边形内、外部规则进行处理,处理的根据仍是基 于交点配对原理:如果按一定的方向追踪交点,首先遇到的必然是入交点, 然后是出交点,依此类推……入交点和出交点之间的区段就是多边形的内 部区域。这种方法应该是有道理的。如果从足够远的区域靠近多边形,开 始必然位于多边形外部,然后遇到多边形的边界,也就是入交点,然后必 然来到多边形内部(因为多边形边界将其内部和外部分开了);继续移动, 同样首先将遇到边界,也就是出交点,然后必然来到多边形外部(同样是 因为多边形边界将其内部和外部分开)。
第二组实验用于测试算法填充效率。为方便填充自相交多边形,比较与 原始算法的运算效率,将本文正确填充自相交多边形部分的内容也加入 到了原始算法,然后对两者进行效率对比。实验中选取了5 000 个随机 多边形,这些多边形的顶点数量为 10 到 30 ,坐标变化范围为 x , y ∈(100,1 000)。表1是分别调用两个算法对实验多边形各填充10 次的 时间统计结果。本实验中,硬件环境为CPU Intel Pentium P6100,主 频2.0 GHz,内存为2 GB,编译环境为Virtual Studio 2008。
图一 正确填充自相交图形
算法的其他关键过程
(1)活性边的发现与删除原始的活性边表算法基于预先建立的邻接表 来现活性边。改进算法是先建立一个存放多边形顶点编号的数组,依 据顶点编号的连续性在扫描过程中动态发现活性边。
(2)扫描线与活性边交点坐标的计算计算活性边上某Y 值处对应点的X 坐标,容易想到的方法是利用直线方程f (x,y) = 0, 将Y 带入直线 方程求解X 。但由于Y 是按dy = 1 累加的,因此有更简单的方法:只 需要求出dy = 1 对应的dx 即可,则 y′ = y + 1
为检验本文算法,设计了两组实验。 第一组实验用于检测本文算法的填充正确性。实验中选取了一个 四个多边形,分别代表了四种不同的情形。如图3 所示,图(a) 为一个基本的简单多边形;图(b)也为简单多边形,但有多条水 平边,且各水平边所在是扫描线上有很多Y 值相同的点(图中B、 D、G、H,C、E、F,S、R、O、M、J,O、N、L、K 分别处在四条 扫描线上);图(c)为一个自相交多边形,其中,BC、DE,JA、 HI 分别自相交,DE、EF、FG、GH 构成了多次自相交;图(d)中, BC、DE、FG三条边相交于一点。 从填充效果上可以看到,本文算法对上述列举出的各类多边形均 进行了正确填充。
3.for:i=0 to N-1 3.1 找到id=ptID[i]的多边形顶点,将当前扫描线的Y坐标作为当前扫 描线的Y值 3.2 找到与当前顶点相关联的另外两条边,如果边的Ymax大于扫描线 的Y 值,则将该边加入活性边列表,保持结点按X 大小升序排列;否则, 如果该边在活性边列表,则将该边从活性边表删除
x′ = x + dx 其中,dx = 1/k,k 为直线斜率。在计算过程中,及时保存当前x ,则 下一个x 可根据上述公式直接计算。
下面,采用伪代码的形式给出算法的完整描述:
1.定义数组ptID[N],用于存储多边形的N个顶点的序号,并将ptID[]内 的各元素按顶点的Y坐标升序排列
2.建立活性边表,置初始活性边表为空
规定:奇点是极值点时,该点按两个交点计算,否则按一个交点 计算。


奇点的预处理:
8 7 P 1 6 5 4 3 2 1 0 1 A P6 B
P2
多边形填充算法
1、扫描线y=1; 2 、求出该扫描线与多边形的交 点; 3、将所求交点按x坐标从小到大 排列,将交点成对取出,作为 两个端点,并填充两端点内的 像素; 4、扫描线y++; 5、重复步骤2-4,直到y=ymax, 扫描结束。 该算法中每条扫描线都需要对多 边形求交,计算量大,效率低。 没有利用多边形边的相关性
1、根据给定的多边形顶点坐标,建立ET 表。 2、AET表初始化,每个桶置空。
3、for(y=ymin;y<= ymax;y++)
合并当前扫描线y的ET表; 将y桶中每个记录按x项升序排列; {
在当前y值下,将两两记录的x值之间的像素进行填充;
删除y=ymax的边记录; 修改边记录x=x+1/m; }
3.3while(Y<point[id+1].y)
3.3.1 计算当前扫描线与各活性边的交点,按交点出现的先后顺序依 次两两配对,填充配对交点之间的多边形区域。在此过程中,如果发现 后面一个结点的X 值小于或等于前面一个结点的X 值,说明出现了自相 交情形,则交换这两个结点的前后位置 3.3.2Y++4.算法结束

一项:ymax=ymax-1。例如:P3P4边、P3P2边、P4P5边)

建立ET表(注意:在做奇异点处理时,当该边最大y值对应的顶点为非极值点时,边记录的第
建立AET表(AET表的建立过程就是进行填充的过程)
(1)合并ET表(2)x递增排序;(3)实施填充;(4)删除ymax=yj的边; (5)修改边记录xi=xi+1/m;(6)yj+1进入下一轮循环。
基本思想:
利用多边形边的相关性,采用边表和活性边表,减少求交计 算量。
边的相关性:
相邻扫描线上的交点是与多边形的边线相关 的。对同一条边,前一条扫描线 yi 与该边的 交点为xi,而后一条扫描线yi+1=yi+1与该边 的交点则为xi+1=xi+1/m,利用这种相关性 可以省去大量的求交运算。
边表(ET:Edge
区域填充的两种 算法及其改进
周锡峰 宛沪生 郑晓坤
直线和圆都属于线划图(线图元) 区域填充属于面着色(填充图元),二维的面着色体现逼真的视觉效 果,是三维多边形面着色的基础。
表示一个区域的要素为:
边界(闭合区域)+ 填充色(灰度或色彩)
区域填充即给出一个闭合区域的边界,要求对边界范围内的所有像 素单元赋予指定的颜色代码。
活动边表(AET:Active
Edge Table)
ET表建立以后,就可以开始扫描转换了。对不同的扫描线,与 之相交的边线也是不同的,当对某一条扫描线进行扫描转换时,我 们只需要考虑与它相交的那些边线,为此需要建立一个只与当前扫 描线相交的边记录链表,称之为活动边表。
对下图的多边形利用有序边表填充算法进行处理:
相关文档
最新文档