种子填充

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、实验目标
1)通过实验,进一步了解和掌握几种常用多边形种子填充算法的基本原理
2)熟练掌握种子填充算法和区域图案填充的基本过程
3)掌握在C/C++环境下用多边形种子填充算法编程实现指定多边形的填充
二、实验内容
一、实验内容
1. 在给定的程序模板中添加递归种子填充、简单种子填充、扫描线种子填充,区域图案填充的功能,生成新的程序窗口中要有递归种子填充、简单种子填充、扫描线种子填充,区域图案填充的菜单按钮,点击按钮分别出现递归种子填充、简单种子填充、扫描线种子填充,区域图案填充的窗口,点击鼠标左键实现在窗口任意位置填充;
2. 在理解递归种子填充、简单种子填充、扫描线种子填充,区域图案填充的原理,使用VC实现递归种子填充、简单种子填充、扫描线种子填充,区域图案填充程序的编写,并最终在MFC上演示出来。

二、实验原理
种子填充算法又称为边界填充算法。

其基本思想是:从多边形区域的一个内点开始,由内向外用给定的颜色画点直到边界为止。

如果边界是以一种颜色指定的,则种子填充算法可逐个像素地处理直到遇到边界颜色为止。

种子填充算法常用四连通域和八连通域技术进行填充操作。

1.递归种子填充算法原理
种子填充算法是区域填充的一种重要基本方法,它假设在多边形内有一像素已知,由此出发利用连通性找到区域内的所有像素。

递归种子填充算法的基本思想:设(x,y)是内点表示的一区域G内的一点,先取(x,y)点为种子点,测试其颜色,若不等于边界颜色,说明是区域内一点,则将其置为新的颜色newcolor,否则说明该点不在区域G内,则停止填充;然后将该点周围的四个点(四连通)或八个点(八连通)作为新的种子点进行同样的处理,通过这种扩散完成对整个区域的填充。

2.简单种子填充算法原理
简单种子填充算法,其基本思想:从多边形区域的一个内点开始,由内向外
用给定的颜色画点知道边界颜色为止。

如果边界是以一种颜色指定的,则简单种子填充算法可逐个像素地处理知道遇到边界色为止。

算法具体实现如下:
(1)初始化:堆栈置空,将种子点入栈;
(2)栈顶像素出栈;
(3)将出栈像素设置成多边形色;
(4)按左上右下的顺序检查与出栈像素相邻的四个像素,若其中某个像素不在边界且未设置成多边形色,则把该像素入栈;
(5)返回第(2)步
3.扫描线种子填充算法原理
该算法思想:首先填充种子所在扫描线上的连续区段;然后确定与这一区段相邻的上下两条扫描线上位于该区段内是否存在需要填充的新区段,如果存在,则依次把它们保存起来,反复这个过程,直到所保存的各区段都填充完毕。

算法具体实现如下:
(1)初始化:堆栈置空,将种子点(x,y)入栈;
(2)出栈:若栈空则结束,否则取栈顶元素(x,y),以y作为当前扫描线;(3)填充并确定种子点所在区段:从种子点(x,y)出发,沿当前扫描线向左、右两个方向填充,直到边界。

分别标记区段的左、右两个端点坐标为xl和xr;(4)确定新的种子点:在区间[xl,xr]中检查与当前扫描线y上、下相邻的两条扫描线上的像素。

若存在非边界、未填充的的像素,则把每一个区间的最右像素作为种子点压入堆栈,返回第(2)步。

4.区域图案填充算法原理
区域图案填充就是用图案来填充平面区域,在确定了区域内点后,不是马上对该像素填色,而是先将该像素映射到图案位图的对应位置。

根据图案上对应位置的像素值,决定填充颜色。

填充方式有透明方式和不透明方式,图案填充方式有相对定位法和绝对定位法。

三、实验步骤
本次实验步骤
1.添加菜单
1)找到资源视图, 找到Menu, 并点开IDR_MAINFRAME;
2)基本图形生成中,加入递归种子填充菜单;
3)右键递归种子填充菜单,选择添加事件处理程序;
2.转到头文件中drawstyle的定义,在枚举中添加Seedfill4;
3.在void CcgdemoView::OnDraw(CDC* pDC)中定义填充的颜色,初始颜色。

4.在OnLButtonDown类中加入Seedfill4的响应;
5.在OnRButtonDown类中加入Seedfill4的响应;
6.在事件处理响应中将按钮对应到响应的函数中;
7.构建处理函数
8.void CcgdemoView::Seedfill4(CDC* pDC,int x,int y,int boundarycolor,int newcolor)
其他的都类似
四、实验遇到的问题及其解决方法(重点)
1.当填充的背景颜色和边界颜色不同时,会产生只能填充一半的问题,然后我将填充的背景颜色和边界颜色设置为同一种颜色就可以了;
2.完成程序编写调试之后,运行程序,在生成的画图窗口基本图形生成下拉菜单下没有发现递归种子填充的菜单按钮;错误提示void CcgdemoView::Seedfill4(CDC* pDC,int x,int y,int boundarycolor,int newcolor)中没有重载变量,后经检查发现void CcgdemoView::onSeedfill4(CDC* pDC,int x,int y,int boundarycolor,int newcolor)中多写了on,应该是void CcgdemoView::Seedfill4(CDC* pDC,int x,int y,int boundarycolor,int newcolor);
3.在扫描线填充中,运行程序时出现无调试信息,即无法找到“cgdemo.exe”的调试信息,或者调试信息不匹配,在同学的帮助下删除;
4.afx_msg void OnSaomiaofill()
5.ON_COMMAND(ID_SaoMiaoFill, &CcgdemoView::OnSaomiaofill)
6.重新添加事件处理程序和添加void CcgdemoView::OnSaomiaofill(){m_drawstyle = SaoMiaoFill; Invalidate(true);},完成了程序的运行;
7.在区域图案填充中,运行程序后,在生成的画图窗口中,点击区域图案
填充菜单按钮后,进行按钮填充没有出现图案填充,而是还是递归种子填充,经检查发现,递归函数写成了Seedfill4,而应该是Quyu。

五、实验结论和收获
种子填充算法的优点是非常简单,缺点是需要大量栈空间来存储相邻的
点。

扫描线填充算法就是它的改进的方法。

它是通过沿扫描线填充水平像素段,来处理四连通或八连通相邻点,这样就仅仅只需要将每个水平像素段的起始位置压入栈,而不需要将当前位置周围尚未处理的相邻像素都压入栈,从而可以节省大量的栈空间。

相关文档
最新文档