我正在编写一个随机地图生成器,并不太确定如何随机生成逼真的景观。我正在处理these sorts本地规模的地图,这会带来一些有趣的问题。
最简单的案例之一是forest:
Sparse Medium Dense
Typical trees 50% 70% 80%
Massive trees — 10% 20%
Light undergrowth 50% 70% 50%
Heavy undergrowth — 20% 50%
树木和灌木丛可以存在于同一个空间中,因此平均稀疏森林有25%的典型树木和浅灌木丛,25%的典型树木,25%的光丛林和25%的开放空间。中等密度的森林需要更多的思考,但这也不是我的问题所在,因为它们都是均匀分散的。
我的问题在于生成集群和路径,同时保持百分比限制。 Marshes就是一个很好的例子:
Moor Swamp
Shallow bog 20% 40%
Deep bog 5% 20%
Light undergrowth 30% 20%
Heavy undergrowth 10% 20%
深沼泽广场通常聚集在一起,周围是不规则的浅沼泽广场环。
还可能存在一个额外的地图元素,一个树篱,以及一条开阔的地面,蜿蜒穿过沼泽。这两种类型的地图元素(聚类和路径)都存在问题,因为地图的总构图应该包含元素的X%,但它不是均匀分布的。其他元素,例如溪流,池塘和流沙也需要集群或路径类型生成。
在给定这些约束的情况下,我可以使用哪种技术生成逼真的地图?
我正在使用C#,FYI(但这不是C#特定的问题。)
答案 0 :(得分:21)
现实的“随机”分发通常是使用Perlin Noise完成的,可以用来给出像你提到的“clumps”分布。它通过对来自随机数据点的多层线性内插值求和/组合来工作。每层(或“八度”)的数据点数是最后一层的两倍,并限制在较窄的值范围内。结果是“逼真”的随机纹理。
以下是Hugo Elias对the theory behind Perlin Noise的精彩演示。
这是我在Perlin Noise in C#上找到的第一件事。
你可以做的是生成一个Perlin Noise图像并设置一个“阈值”,其中任何高于某个值的东西都是“on”,而它下面的所有东西都是“off”。你最终得到的是事物高于门槛的团块,看起来不规则和令人敬畏。只需将阈值以上的值分配到您想要地形特征的位置即可。
Here is a demonstration如果程序生成Perlin Noise位图,然后随时间调整截止阈值。可以看到清晰的“结块”。它可能就是你想要的。
请注意,在阈值较高的情况下,它上面的点很少,而且很稀疏。但是当阈值降低时,这些点会“增长”成团块(根据perlin噪音的性质),并且这些团块中的一些将相互结合,并且基本上创造出非常自然和类似地形的东西。
请注意,您还可以通过设置Perlin Noise函数的“湍流”来设置“丛集因子”或特征聚集的趋势,这基本上会导致PN函数的峰值和波谷更加突出并且更加接近在一起。
现在,在哪里设置阈值?阈值越高,最终地图上要素的百分比越低。阈值越低,百分比越高。你可以搞砸他们。你可以通过摆弄一点数学来得到确切的百分比(似乎值的分布遵循Normal Distribution;我可能是错的)。调整它直到它恰到好处:)
编辑正如评论中所指出的,您可以通过创建累积直方图(地图的百分比%低于阈值的索引)找到确切的百分比,然后选择给您的阈值你需要的百分比。
这里最酷的事情是你可以在这里轻松地创建围绕某些其他功能(如沼泽功能)的功能 - 只需使用相同的Perlin Noise地图两次 - 第二次,降低阈值。第一个将是块状,第二个将在同一区域周围成块,但随着块放大(参考前面发布的flash动画)。
对于像树篱这样的其他功能,你可以尝试建模简单的random walk线,这些线比转弯更倾向于直线,并将它们随机放置在基于perlin的地图上。
以下是50x50瓷砖稀疏森林地图示例。灌木丛是棕色的,树木是蓝色的(对不起),以便清楚哪一个。
Sparse Forest http://img688.imageshack.us/img688/7005/forestmap.png
对于这张地图,我没有确切的阈值来匹配50%;我只将阈值设置为最大值的50%。从统计数据来看,每次平均精确到50%。但它可能不足以满足您的目的;请参阅前面的说明,了解如何执行此操作。
以下是Marsh功能的演示(为清晰起见,不包括灌木丛),背面有浅灰色和深沼泽的沼泽:
Marshes http://img202.imageshack.us/img202/5092/marshdemo.png
这只是50x50,因此有一些神器,但你可以看到你可以轻松地从深沼泽中“生长”浅沼泽 - 只需调整相同Perlin地图上的阈值即可。对于这个,我用眼球水平来表达最令人满意的结果,但为了你自己的目的,你可以做以前提到的。
这是一张从相同的Perlin Noise地图生成的沼泽地图,但是在250x250平铺地图上展开:
Marshes 250x250 http://img251.imageshack.us/img251/2867/marshdemo250.png
答案 1 :(得分:2)
我从未做过这类事,但这里有一些想法。
您可以通过将随机选择偏向网格上与该类型的现有元素相近的位置来获取聚类。为所有方块指定默认值1。对于具有现有聚类元素的正方形,将聚类值添加到相邻正方形(聚类值越高,聚类越强)。然后在所有正方形的概率分布函数上随机选择该类型的下一个元素。
对于路径,您可以使用类似的过程,但路径将逐步扩展(路径概率在路径末端旁边的方块有限,其他地方为零)。可以通过增加在路径方向上选择的概率来完成方向路径。蜿蜒路径的方向可以在随机扩展的过程中发生变化(new_direction = mf * old_direction +(1-mf)* rand_direction,其中mf是0到1之间的动量因子。)
答案 2 :(得分:1)
要扩展academicRobot的评论,你可以从一些网格单元格中的默认沼泽或森林种子开始,让它们使用相关的随机数从源头增长。例如,沼泽可能有八个相邻的网格单元,每个网格单元有90%的可能性也是沼泽,但有10%的可能性是其他东西。您可以让种子中的生态系统形成并调整相关性,直到您得到看起来正确的东西。即使在电子表格中也可能很容易实现。
答案 3 :(得分:0)
您可以开始阅读链接here。我记得看过更好的文件。如果我发现它会发布它(它也是基于L系统)。
但这是一般的;关于你面临的特殊问题,我想你应该按照
进行建模关键在于,即使你不知道如何用给定的属性构建地图,如果你能够评估属性(聚类比率;路径优度)并对它们进行评分,那么你可以蛮力或做一些其他问题空间横向。
如果您仍然想要采用生成方法,那么您将不得不更仔细地检查生成规则;这是我想要追求的想法
答案 4 :(得分:0)
对于具有Voronoi模式的某些类型的区域,您可能会取得一些成功。我从来没有见过用于创建地图,但我已经看到它用于许多类似的领域。