计算机图形学第3讲多边形区域填充算法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
l2
2
4
6
8 10 12 14
10
3/2
5 ∧
23/2 3/2
13 0 0 11 11 9 9 13
5 ∧
∧ ∧
l5
7 3/2 11 17/2 3/2 11
7
8 9 10 11 ∧
l3
7 -5/2 7 -5/2
l4
13
0 11 ∧ 11 ∧
13 0
10 3/2 11 23/2 3/2 11
13 0 11 ∧ 13 0 11 ∧
扫描转换算法
区域填充算法
34
种子填充算法
区域:点阵表示的图形,像素集合 表示方法
内点表示 区域内的所有像素具有同一颜色,而区域外的所有像素具有另 一种颜色 边界表示 区域边界上的所有像素具有特定的颜色(可以是填充色),在 区域内的所有像素均不能具有这一特定颜色,而且边界外的像 素也不能具有与边界相同的颜色
多边形的扫描转换与区域填充
中南大学地球科学与信息物理学院GIS中心
区域的表示方法
区域的表示方法
顶点表示(几何表示)
用区域的顶点序列来表示区域,经过数学计算可知区域是由什 么样的相连直线或曲线构成其轮廓线的 用位于多边形内的像素集合来刻画多边形
点阵表示(像素表示)
2
区域填充的概念
扫描转换(scan conversion)多边形
若低端点y值为ymin,则该边就放在ymin所对应的桶中
桶中的各边:
按下端点的x坐标值排序
27
12 10(2,9) l3 8 6 4 2 l2 l4
(13,11) l5 (13,5) l6
(7,7)
(2,3) (7,1) l1 2 4
9 11 9 3 ∧ ∧
6
8 10 12 14
7 3/2 11
(x3,y3)
(x2,y2)
(x1,y1)
11
扫描线算法
依顺序取出每一条射线,求其与多边形边界的交 点,并对每一对交点中的像素进行填充
射线
a
b
c
d
12
扫描线算法
求交
计算扫描线与多边形各边的交点
排序
A F
把所有交点按x值递增顺序排序
射线1
配对
2
a
3
b c
扫描线算法(改进)
排序 扫描线连贯性 采用插入排序
复杂度为O(n)
22
扫描线算法(改进)
数据结构——加速结构
求交问题
空间换时间
边表(Edge table, ET)
动记录与当前扫描 态表(活性边表,Active 链表形式
Edge table,AET)
23
扫描线算法(改进)
24
扫描线算法(改进)
下一条扫描线的边表(边的连续性)
活性边表(AET)更新
交点的计算——增量算法:
xi 1 xi 1 / k
当扫描线 y = ymax ,说明该扫描线与此边不相交( 上开下闭),将该边从AET中删除 Deltax不变
问题
初始交点如何计算
新边如何得到
25
扫描线算法(改进)
新边表(New Edge Table,NET )
按边的下端点 y 坐标,对非水平边进行分类的链表 每条扫描线(y坐标):
建立它的新边表
作用
避免盲目求交(增量算法的初值) 计算第二类交点坐标
26
扫描线算法(改进)
AET的建立
先按下端点的y坐标值对所有的边进行分组 对每条边:
目标
利用相邻像素之间的连贯性,提高算法效率
处理对象:简单多边形
非自交多边形 (边与边之间除了顶点外无其它交点)
平行于坐标轴的直线 一般取平行于X轴 区间:扫描线与边的交点间的线段
扫描线(Scanning Line)
9
多边形
X
10
扫描线算法
需要找出扫描线上与多边形相交的像素,填充之 约定:至底向上扫描
累计角度法
问题
(xmax, ymax)
P1 P2
(xmin, ymin)
4
射线法
A
P
B
C
A
C
P
B
E
D
E
D
若交点数=偶数(包 括0),则点在多边 形之外
若交点数=奇数,则 点在多边形之内
5
扫描线算法
特点
程序简单 测试点是否在多边形内的算法速度太慢,效率低 逐点判断法孤立考虑各个像素与多边形的内外关系 利用内部点的连贯性(Coherence)
射线4 射线1 a b c d B 1两个交点 C 2两个交点
射线2 射线3
14
扫描线算法
解决方法
F
B
当奇点在多边形两边之下时, 该点计2次,如A、D、H点 当奇点在多边形两边之上时, 该点计0次,如B、F、I点 当奇点在多边形两边中间时, 该点计1次,如C、E、G点
G E
C
A I H D 15
解决方法
17
扫描线算法
填充扩大化问题
若将多边形边界看成是多边形内部,并对它们填充,则 该多边形会被放大 采取“左闭右开,下闭上开”的方法,即将左、下边界 像素视为多边形内部,需填充,而右、上边界则为多边 形外部,不予填充
3
解决方法
2
1 1 2 3 18
扫描线算法
简单(naive)扫描线算法
30
扫描线算法(改进)
优点:
每个像素只访问一次,避免了反复求交点等大量运算 与设备无关 数据结构复杂 只适合软件来实现
缺点
31
扫描转换在GIS上的应用
多边形的矢量-栅格转换
32
扫描转换的边界标志算法
栅格算法
扫描填充算法 阅读
33
扫描转换与区域填充
// 填充
color = GetPixel(px+1, py); if ((color != boundColor) && stackPush(px+1, py); color = GetPixel(px, py+1); if ((color != boundColor) && stackPush(px, py+1); color = GetPixel(px-1, py); if ((color != boundColor) && stackPush(px-1, py); color = GetPixel(px, py-1); if ((color != boundColor) && stackPush(px, py-1); } }
8 7 6 5 4 3 2 1 0
7 ∧
l3
-5/2 0 0 -5/2
l4
∧
13 ∧ ∧ ∧ 2 7
l5 l2
7 3/2 5 ∧
l1
l6
28
扫描线算法(改进)
建立NET; AET为空; for each 扫描线i
NET[i]按x顺序插入AET; 按AET边顺序产生区间; 填充区间; 遍历AET,删除y_max=i的结点,对y_max<i的 结点,令x=x+deltax;
每条扫描线都要求交点
解决:空间连贯性(spatial coherence)
19
扫描线算法(改进)
连贯性(Coherence)
边的连贯性(Edge Coherence) √
某条边与当前扫描线相交,也可能与下一条扫描
线相交 扫描线的连贯性(Scan-line Coherence) √ 当前扫描线与各边的交点顺序与下一条扫描线与 各边的交点顺序可能相同或类似 区间的连贯性(Span Coherence) 同一区间上的像素取同一颜色属性
改进
6
扫描转换与区域填充
暴力算法
不能很好地利用空间连贯性
空间连贯性性(Spatial coherence)
若当前像素在多边形内部时,与其空间临近的像素亦很 有可能在多边形内部
扫描转换 区域填充
7
扫描转换与区域填充
扫描转换算法 区域填充算法
8
扫描转换算法算法
29
扫描线算法(改进)
0 1 2 3 4 5 6
例:活性边表的更新。
∧ 7 -5/2
l1
3 3
7 3/2 5 17/2 3/2
l6
12 (13,11) 10(2,9) l4 l3 l5 8 6 l2 (7,7) (13,5) 4 (2,3) ∧ 2 l1 (7,1) l6
5 ∧
9/2 -5/2 2 2 2 2 2 2 0 0 0 0 0 0 9 9 9 9 9 9
种子填充算法
分类
四向算法
从四个方向寻找下一像素点 有时不能通过狭窄区域,因而不能填满多边形
八向算法
允许从八个方向搜索下一像素点 有时会填出多边形的边界
39
种子填充算法
简单的种子填充算法(四向算法)
void BoundaryFill4(int x, int y, int oldColor, int newColor) { color = GetPixel(x, y); if((color != oldColor) && (color != newColor)) { SetPixel(x, y, newColor); BoundaryFill4(x+1,y,oldColor,newColor); BoundaryFill4(x,y+1,oldColor,newColor); BoundaryFill4(x-1,y,oldColor,newColor); BoundaryFill4(x,y-1,oldColor,newColor); } }
20
扫描线算法(改进)
计算交点 分类
第一类交点:位于同一条边上的后继交点--(P2,
P4 )
第二类交点:新出现的边与扫描线的交点--(P3)
计算: y=e+1的交点
第一类交点:边的连贯性!
P2
P0
P3
P4 P1
x’=x+1/k 增量算法 第二类交点: 线段的下端点即为交点
21
扫描线算法
取整问题
扫描线与多边形边界交点坐标值不为整数 当扫描线与多边形边界交点坐标为小数值时,如果多 边形在此边界右侧,则将该小数值进1作为边界点,否 则舍去小数部分并进行填充,这样可使多边形不扩大
解决方法
16
扫描线算法
水平边问题
扫描线与多边形的水平边相交时,交点理论上是无穷 多个 对于多边形的水平边,不计它与射线的交点
40
种子填充算法
栈实现的种子填充算法(四向算法)
void BoundaryFill4(int x, int y, int boundColor, int newColor) { int px = x, py = y; stackPush(px, py); while(!stackEmpty()) { stackPop(&px, &py); SetPixel(x, y, newColor);
4
d B
1
第1个与第2个,第3个与第4个等, 每对交点代表一个相交区间 把相交区间内:多边形颜色 相交区间外:背景色
C
填色
E D 13
扫描线算法
奇点取舍问题
当射线与多边形顶点相交时,称该交点为奇点。如果 A 奇点的计数不正确,会导致填充错误
• 射线4与多边形相交时,有一 个奇点。如果奇点计数为奇 数个,则总共得到3个交点, 此时多边形会将区域外部填 充,而区域内部不予填充, 出现错误。 • 射线2与多边形相交时,有一 个奇点。如果奇点计数依照 上述计为偶数个,则总共得 到3个交点,仍然会造成错误 填充。
表示内点
表示边界点
35
种子填充算法
基本思想:假设在多边形区域内部至少有一个像素 是已知的(此像素称为种子像素),由此出发找到 区域内所有其他像素,并对其进行填充 空间连贯性 种子填充算法要求区域是连通的
36
种子填充算法
4连通区域:区域中任意两点可通过上下左右
四个方向互相到达
8连通区域:区域中任意两点可通过上下左右
将多边形顶点表示形式转换成点阵表示形式
区域填充( region fill )要求对此区域范围内的所 有像素赋予指定的颜色代码
确定哪些像素位于填充区域的内部 用指定颜色绘制这些像素
3
逐点判断法(暴力)
基本原理
判断绘图窗口内的像素是否位于多边形内,若是,则 用指定颜色绘制该像素 如何判断点在多边形的内外关系? 射线法
和对角线八个方向互相到达
37
种子填充算法
百度文库
4连通与8连通区域的区别
连通性: 4连通可看作8连通区域,但对边界 有不同要求 依据区域内点能否访问到区域外的点,对边 界的要求是
4连通区域,边界只要8连通即可 8连通区域,边界必须是4连通
例:如左图
像素 和 像素
38
(1)4连通区域,边界为 (2)8连通区域,边界为
ET定义
每条扫描线,对应一个链表 链表中每个结点的结构 x 1/k ymax next
typedef struct { int ymax; float x; float deltax; Edge* nextEdge; } Edge;
•x:交点x 坐标 •Deltax(1/k):边的斜率的倒数 •ymax: 边的上端点的 y 坐标值(何时不再相交) •nextEdge:下一条边的指针