计算机图形学笔记 || 多边形填充

一、多边形的扫描转换

多边形分为三种:凸多边形、凹多边形和环;在计算机图形学中,多边形有两种表示方法:顶点表示法和点阵表示法;那么如何判断点在多边形内部还是外部呢?任选一点向右做一条射线,“奇内偶外”;我们将多边形从顶点表示法变换到点阵表示法的过程称为多边形的扫描转换。方法有逐点判断法,扫描线算法,有效边表填充算法,边缘填充算法等,在多边形的几种扫描转换方法中,最主要的填充方法是扫描线算法,最简单的方法是逐点判断法。

  1. 扫描转换算法:确定多边形覆盖的扫描线条数;计算扫描线与多边形边界的交点区间,将该区间内的像素赋予指定的颜色;重复上述步骤。
  2. 对一条扫描线的填充:求交,排序,配对,着色。
  3. 可以从以下方面考虑改进:在处理一条扫描线时,仅对与它相交的多边形的有效边进行求交运算;考虑扫描线的连贯性;考虑多边形的连贯性。

二、有效边表填充算法

1. 基本原理:按照扫描线从小到大的移动顺序,计算当前扫描线与有效边的交点,然后将这些交点按X值递增的顺序进行排序、配对,以确定填充区间,然后用指定颜色设置填充区间内的所有像素。

2. 数据结构:

(1)有效边表(AET):把与当前扫描线相交的边称为有效边,并把它们按与扫描线交点X坐标递增的顺序存放在一个链表中;(2)节点内容(一个节点在数据结构里可用结构来表示)

xy_{max}\frac{1}{k}next

3. 边界像素的处理原则:“下闭上开”、“左闭右开”

4. 有效边:多边形内与当前扫描线相交的边。设有效边的斜率为k,交点为(x_{i}y_{i}),则

x_{i+1}=x_{i}+\frac{1}{k}=x_{i}+\frac{\Delta x}{\Delta y}y_{i+1}=y_{i}+1

5. 有效边表:把有效边按照与扫描线交点 x 坐标递增的顺序放在一个链表中。

6. 边表(Edge Table.ET):用以存放扫描线上多边形各条边出现的信息。(给出新边出现的位置坐标)

注意:水平边的 \frac{1}{k} 为 \infty ,并且水平边本身就是扫描线,在建立边表时可以不予考虑。

x | y_{min}y_{max}\frac{1}{k}next

每做一次新的扫描线时,要对已有的边进行三个处理:

(1)是否被去除掉;

(2)如果不被去除,第二就要对它的数据进行更新,即: x+1/k

(3)判断有没有新边进来,新边在 next 里,可以插入排序插进来。

三、边缘填充算法

边缘填充算法是求出多边形的每条边与扫描线的交点,然后将交点右侧的所有像素颜色全部取为反色。

优点:算法简单;

缺点:对于复杂图形,每一像素可能被访问多次,输入/输出的量比有序边表算法大得多,需要对帧缓冲存储器反复赋值。它的效率受交点右侧像素点的数量影响,右侧像素点越多,需要取反的像素点越多。

如何提高填充效率:可以在多边形的外接矩形范围内进行像素取反;在多边形内添加栅栏,在处理每条边与扫描线的交点时,只将交点与栅栏之间的像素取反,若交点位于栅栏左侧,将交点之右,栅栏之左的所有像素取反,若交点位于栅栏右侧,将栅栏之右,交点之左的所有像素取反。

四、区域填充算法

填充原理:用点阵方法表示的多边形区域,如果其内部像素具有同一种颜色,而边界像素具有另一种颜色,可以使用种子算法进行填充。区域填充要求区域是连通的。种子填充算法是从区域内任一个种子像素位置开始,由内向外将填充色扩散到整个多边形区域的填充过程。

区域填充表示方法:

  1. 内点表示:枚举出区域内的所有像素,内部的所有像素着同一个颜色,边界像素着与内部像素不同的颜色;
  2. 边界表示:枚举出边界上所有的像素,边界上的所有像素着同一颜色,内部像素着与边界像素不同的颜色。

四领接点:对于多边形区域内任意一个种子像素,其左、上、右、下这4个像素称为四领接点;八领接点同理。

四连通域:从多边形区域内任意一个种子像素点出发,通过访问其左、上、右、下这4个领接点可以遍历区域内的所有像素,该多边形区域称为四连通域;八连通域同理。

种子填充算法

根据区域填充表示方法不同,有适合于内点表示区域的填充算法,也有适合于边界表示区域的填充算法。

算法定义:

  • 四领接点填充算法的缺点是不能通过狭窄区域,即不能填充八连通域;
  • 八领接点填充算法既可以填充四连通域,也可以填充八连通域。

算法原理:适合于内点表示区域的填充算法

设G为一内点表示的区域,(x,y)为区域内一点,old_color为G的原色。先置像素(x,y)的颜色为new_color,然后逐步将整个区域G都置为同样的颜色:

(1)栈顶像素出栈;

(2)将出栈像素置为new_color;

(3)按上、下、左、右的顺序检查与出栈像素相领的四个像素,若其中某个像素在边界内且未置成new_color,则把该像素入栈。

优点:算法简单,可以填充有孔区域;

缺点:(1)会将大量像素压入堆栈,有些像素甚至会入栈多次,既降低了算法的效率,也占用了大量的存储空间;(2)递归执行,区域内每一像素都引起一次递归,进/出栈,费时费内存。

改进算法:减少递归次数,提高效率。

解决方法:使用扫描线种子填充算法。

扫描线种子填充算法

目标:减少递归层次。

适用范围:边界表示的四连通区域。

算法思想:在任意不间断区间中只取一个种子像素,填充当前扫描线上的该段区间,然后确定与这一区段相领的上下两条扫描线上位于区域内的区段,并依次把它们保存起来,反复进行这个过程,直到所保存的各区段都填充完毕。

具体步骤:

  1. 初始化:堆栈置空。将种子点入栈。
  2. 出栈:若栈空则结束,否则取栈顶元素,以y作为当前扫描线。
  3. 填充并确定种子点所在区段:从种子点出发,沿当前扫描线向左、右两个方向填充,直到边界,分别标记区段的左、右端点坐标为xl和xr.
  4. 确定新的种子点:在区间【xl,xr】中检查与当前扫描线y上、下相领的两条扫描线上的像素,若存在非边界、未填充的像素,则把每一区间的最右像素作为种子点压入堆栈,返回第二步。

五、多边形扫描转换与区域填充方法比较

联系:都是光栅图形面着色,用于真实感图形显示,可相互转换。

  1. 多边形的扫描转换转化为区域填充:当给定多边形内一点为种子点,并用Bresenham或DDA算法将多边形的边界表示成八连通区域后,则多边形的扫描转换转化为区域填充。
  2. 区域填充转化为多边形的扫描转换:已知给定多边形的顶点。

不同点:

  1. 基本思想:前者是顶点表示转换成点阵表示,后者只改变区域内填充颜色,没有改变表示方法;
  2. 对边界的要求:前者只要求扫描线与多边形边界交点个数为偶数,后者区域封闭,防止递归填充跨界;
  3. 基本条件:前者从边界顶点信息出发,后者是区域内的种子点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值