- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第三章(续)
3.3 区域填充
区域填充即给出一个区域的定义,要求对此区域范围内的所有像素赋予指定的颜色代码。只要算法设计合理,运用着色的方法就可以使光栅图形的画面色彩逼真,更能形象面具有真实感地利用二维光栅技术显示三维图形。
多边形可以是构成平面图形的几何元素,也可以是构成三维物体表面的投影。如果物体的表面是曲面,也可由适当的多边形去逼近。因此,区域填充中最常用的是多边形填色。
3.3.1 区域的表示和类型
在计算机图形学中,区域有两种重要的表示方法:顶点表示和点阵表示。顶点表示(如图3-15所示)也称几何表示,是用区域的顶点序列来表示。例如,多边形区域由闭合折线定义。这种表示直观、几何意义强、占内存少,易于进行几何变换,但由于没有明确指出哪些象素在多边形内,故不能直接用于面着色,需要通过某种扫描转换将顶点表示转变为点阵表示。 点阵表示(如图3-16所示)也称像素表示,是用位于多边形内的象素集合来刻画多边形。这种表示便于帧缓冲器表示图形,是面着色所需的图形表示形式。
点阵表示分两种情况,一种称为内点表示,如图3-17所示,另一种称为边界表示,如图3-18所示。
区域填充算法要求区域是连通的。但是由象素构成的“区域”有一定的特殊性,因此被区分为两种连通性区域:四连通区域和八连通区域。它们的区别是前者只有四个连通方向而后者则有八个连通方向,见图3-19和图3-20。
图3-21给出了由内点定义的四连通区域和八连通区域。
通常,四连通区域也是八连通的区域,但二者的边界不尽相同。例如,图3-21(a)在四连通意义下的边界为图3-22,在八连通意义下的边界则为图3-23。
图3-24给出了由边界定义的四连通区域和八连通区域。
这两种不同连通性区域的填充算法不能混用。例如,当适用于八连通区域的填充算法用到四连通区域上去时,就有可能越界填充。
3.3.2 区域填充算法
常见有扫描线多边形填充算法、边填充算法、种子填充算法 等。其中种子填充算法比较简单,具体还可以分成:
边界表示的四连通区域种子填充算法
边界表示的八连通区域种子填充算法
内点表示的四连通区域种子填充算法
内点表示的八连通区域种子填充算法
扫描线种子填充算法
先介绍一个以边界表示的四连通区域种子填充算法 (基于递规)
void BoundaryFill4(int x,int y,TColor boundaryColor,TColor newColor)
{
}
可以稍加修改将其改为基于栈的算法。(本质上递归也是用栈实现的)
种子填充法不断要进出栈操作,并且重复检查率极高,因此效率非常低。
一种改进方法是使用扫描线种子填充法。
3.3.2扫描线种子填充算法
目标:减少递归层次
适用于边界表示的4连通区域
算法思想:在任意不间断区间中只取一个种子像素(不间断区间指在一条扫描线上一组相邻象素),填充当前扫描线上的该段区间;然后确定与这一区段相邻的上下两条扫描线上位于区域内的区段,并依次把它们保存起来,反复进行这个过程,直到所保存的个区段都填充完毕。
扫描线种子填充法的流程描述:
(1) 初始化:堆栈置空。将种子点(x,y)入栈。
(2) 出栈:若栈空则结束。否则取栈顶元素(x,y),以y作为当前扫描线。
(3) 填充并确定种子点所在区段:从种子点(x,y)出发,沿当前扫描线向左、右两个方向填充,直到边界。分别标记区段的左、右端点坐标为xl和xr。
(4) 确定新的种子点:在区间[xl,xr]中检查与当前扫描线y上、下相邻的两条扫描线上的象素。若存在非边界、未填充的象素,则把每一区间的最右象素作为种子点压入堆栈,返回(2)。
该算法对于每一个待填充区段,只需压栈一次;因此,扫描线填充算法提高了区域填充的效率。
下面将要给出一段可以实现上述算法的C语言代码。为了使读者易于理解这一段代码。我们先提供在上述流程基础上结合了数据描述,并且具有更精确描述的一种改进版:
// 与上面流程中描述步骤的主要差异是将区间的左端点入栈
(1)若当前点在边界上或者已着色,则结束。否则将栈清空,当前点(种子)进栈。
(2)出栈,由栈顶元素 (x0, y0) 确定当前扫描线。
(3)沿扫描线 y= y0 左移,直到受阻于边界点或已着色点。将上行标志和下行标志(是两个布尔型的变量)都置为无。
(4)对当前点着色。
(5)检查上行当前点:若上行标志为无,并且该点既非边界也没有被着色,则置上行标志为有,并且使上行当前点(x, y-1) 进栈;若该点为边界点或者已被着色,则置上行标志为无。
(6)检查下行当前点:若下行标志为无,并且该点既非边界也没有被着色,则置下行标志为有,并且使下行当前点(x, y+1) 进栈;若该点为边界点或者已被着色
文档评论(0)