程序地在岛上生成区域


29

我目前有一些看起来像这样的岛屿:

岛

我想按程序将其细分为多个区域,如下所示:

岛屿与地区

我要寻找什么算法?您对下图所示的如何创建连贯区域有建议吗?感谢您的帮助。


首先,您是如何获得岛屿形象的?您是否生成了它,如果是,则如何实现它?
Vaillancourt

我是从在线地图生成器获得的。
domisum

很抱歉延迟更新我的答案-回家所需的时间比原先计划的时间更长。我添加了一些插图和链接。
皮卡列克

如果您是通过在线生成器获得的,则应查看Azgaar的Fantasy Map Generator。它具有区域和名称,带有可自定义的参数,WB.SE表示欢迎。这是一个github,因此您可以检查他们的代码。
Anoplexian-恢复莫妮卡

Answers:


40

在现实世界中,那些省级边界通常会遵循河流等地质特征。

因此,也许一个好的方法就是对岛上的地质建模,并确定边界是否脱离了这个边界?

Red Blob Games在这个主题上有一些不错的文章,效果很好。

他的方法似乎涉及使用Voronoi细分,并将河流定义为单元之间的边界。

查阅他网站上的其他文章,他在地图生成方面做了很多工作。

岛


3
请注意,在现实世界中,政治或行政区划有时也会有任意的区划,通常是直线(例如,沿着纬度/经度线,山峰之间的线等)。
Pablo H

2
@PabloH好点,尽管直线边界似乎是中世纪后的殖民时代现象。但是,由于我们不知道OP的问题所在,因此可能与问题有关
Sentry

27

我将通过两次Voronoi图解决此问题:

第一遍:区域划分

第一遍将使用点的稀疏分布(即,点之间的距离应相对较大),以便将岛粗略地划分为多个区域(请参见以下有关点生成的注释)。接下来,基于这些点生成Voronoi图。这会将岛围绕每个点划分为多边形区域,如下所示:

在此处输入图片说明

第二次通过:边界随机化

现在,该岛已被划分为多个区域,下一步就是“粗略”它们之间的边界。为此,请使用更紧凑的点分布(即,点之间的距离应较小)生成新的点层,然后再次使用这些点创建另一个Voronoi图。接下来,对于每个较小的区域,通过检查其“种子”点将其分配给较大的区域。这将导致较大细分之间的边界更加锯齿。这是两个Voronoi图的特写图:

在此处输入图片说明

这是仅显示最终边界的同一区域:

在此处输入图片说明

关于点生成的评论

关于点生成,我喜欢使用Poisson圆盘分布来获得相对较好甚至均匀的点分布。另一个常见的选择是获得相似的均匀分布,即对一组“规则”随机点使用劳埃德算法。LLoyd的代码更容易编写,但可能需要经过反复试验才能确定需要多少次传递才能得出所需的结果。

这种方法的一个潜在问题是,第一遍分区可能会生成一些非常小的区域。如果您不希望它们出现在最终结果中,则只需将它们与随机的相邻区域合并即可。

最后说明

我提供的插图恰好是光栅图像,但是该技术也适用于多边形/矢量表示。


1
对于程序平面图,这就是我要做的,从区域(岛屿)内部的点制作Voronoi图,构造一个包围同一区域的网格(对于您的情况,它不一定是矩形,变形的网格),然后根据最小网格单元格的0.6%,计算网格和Voronoi的布尔交集,计算面积并分配给数据树(列表列表,锯齿状数组等……您喜欢的任何数据结构),您会得到一些丢失的单元格,但是您可以将选中的网格与原始网格进行比较,以找到并重新分配给您的树。
菲利佩·古铁雷斯

您已添加图片!这正是我为其他目的所做的
菲利普·古铁雷斯

4

MineCraft很好地做到了这一点,并且已经对其世界生成算法进行了详尽的分析和记录。

该算法有各种描述,其中一个在这里:https : //github.com/UnknownShadow200/ClassiCube/wiki/Minecraft-Classic-map-generation-algorithm

该算法的核心是Perlin噪声发生器。这可以直接控制海拔(或多或少,因为后续的挖洞步骤也可以改变表面),以及生物群落的产生。像生物群系生成器之类的东西可能是您要用来创建区域的东西。

(它的旧版本)已记录在案,基本上它是通过使用两个不同的Perlin Noise发生器来工作的,一个用于“温度”,一个用于“降水”,然后从这两个中选择生物群系。变量本身(温度和降水)在以后的游戏中并没有真正使用。例如,沙漠没有下雨,但是游戏是根据“沙漠”属性而不是原始的降水值来确定的。

有多种在线工具可以根据随机种子生成生物群系图,其中之一是 mineatlas.com。我猜他们在内部使用了Java服务器,该服务器使用了MineCraft本身的内部类。我不知道他们的任何源代码是否直接可用。


4

一种典型的算法,例如, Azgaar使用源代码)。大致是这样的:

  1. 将您的陆地分割成较小的区域,例如通过三角骨三角化或voronoi细胞。
  2. 确定(随机或以其他方式)您的文化,境界,宗教或您想模拟的其他任何东西的“起点”位置。
  3. 为他们每个人确定(随机或其他方式)一个“增长因素”。您拥有的增长因子差异越大,最终图的一致性就越差。
  4. 现在,遍历您的领域(等),并根据增长因素,使它们散布到周围的空区域中,直到填满整个地图。
  5. 您可能希望以稍微拉直边界为结尾,方法是切换只有一种邻居使用其自身颜色的单元格,否则将其周围的单元格替换为该颜色。


2

有趣的问题是:)这种方法有点基于Vornoi单元,但是距离度量不是完全欧几里得(我使用1.5的幂而不是2.0的幂),并且内置了一些随机性。它可能会跳过不理想的水面。

可以将附近的区域合并在一起以获得更多有趣的形状,这里我使用了N个最近的邻居来确定。

如果您有兴趣,我可以详细介绍并分享Python代码。

地图1 地图2

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.