您好,欢迎来到99网。
搜索
您的当前位置:首页图形学实验报告四 多边形填充算法

图形学实验报告四 多边形填充算法

来源:99网
贵州大学实验报告

学院:计算机科学与信息学院 专业:计算机科学与技术 班级: 101

姓名 实验时间 2013.4.25 学号 指导教师 吴云 实验组 成绩 4 实验项目名称 多边形填充算法 实验使学生掌握光栅显示系统中多边形的扫描转换和区域填充算法。掌握4连通区域的扩展性。 目的 实验实现多边形的扫描转换算法和区域填充算法 要求 扫描线算法算法原理: 利用相邻像素之间的连贯性,提高算法效率。根据多边形内部点的连续性知:一条扫描线与多10 8 实6 验原4 1 2 3 4 边形的交点中,入点和出点之间所有点都是多边形的内部点。所以,对所有的扫描线填充入点到出点之间所有的点就可填充多边形。 处理对象:非自交多边形(边与边之间除了顶点外无其它交点)判断扫描线上的点是否在多边形之内,根据多边形区域连续性,分为3个步骤: – 求出扫描线与多边形所有边的交点; – 把这些交点的x坐标值以升序排列; – 对每一对交点间的区域进行填充。 – 第三个步骤是从奇数个交点出发到偶数理 2 0 2 4 6 8 10 12 个交点。如右图,对y=8的扫描线排序x坐标得到的表是(2,4,9,13),然后对交点2与4之间、9与13之间的所有象素点进行填充。 边界上的象素:“左闭右开”,“下闭上开”(将左边界和下边界的点算为内部,而将右边界和上边界算为外部) 顶点:“上开下闭”。 几种特殊情况: 1.扫描线交于一顶点,共享的两条边分另处于扫描线的两边,这时交点只取一个,如扫描线y=3,该点被填充一次。2.共享交点的两条边处于扫描线的上方,这时交点取二个,如扫描线y=1,该点被填充一次。 3.共享交点的两条边处于扫描线的下方,这时交点取0个,如扫描线y=9,无交点,不填充。 4.水平边在算法中不起任何作用,可不考虑。 活性边表(提高效率): 为了减少求交的计算量,要利用一条边与相继的两条扫描线的交点的连贯性。在处理一条扫描线时只对活性边(与它相交的多边形的边)进行求交运算。把交点按x增加方向存在一个链表(活性边表)中。活性边:与当前扫描线相交的边。 活性边表(AEL):按交点x的增量顺序存放在一个链表中,该链表称作活性边表(AEL)。 种子填充算法算法原理 种子填充算法首先假定区域由封闭轮廓线围成,且轮廓线内某点是已知的,然后开始搜索与种子点相邻且位于轮廓线内的点。如果这相邻 点不在轮廓线内,则已达到轮廓线的边界;如果相邻点在轮廓线之内,则这相邻点成为新的种子点,继续搜索下去。只适用于光栅扫描设备。 区域分类(区域采用边界定义,即区域边界上与边界外的象素取相同值,区域内部的点取不同值) 1、 四向连通区域:各象素在水平垂直四个方向是边通的。即从区域内任一点出发,可水平/垂直移动到达区域内任一点。 2、 八向连通区域:各象素在水平、垂直、及四个对角线方向都是是边通的。即从区域内任一点出发,可水平、垂直、及四个对角线方向移动到达区域内任一点。 扫描线种子算法 测试对象为象素段 ,对区域内的每一象素段,只保留其最右边(或左边)的象素作为种子象素.区域填充(扫描线算法): –目标:减少递归层次 –适用于内点表示的4连通区域 基本过程: 当给定种子点时,首先填充种子点所在的扫描线上的位于给定区域的一个区段,然后确定与这一区段相通的上下两条扫描线上位于给定区域内的区段,并依次保存下来。反复这个过程,直到填充结束。 算法步骤: 1、填充并确定种子区段; 2、初始化:将种子区段压入堆栈; 3、出栈:如果堆栈为空,则算法结束;否则取栈顶元素y,xLeft,xRight),以纵坐标为y的扫描线为当前扫描线,[xLeft, xRight]为搜索区间; 4、填充并确定新的区段 。 扫描线种子填充: public void FillField(int x, int y, Color newColor, uint oldColor, Graphics g) { if (\"\".Equals(txtx.Text) || \"\".Equals(txty.Text)) { return; } else { x = Convert.ToInt32(txtx.Text); y = Convert.ToInt32(txty.Text); } int xl, xr; bool spanNeedFill; myStack.Clear(); int ptx = x; int pty = y; myStack.Push(ptx); myStack.Push(pty); while (myStack.Count != 0) { pty = (int)myStack.Pop(); ptx = (int)myStack.Pop(); x = ptx; y = pty; while (bitmap.GetPixel(g, x, y) == oldColor) { bitmap.SetPixel(g, x, y, ColorTranslator.ToWin32(newColor)); x++; } xr = x - 1; x = ptx - 1; while (bitmap.GetPixel(g, x, y) == oldColor) { bitmap.SetPixel(g, x, y, ColorTranslator.ToWin32(newColor)); x--; } xl = x + 1; x = xl; y = y + 1; while (x <= xr) { spanNeedFill = false; while (bitmap.GetPixel(g, x, y) == oldColor) { spanNeedFill = true; x++; } if (spanNeedFill) { ptx = x - 1; pty = y; myStack.Push(ptx); myStack.Push(pty); spanNeedFill = false; } while (bitmap.GetPixel(g, x, y) != oldColor && x <= xr) { x++; } } x = xl; y = y - 2; while (x <= xr) { spanNeedFill = false; while (bitmap.GetPixel(g, x, y) == oldColor) { spanNeedFill = true; x++; } if (spanNeedFill) { ptx = x - 1; pty = y; myStack.Push(ptx); myStack.Push(pty); spanNeedFill = false; } while (bitmap.GetPixel(g, x, y) != oldColor && x <= xr) { x++; } } } } 四连通种子填充: public void BoundaryFill4(int x, int y, uint oldColor, Graphics g) { if (\"\".Equals(txtx.Text) || \"\".Equals(txty.Text)) { return; } else { x = Convert.ToInt32(txtx.Text); y = Convert.ToInt32(txty.Text); } if (bitmap.GetPixel(g, x, y) != oldColor && bitmap.GetPixel(g, x, y) == ColorTranslator.ToWin32(Color.Yellow)) { bitmap.SetPixel(g, x, y, ColorTranslator.ToWin32(Color.Red)); BoundaryFill4(x, y + 1, oldColor, g); BoundaryFill4(x - 1, y, oldColor, g); BoundaryFill4(x, y - 1, oldColor, g); BoundaryFill4(x + 1, y, oldColor, g); } } 实验VS2010(C#) 环境 1、 添加一个C#下的Windows窗体应用程序,实现对于算法的选择。 实2、 根据不同算法添加不同窗体,接受圆初始化数据,编写核心函数。代码见实验原理中代码验部分。 步3、 调试运行。 骤 实验内容 在VS2010环境下利用C#编程实现多边形填充算法,并给出实验报告。 实验 结果 实验总一、对四连通的递归区域填充算法的分析: 该算法也可以填充有孔区域。 优点:算法简单 缺点:递归执行,效率不高,要求很大的存储空间来实现堆栈。费时费内存。 改进:减少递归次数,提高效率。 二、扫描线种子填充算法 结 该算法对于每一个待填充区段,只需压栈一次;因此,扫描线种子填充算法提高了区域填充的效率。 指导教师意见

签名: 年 月 日

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 99spj.com 版权所有 湘ICP备2022005869号-5

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务