当前位置:文档之家› 图形学实验报告四 多边形填充算法

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


扫描线种子填充:
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();
个交点。如右图,对 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) 。
扫描线种子算法
测试对象为象素段 ,对区域内的每一象素段 ,只保留其最右边 (或左边)的象素作为种子象素 .区域填充(扫描 线算法): –目标:减少递归层次 –适用于内点表示的 4 连通区域 基本过程: 当给定种子点时,首先填充种子点所在的扫描线上的位于给定区域的一个区段,然后确定与这一区段相通的上 下两条扫描线上位于给定区域内的区段,并依次保存下来。反复这个过程,直到填充结束。 算法步骤: 1、填充并确定种子区段; 2、初始化:将种子区段压入堆栈; 3、出栈:如果堆栈为空,则算法结束;否则取栈顶元素 y,xLeft,xRight) ,以纵坐标为 y 的扫描线为当前扫描 线,[xLeft, xRight]为搜索区间; 4、填充并确定新的区段 。
}
四连通种子填充:
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); } }
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;
扫描线算法算法原理:
利用相邻像素之间的连贯性, 提高算法效率。 根据多边形内部点的连续性知:一条扫描线与多
10 8 实 6 验 原 理 4 2 0 2 4 6 8 10 12 1 2 3 4
边形的交点中,入点和出点之间所有点都是多边 形的内部点。所以,对所有的扫描线填充入点到 出点之间所有的点就可填充多边形。 处理对象:非自交多边形(边与边之间除了 顶点外无其它交点)判断扫描线上的点是否在多 边形之内,根据多边形区域连续性, 分为 3 个步骤: – – – – 求出扫描线与多边形所有边的交点; 把这些交点的 x 坐标值以升序排列; 对每一对交点间的区域进行填充。 第三个步骤是从奇数个交点出发到偶数
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;
指 导 教 师 意 见 签名: 年 月 日
实 验 VS2010(C#) 环 境 1、 添加一个 C#下的 Windows 窗体应用程序,实现对于算法的选择。 实 2、 根据不同算法添加不同窗体,接受圆初始化数据,编写核心函数。代码见实验原理中代码 验 部分。 步 3、 调试运行。 骤
实 验 内 容 在 VS2010 环境下利用 C#编程实现多边形填充算法,并给出实验报告。
种子填充算法算法原理
种子填充算法首先假定区域由封闭轮廓线围成,且轮廓线内某点是已知的,然后开始搜索与种子点相邻且 位于轮廓线内的点。如果这相邻 点不在轮廓线内,则已达到轮廓线的边界;如果相邻点在轮廓线之内,则这相 邻点成为新的种子点,继续搜索下去。只适用于光栅扫描设备。 区域分类(区域采用边界定义,即区域边界上与边界外的象素取相同值,区域内部的点取不同值) 1、 四向连通区域:各象素在水平垂直四个方向是边通的。即从区域内任一点出发,可水平/垂直移动到达区 域内任一点。 2、 八向连通区域:各象素在水平、垂直、及四个对角线方向都是是边通的。即从区域内任一点出发,可水平、 垂直、及四个对角线方向移动到达区域内任一点。
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++; } }
实 验 结 果
实 验 总 结
一、对四连通的递归区域填充算法的分析: 该算法也可以填充有孔区域。 优点:算法简单 缺点:递归执行,效率不高,要求很大的存储空间来实现堆栈。费时费内存。 改进:减少递归次数,提高效率。 二、扫描线种子填充算法 该算法对于每一个待填充区段,只需压栈一次;因此,扫描线种子填充算法提高了区域填充的 效率。
贵州大学实验报告
学院:计算机科学与信息学院 姓名 实验时间 实验项目名称 实 验 2013.4级: 101 实验组 4
指导教师
吴云
成绩
使学生掌握光栅显示系统中多边形的扫描转换和区域填充算法。掌握 4 连通区域的扩展性。 目 的 实 验 实现多边形的扫描转换算法和区域填充算法 要 求
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++; } } }
相关主题