📜  多边形填充算法

📅  最后修改于: 2021-01-13 09:35:18             🧑  作者: Mango


多边形是顶点的有序列表,如下图所示。为了用特定颜色填充多边形,您需要确定落在多边形边界上的像素和落在多边形内部的像素。在本章中,我们将看到如何使用不同的技术填充多边形。

多边形

扫描线算法

该算法通过使扫描线与多边形边缘相交并填充交点对之间的多边形来工作。以下步骤描述了该算法的工作原理。

步骤1-从给定的多边形中找出Ymin和Ymax。

扫描线算法

步骤2 -ScanLine与多边形的每个边相交(从Ymin到Ymax)。命名多边形的每个交点。如上图所示,它们分别命名为p0,p1,p2,p3。

步骤3-按X坐标的升序对交点进行排序,即(p0,p1),(p1,p2)和(p2,p3)。

步骤4-填充多边形内的所有那些坐标对,并忽略备用对。

洪水填充算法

有时,我们遇到一个物体,想要用不同的颜色填充该区域及其边界。我们可以使用指定的内部颜色绘制此类对象,而不用像边界填充算法那样搜索特定的边界颜色。

它不依赖于对象的边界,而是依赖于填充颜色。换句话说,它将填充颜色替换为对象的内部颜色。当不再存在原始内部颜色的像素时,该算法完成。

再一次,该算法依靠四连接或八连接方法填充像素。但是,它不是在寻找边界颜色,而是在寻找内部的所有相邻像素。

洪水填充算法

边界填充算法

边界填充算法就是它的名字。该算法在对象内部拾取一个点并开始填充,直到它碰到对象的边界。边界的颜色和我们填充的颜色应该不同,此算法才能起作用。

在此算法中,我们假设整个对象的边界颜色相同。边界填充算法可以通过4个连接像素或8个连接像素来实现。

4个连接的多边形

在该技术中,如图所示,使用了4个连接像素。我们将像素放在当前像素的上方,下方,右侧和左侧,此过程将继续进行,直到找到具有不同颜色的边界为止。

4个连接的多边形

算法

步骤1-初始化种子点(种子,种子),fcolor和dcol的值。

步骤2-定义多边形的边界值。

步骤3-检查当前种子点是否为默认颜色,然后重复步骤4和5,直到达到边界像素。

If getpixel(x, y) = dcol then repeat step 4 and 5

步骤4-更改默认颜色,并在种子点填充颜色。

setPixel(seedx, seedy, fcol)

步骤5-以四个邻点递归地遵循该过程。

FloodFill (seedx – 1, seedy, fcol, dcol)
FloodFill (seedx + 1, seedy, fcol, dcol)
FloodFill (seedx, seedy - 1, fcol, dcol)
FloodFill (seedx – 1, seedy + 1, fcol, dcol)

步骤6-退出

该技术存在问题。考虑以下情况,我们试图填充整个区域。在此,图像仅部分填充。在这种情况下,无法使用4像素连接技术。

4连多边形1

8连通多边形

在该技术中,如图所示,使用了8个连接像素。像在4连接技术中一样,我们将像素放在当前像素的上方,下方,右侧和左侧。

除此之外,我们还将像素放在对角线上,以便覆盖当前像素的整个区域。这个过程将继续进行,直到找到具有不同颜色的边界。

8连通多边形

算法

步骤1-初始化种子点(种子,种子),fcolor和dcol的值。

步骤2-定义多边形的边界值。

步骤3-检查当前种子点是否为默认颜色,然后重复步骤4和5,直到达到边界像素

If getpixel(x,y) = dcol then repeat step 4 and 5

步骤4-更改默认颜色,并在种子点填充颜色。

setPixel(seedx, seedy, fcol)

步骤5-以四个邻点递归地遵循该过程

FloodFill (seedx – 1, seedy, fcol, dcol)
FloodFill (seedx + 1, seedy, fcol, dcol)
FloodFill (seedx, seedy - 1, fcol, dcol)
FloodFill (seedx, seedy + 1, fcol, dcol)
FloodFill (seedx – 1, seedy + 1, fcol, dcol)
FloodFill (seedx + 1, seedy + 1, fcol, dcol)
FloodFill (seedx + 1, seedy - 1, fcol, dcol)
FloodFill (seedx – 1, seedy - 1, fcol, dcol)

步骤6-退出

4像素连接技术无法填充下图所示的区域,而8像素连接技术不会发生这种情况。

8连多边形1

内外测试

此方法也称为计数法。在填充对象时,我们经常需要确定特定点是在对象内部还是外部。有两种方法可以识别特定点是在对象内部还是外部。

  • 奇偶规则
  • 非零绕组数规则

奇偶规则

在这项技术中,我们将计算从任意点(x,y)到无穷大沿线的边缘。如果交互次数为奇数,则点(x,y)为内部点;如果交互次数是偶数,则点(x,y)是外部点。下面的示例描述了此概念。

奇偶规则

从上图可以看出,从点(x,y)来看,左侧的交互点数为5,右侧的交互点数为3。从两端看,交互点的数量为奇数,因此该点被视为对象内。

非零绕组数规则

此方法还可以与简单多边形一起使用,以测试给定点是否在内部。借助销钉和橡皮筋可以很容易地理解它。将销钉固定在多边形的边缘之一上,并绑扎其中的橡皮筋,然后沿多边形的边缘拉伸橡皮筋。

当多边形的所有边缘都被橡皮筋覆盖时,请检查已固定在测试点的销钉。如果在该点处发现至少一个风,则将其视为在多边形内,否则可以说该点不在多边形内。

非零绕组

在另一种替代方法中,给多边形的所有边指定方向。从要测试的点到X方向的最左边绘制一条扫描线。

  • 将值1赋给所有要向上的边,将所有其他-1赋给方向值。

  • 检查扫描线从其通过的边缘方向值,并对其求和。

  • 如果该方向值的总和不为零,则该要测试的内部点,否则为外部点

  • 在上图中,我们总结了扫描线所经过的方向值,然后总和为1 – 1 + 1 = 1;非零。因此,该点被称为内部点。