Professional Documents
Culture Documents
5-4 多边形的扫描转换与区域填充
5-4 多边形的扫描转换与区域填充
4 多边形的扫描转换与区域填充
面对一个区域
1
5.4 多边形的扫描转换与区域填充
区域内颜色值的重要性
2
5.4 多边形的扫描转换与区域填充
如何在一个区域的内部填上不同的色彩?
区域的几种表示方法:
3
5.4 多边形的扫描转换与区域填充
如何在一个区域的内部填上不同的色彩?
多边形 区域
多边形区域主要是指顶点表示的区域。
区域通常指以像素点集合表示的区域(边界表示
和内点表示)。
4
5.4 多边形的扫描转换与区域填充
多边形扫描转换与区域填充可以统称区域填充,
就是如何用颜色或图案来填充一个二维区域。
填充主要做两件工作:一是确定需要填充的范
围,二是确定填充的内容。
方法:
扫描线法: x- 扫描线法 - 〉 Y 连贯性算法
边缘填充算法
种子填充算法(区域填充)
5
5.4.1 多边形的扫描转换
对于一个多边形区域
输入:多边形顶点序列 P1(x1,y1) 到 P7(x7,y7)
并不仅需要边界而
输出:最佳逼近这个多边形的像素点集 是需要整个多边形
区域
多边形的扫描转换
顶点表示 点阵表示
6
5.4.1 多边形的扫描转换
顶点表示:用多边形顶点的序列来刻划多边形。直
观、几何意义强、占内存少;不能直接用于面着色。
点阵表示:用位于多边形内的像素的集合来刻划多
边形。失去了许多重要的几何信息;便于运用帧缓
冲存储器表示图形,易于面着色。
7
5.4.1 多边形的扫描转换
多边形的扫描转换:把多边形的顶点表示转换为点
阵表示,也就是从多边形的给定边界出发,求出位
于其内部的各个像素,并给帧缓冲器内的各个对应
元素设置相应的灰度和颜色,通常称这种转换为多
边形的扫描转换或多边形的填充。
两种常用方法:
x- 扫描线算法
y 连贯性算法(改进的有效边表算法)
8
X- 扫描线算法
基本思想:按扫描线 y
12
顺序,计算扫描线与
11
10
9
多边形的相交区间, 8
7
6
再用要求的颜色显示 5
4
3
这些区间的所有像素。 2
1
1 2 3 4 5 6 7 8 9 10 11 12 x
9
X- 扫描线算法
算法步骤:
(1) 确定多边形所占有的最大扫描线数,得到多边形顶点的最小
和最大 y 值( ymin 和 ymax )。
(3) 对一条扫描线填充的过程可分为四个步骤:
①求交。
②排序。
③交点配对。
④区间填充。
10
X- 扫描线算法
算法步骤:
(1) 确定多边形所占有 ymax
的最大扫描线数,
得到多边形顶点的
最小和最大 y 值
( ymin 和 ymax )。
11
X- 扫描线算法
算法步骤:
(1) 确定多边形所占有
的最大扫描线数,
得到多边形顶点的
最小和最大 y 值
( ymin 和 ymax )。
12
X- 扫描线算法
算法步骤:
(3) 对一条扫描线填
充的过程可分为
四个步骤:
①求交。
1
②排序。
③交点配对。
④ 区间填充。
13
X- 扫描线算法
算法步骤:
(3) 对一条扫描线填
充的过程可分为
四个步骤:
①求交。
1
②排序。
③交点配对。
④ 区间填充。
14
X -扫描线算法——取整规则
交点的取整规则:使生成的像素全部位于多边
形之内。(用于直线等图元扫描转换的四舍五
入原则可能导致部分像素位于多边形之外,从
而不可用)。
膨胀
15
X -扫描线算法——取整规则
交点的取整规则:使生成的像素全部位于多边
形之内。(用于直线等图元扫描转换的四舍五
入原则可能导致部分像素位于多边形之外,从
而不可用)。
16
X -扫描线算法——取整规则
规则 1 : X 为小数,即交点落于扫描线上两个相
邻像素之间时:
交点位于左边界之上,向右取整;
交点位于右边界之上,向左取整;
17
X -扫描线算法——取整规则
规则 2 : X 为整数,避免填充扩大化。规定落
在右边边界上的像素不予填充。(具体实现时,只要
对扫描线与多边形的相交区间左闭右开)
图 5.18 取整规则 2
18
X -扫描线算法——个数计算规则
规则 3 :当扫描线
与多边形顶点相交
时,交点的取舍,
保证交点正确配对。
19
X -扫描线算法——个数计算规则
解决方法:
当扫描线与多边形的顶点相交时,
若共享顶点的两条边分别落在扫描线的两边,
交点只算一个;
若共享顶点的两条边在扫描线的同一边,这时
交点作为零个或两个。
20
X -扫描线算法——个数计算规则
实际处理: 0
0
2
1
交点个数 =
0
构成这个顶点的两条边位
于扫描线上方的条数
2 2
21
改进出发点
x- 扫描线法需要进行多次求交、排序运算,效率较低。
改进出发点:
1 )对于某一条扫描线,需要与所有边求交吗?
2 )扫描线和直线在 Y 方向上都有连贯性,那
么交点怎么求?
3 )每次都需要排序吗?
22
改进出发点
1 )对于某一条扫描线,需要与所有边求交吗?
答:只与有效边求交!
有效边 有效边
23
改进出发点
1 )对于某一条扫描线,需要与所有边求交吗?
答:只与有效边求交! Y 连贯性算法
2 )扫描线和直线在 Y 方向上都有连贯性,那
么交点怎么求?
答:增量计算!
3 )每次都需要排序吗?
答:有新边加入时重新排序!
24
改进出发点
1 )对于某一条扫描线,需要与所有边求交吗?
答:只与有效边求交! Y 连贯性算法
2 )扫描线和直线在 Y 方向上都有连贯性,那
么交点怎么求?
答:增量计算!
3 )每次都需要排序吗?
答:有新边加入时重新排序!
25
改进的有效边表算法( Y 连贯性算
法)
有效边( Active Edge ):指与当前扫描线
相交的多边形的边,也称为活性边。
26
如何计算下一条扫描线与边的交点
直线方程: y=kx+b
当前交点坐标: (xi, yi)
下一交点坐标: (xi+1,yi+1)
当 yi+1 = yi +1
xi+1 = xi+1/k x ymax 1/k next
有效边表中需要存放的信息:
x :当前扫描线与边的交点的 x 坐标
1/k(Δx) :从当前扫描线到下一条扫描线之间的 x 增量 1/k
ymax :有效边所交的最高扫描线
27
数据结构与实现步骤
为了方便有效边表的建立和更新,建立另一个
表 - 新边表 NET ( New Edge Table ) ,存放
在该扫描线第一次出现的边。
表结构 NET 和 AET 中的基本元素为多边形的
边。边的结构由以下四个域组成:
28
数据结构与实现步骤 x ymax 1/k next
29
数据结构与实现步骤
AET 有效边表
X: 边与扫描线的交点的 x 坐标
NET 新边表
X: 边的下端点的 x 坐标
30
实例
31
实例
32
实例
33
x ymax 1/k next
实例
34
x ymax 1/k next
实例
35
实例
如何体现:当扫描线与多边形顶点相交时,交
点的取舍策略?
交点个数 =
构成这个顶点的两条边
位于扫描线上方的条数
36
x ymax 1/k next
实例
37
x ymax 1/k next
实例
38
x ymax 1/k next
实例
39
x ymax 1/k next
实例
40
x ymax 1/k next
实例
41
x ymax 1/k next
实例
43
x ymax 1/k next
实例
44
算法分析
优点:
采用增量计算的方法进行交点计算。
仅仅在新边加入时排序。
缺点:
桶表、链表的维护开销大。
45
习题
如图所示多边形,若采用改进的有效边表算法 (Y 连贯
性算法 ) 进行填充,试写出该多边形的新边表( NET
表)和有效边表 (AET 表 ) 。
46
5.4.2 边缘填充法
输入:多边形顶点序列 P1(x1,y1) 到
P7(x7,y7)
输出:最佳逼近这个多边形的像素点集
逐边向右取补
47
5.4.2 边缘填充法
边缘填充
48
5.4.2 边缘填充法
算法过程:对于每一条扫描线和每条多边形
边的交点( x1,y1 ) , 将该扫描线上交点右
方的所有像素取补,对多边形的每条边做同
样处理,多边形顺序随意 .
算法简单,但对于复杂图型,每一像素可能
被访问多次。
49
改进 1- 栅栏填充算法
为了减少重复计算,可采用栅栏填充算法,栅栏指的是一条
过多边形顶点且与扫描线垂直的直线。它把多边形分为两半。
对于每个扫描线与多边形的交
点,将交点与栅栏之间的像素
取补,若交点位于栅栏左边,
则将交点之右,栅栏之左的所
有像素取补,若交点位于栅栏
右边,则将栅栏之右,交点之
左的像素取补。
50
改进 1- 栅栏填充算法
51
改进 2- 边标志算法
改进:先画边界后填色
边标志算法
基本思想:
( 1 )用一种特殊的颜色在帧缓冲存储器中将多边形的
边界勾画出来;
( 2 )将着色的像素点依 x 坐标递增的顺序两两配对;
( 3 )将每一对像素所构成的扫描线区间内的所有像素
置为填充色。
52
改进 2- 边标志算法
分为两个步骤:
(1) 打标记 下闭上开
(2) 填充
Inside
初值:假
遇到标记点:取反
真:填充;
假:不填充
53
改进 2- 边标志算法
分为两个步骤:
(1) 打标记
(2) 填充
左闭右开
Inside
初值:假
遇到标记点:取反
真:填充;
假:不填充
54
改进 2- 边标志算法
分为两个步骤:
(1) 打标记
(2) 填充
Inside
初值:假
遇到标记点:取反
真:填充;
假:不填充
55
边标志算法分析
边标志算法对每个象素仅访问一次:
与边缘填充算法和栅栏填充算法相比,避免了对帧
缓存中大量元素的多次赋值,但仍然需逐条扫
描线地对帧缓存中的元素进行搜索和比较。
56
5.4.3 区域填充算法
区域指已经表示成点阵形式的填充图形,它
是像素的集合。
区域填充指先将区域的一点(种子点)赋予
指定的颜色,然后将该颜色扩展到整个区域
的过程。区域填充算法要求区域是连通的。
57
区域填充
表示方法:边界表示、内点表示
边界表示 (边界填充算法)
枚举出边界上所有的像素
边界上的所有像素着同一颜色
非边界像素着与边界像素不同的
颜色
内点表示 (泛填充算法)
枚举出区域内部的所有像素
内部的所有像素着同一个颜色
区域外像素着与内部像素不同的颜色
58
区域填充
区域填充要求区域是连通的
连通性: 4 连通、 8 连通
定义: 4- 邻接点 8- 邻接点
P 的 4- 邻接点 P 的 8- 邻接点
59
区域填充
区域填充要求区域是连通的
连通性: 4 连通、 8 连通
4 连通:
8 连通
60
区域填充
4 连通区域与 8 连通
区域的区别
邻接点不同。 4 连
通区域访问 4- 邻接点,
8 连通区域访问 8- 邻
接点, 8- 邻接点中包
含了 4- 邻接点。
边界要求不同。 8
连通区域对边界的要
求更高。
61
(a) 以边界表示的 4- 连通区域 (b) 以内点表示的 4- 连通区域
区域的边界表示和内点表示 62
种子填充算法
区域填充的算法:种子填充算法
4 连通算法
连通性
8 连通算法
边界填充算法(边界
表示的区域)
表示方式
泛填充算法(内点表示的
区域)
63
种子填充算法 -4- 连通边界填充
算法的输入:种子点坐标 (x,y) ,填充色和边界颜色。
栈结构实现 4- 连通边界填充算法的算法步骤为:
1 、种子像素入栈。
2 、当栈非空时重复执行如下三步操作:
(1) 栈顶像素出栈;
(2) 将出栈像素置成填充色;
(3) 按一定顺序检查出栈像素的 4- 邻接点,若其中某
个像素点不是边界色且未置成多边形色,则把该像
素入栈。
64
举例 -4- 连通边界填充
以 s1 为种子, 4
按照左、上、
右、下顺序入
3 7 8
栈出栈,过程 2 9 6 S1 4
如下:
1 5 2 3
0 1 2 3 4 5
65
S1 2 3 4 5 6
S1
3 4
2 5 5 5 6
4
4 4 4 4 4
8 8 8 3 7 8
8 8
S1 6 6 6 6 6 2 9 6 S1 4
1 5 2 3
1 2 3 4 5
S1
0
0 1 2 3 4 5
9 4 8 6
7 8
7 8
9 9 9
4 4 4 4
8 8 8 8 8 4,8,6 像素
6 6 6 6 6 6 多次入栈
9 10 11
6 7 8 66
种子填充算法 - 4- 连通边界填充
void BoundaryFill4(int x,int y,int boundaryColor,int newColor)
{ int color;
color = GetPixel(x,y);
if((color != boundaryColor) && (color != newColor))
{ PutPixel(x,y,newColor);
BoundaryFill4(x,y+1,oldColor,newColor);
BoundaryFill4(x,y-1,oldColor,newColor);
BoundaryFill4(x-1,y,oldColor,newColor);
BoundaryFill4(x+1,y,oldColor,newColor);
}
}/*end of BoundaryFill4() */
67
种子填充算法 -8- 连通边界填充
栈结构实现 8- 连通边界填充算法的算法步骤为:
种子像素入栈;当栈非空时重复执行如下三步操作:
(1) 栈顶像素出栈;
(2) 将出栈像素置成填充色;
68
种子填充算法 -4- 连通泛填充算法
适合于内点表示区域的填充算法 .
设 G 为一内点表示的区域, (x,y) 为区域内一
点, old_color 为 G 的原色。现取 (x,y) 为种子点对区
域 G 进行填充:即先置像素 (x,y) 的颜色为 new_color ,
然后逐步将整个区域 G 都置为同样的颜色。 步骤如下:
种子像素入栈,当栈非空时,执行如下三步操作:
( 1 )栈顶像素出栈;
( 2 )将出栈像素置成填充色;
( 3 )按左、上、右、下的顺序检查与出栈像素相邻的
四个像素,若其中某个像素是给定内部点的颜色且未置
成新的填充色,则把该像素入栈。
69
种子填充算法 - 4- 连通泛填充算法
递归算法可实现如下:
void FloodFill4(int x,int y,int oldColor,int newColor)
{ if(GetPixel(x,y) == oldColor)
{ PutPixel(x,y,newColor);
FloodFill4(x,y+1,oldColor,newColor);
FloodFill4(x,y-1,oldColor,newColor);
FloodFill4(x-1,y,oldColor,newColor);
FloodFill4(x+1,y,oldColor,newColor);
}
}/*end of FloodFill4() */
70
举例 - 4- 连通泛填充算法
以 s1 为种子, 4
按照左、上、
右、下顺序入
3 7 8
栈出栈,过程 2 9 6 S1 4
如下:
1 5 2 3
0 1 2 3 4 5
71
S1 2 3 4 5 6
S1
3 4
2 5 5 5 6
4 4 4 4 4
7 8
8 8 8 8 8
S1 6 6 6 6 6
9 6 S1 4
1 2 3 4 5
S1
5 2 3
9 4 8 6
7 8
7 8
9 9 9
4 4 4 4
8 8 8 8 8 4,8,6 像素
6 6 6 6 6 6 多次入栈
9 10 11
6 7 8 72
种子填充算法
该算法也可以填充有孔区域。
缺点:
(1) 有些像素会入栈多次,降低算法效率;栈结构占空
间。
(2) 递归执行,算法简单,但效率不高,区域内每一象
素都引起一次递归,进 / 出栈,费时费内存。
解决方法
改进算法,减少递归次数,提高效率。
解决方法是用扫描线填充算法。
73
扫描线种子填充算法(四连通)
目标:减少递归层次
以边界表示的 4 连通区域为例
算法思想:在任意不间断区间中只取一个种子像素(不
间断区间指在一条扫描线上一组相邻元素),填充当前
扫描线上的该段区间;然后确定与这一区段相邻的上下
两条扫描线上位于区域内的区段,并依次把它们保存起
来,反复进行这个过程,直到所保存的个区段都填充完
毕。
74
扫描线填充算法
(1) 初始化:堆栈置空。将种子点( x , y )入栈。
(2) 出栈:若栈空则结束。否则取栈顶元素( x , y ),以
y 作为当前扫描线。
(3) 填充并确定种子点所在区段:从种子点( x , y ) 出发,
沿当前扫描线向左、右两个方向填充,直到边界。分别标
记区段的左、右端点坐标为 xl 和 xr 。
(4) 并确定新的种子点:在区间 [xl , xr] 中检查与当前扫描
线 y 上、下相邻的两条扫描线上的像素。若存在非边界、
未填充的像素,则把每一区间的最右像素作为种子点压入
堆栈,返回第( 2 )步。
优点:上述算法对于每一个待填充区段,只需压栈一次,
因此,扫描线填充算法提高了区域填充的效率。
75
扫描线算法分析(例 1 分析)
该算法也可以
填充有孔区域。
像素中的序号
标指它所在区
段位于堆栈中
的位置
76
扫描线算法分析(例 1 分析)
77
扫描线算法分析(例 1 分析)
78
扫描线算法分析(例 1 分析)
79
5.4.4 多边形扫描转换与区域填充方法比
较
联系:都是光栅图形面着色,用于真实感图形显示,
可相互转换。
多边形的扫描转换转化为区域填充问题:当给定多
边形内一点为种子点,并用 Bresenham 或 DDA 算
法将多边形的边界表示成八连通区域后,则多边形
的扫描转换转化为区域填充。
区域填充转化为多边形的扫描转换;若已知给定多
边形的顶点,则区域填充转化为多边形的扫描转换。
80
多边形扫描转换与区域填充方法比较
不同点:
1. 基本思想不同;前者是顶点表示转换成点阵表示,
后者只改变区域内填充颜色,没有改变表示方法。
2. 对边界的要求不同
前者 : 只要求扫描线与多边形边界交点个数为偶数
后者:区域封闭,防止递归填充跨界。
3. 基本的条件不同
前者:从边界顶点信息出发。
后者:区域内种子点。
81
多边形扫描转换与区域填充
边界
S451
23
82