我在Java中实现了菱形方形算法,但我对结果作为高度图并不完全满意。它形成了一个很多的“湖泊” - 低矮的小区域。使用菱形平方算法生成高度,然后进行标准化。在下面的示例中,white = high,black = low,blue是低于15的任何值:海洋的占位符。
如何平滑地形以减少湖泊数量?
我研究了一个简单的盒子模糊功能(将每个像素设置为其邻居的平均值),但这会导致奇怪的伪影,可能是因为钻石方块的方形步长。
不同(可能是高斯)模糊是否合适,或者这是我实施的问题? This链接说钻石方块有一些固有的问题,但这些似乎不是规则间隔的工件,而我的高度图是以16(而不是4)值的方式播种的。
答案 0 :(得分:0)
您的阈值算法需要更合理。您需要在尺寸方面实际指定要移除的内容,而不仅仅是高度。基本上简单的阈值设置“海平面”,低于这个水平的任何东西都是水。问题在于,因为用于生成地形的算法是以偶然的方式进行的,所以可以用水填充小区域。
要解决此问题,您需要从根本上确定水域的大小,并且只允许更大的区域。
一种简单的方法是不允许单个“像素”代表水。基本上要么不将它们设置为水(如果有水,可以使用每个位代表的位图)或者只是提高水平。这应该可以从图像中获取大部分单个像素,并将其清除相当多。
您可以将其扩展为N个像素(实际上代表区域)。基本上你必须通过计算连接的像素来识别水域的大小。问题是,它允许长的薄区域(可能代表河流)。
因此最好更进一步,将宽度和长度分开计算。
例如,检测一个简单的单个像素如果map [i,j]<门槛和& (map [i-1,j-1]> threshold&& ...&& map [i + 1,j + 1]> threshold)then Area = 1
会检测出孤立的像素。
您可以对此进行修改以检测较大的组并编写通用算法来测量任何大小的潜在“海洋”...然后应该很容易生成任何您想要的最小(和最大)海洋尺寸的高度图。下一步是“修复”(或使用位图)地图中可能低于海平面但未转换为实际水的部分。也就是说,因为我们一般认为海平面以下的东西含有水。通过使用位图,您可以允许水中的水或陆地中的水等
如果你使用平滑,它可能也可以正常工作,但你仍然会遇到这样的问题。平滑减小了“海洋”的大小,但是大海洋可能会变成一个小海洋,一个小海洋最终变成一个像素。根据地图的整体平均值,经过足够的迭代后,您可能会得到所有水或所有土地。模糊还可以减少地图的细节。
好消息是,如果你用可控参数设计你的算法,那么你可以控制地图中有多少海洋,或它们有多大,它们是多方形(或者你想要的圆形),或者可以使用多少水,等等。您投入的精力越多,您就可以更准确地模拟现实。最终,如果你想要无限复杂,你可以考虑如何实际形成地形等等......但是,当然,这些简单算法的重点是允许它们在合理的时间内可计算。