部分补水

时间:2019-04-01 11:17:42

标签: algorithm graph-theory theory geography flood-fill

我正在写一个基于voronoi的世界生成器,其中我区分了山脉,湖泊,森林和海洋等地理特征。

每个功能都有一个ID,因此可以对其进行标识和引用。我使用洪水填充算法来确定单元格属于哪些特征。

我已经实现了几种类似的情况,我想将一个功能拆分为多个较小的功能。最直接的例子是由一条狭窄的森林带相连的两个大森林。实际上,应该将其视为两个森林,在狭窄的条带上彼此隔开,但是我的填充算法只是直耕到底,并将所有内容标记为一个大森林的一部分。

我想最终将它们标记为“西部100英亩的木材”和“东部100英亩的木材”,让他们知道它们源自同一片连续的森林。我已经查找了部分洪水填充逻辑,但是由于缺乏主题术语,搜索一直陷于瘫痪。

如果您想查看我正在使用的代码: https://github.com/olinkirkland/map

3 个答案:

答案 0 :(得分:4)

您通常会使用“形态学开口” see Wikipedia definition,它是形态学侵蚀然后是扩张。如果您想象黑色背景上有一个感兴趣的白色前景物体,则腐蚀将侵蚀该物体(在边缘处蚕食),并且膨胀将使边缘变宽/变浅,从而消除小条和狭窄的连接。

您可以使用Python中的Scikit-Image模块或Python或C ++中的OpenCV来实现。我选择只在终端的命令行中使用 ImageMagick 来执行此操作,该安装在大多数Linux发行版中,并且可用于macOS和Windows。

因此,使用此地图图像:

enter image description here

我将其加载,对其进行反转/求反以使森林变白,然后应用我提到的形态学开口,然后将其反转并保存:

<dependency>
  <groupId>com.google.cloud</groupId>
  <artifactId>google-cloud-storage</artifactId>
  <version>1.66.0</version>
</dependency>

enter image description here

答案 1 :(得分:1)

找到连接的区域后,您可以使用右手规则(https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower)在内部进行追踪。

要查找可以实现良好分割点的单像素路径,则可以在此内部路径中查找两次(每个方向一次)访问过的像素。如果分割两边的路径长度都足够长,则可以将该区域在该像素处分割为两部分,然后尝试使用较小的区域再试一次。

如果您要查找超过一个像素宽的分割点,或者要确保任一侧的森林都足够“漂亮”,我建议您将基于像素的方法与其他方法结合起来:

  1. BFS删除距边界小于 w 的像素。

  2. 查找每个剩余的连接区域。每个都将是森林的“中心”。

  3. 检查每个中心,以确保其距离边缘足够远,可以成为森林的中心。

  4. 重新添加删除的像素,将它们连接到最近的中心。

答案 2 :(得分:0)

您可以使用图像处理中的一种技术,该技术使用模糊并应用50%的阈值。这样,减少了细线连接和尖锐的尖峰,并且特征通常变得更圆整,而对象的整体大小不应在一个特定方向上改变。这是重复应用该过程时的样子的图像:

Separation of forests by blurring and applying a threshold

最上面的图像表示您的原始情况,其中有两个森林通过一条狭窄的走廊相连。此过程将逐步删除走廊。

您可以在此过程中调整一些参数,例如。 G。模糊半径和步数,因此您可以根据需要进行调整。