山脉的衰减函数

Fall-off function for mountains

我正在用体素地形编写类似 mincraft 的游戏。

对于山脉,我指定了位置、高度和大小。如果当前 (x, y, z) 坐标处的方块是山的一部分,则有一个函数 return 为真。如果一个方块远离山的中心,如果 z 坐标低于与山的距离的最大高度,即方块离山越远,则只有 returned降低最大高度。所以在山的中心,最大高度很高,即使 z 很高,True 也会被 returned(我使用的是 z-up 系统)。但是,离山越远,最大高度会越低。

然而,我当前的函数(下图)return将它们线性化,真正的山没有直边:

def isMountain(self, x, y, z, mountainPos, mountainSize, mountainHeight):
        if math.hypot(mountainPos[0] - x, mountainPos[1] - y) < mountainSize:
                if z < (mountainHeight - math.hypot(mountainPos[0] - x, mountainPos[1] - y)):
                    return True
                else:
                    return False

第 3 行检查 z 是否小于该位置的最大高度,如果是,returning True,否则,False。

这些是距离的最大高度:
距离:最大高度
0 - 10
1 - 9
2 - 8
...
9 - 1
10 - 0

我如何重写此函数以使其 return 更像山峰的值:不是线性的,而是立方体或平滑衰减(如 blender 比例编辑模式),因此它会给出值更像这样:
0 - 10
1 - 9
2 - 9
3 - 8
4 - 7
5 - 5
6 - 3
7 - 1

您可以为此绞尽脑汁找出一些数学公式,也可以模拟自然侵蚀过程。 这通常是使用网格(矩阵、单元格...)和迭代来完成的。 基本上你会从或多或少随机的高地开始,然后侵蚀它直到形成山脉,实际上山脉就是剩下的。 也就是说,这通常比使用简单函数的成本更高,但在现代计算机上这会运行良好。

另见:https://www.gamasutra.com/blogs/MattKlingensmith/20130811/198049/How_we_Generate_Terrain_in_DwarfCorp.php

如果您有兴趣走另一条路,您可以使用修改版本的柏林噪声来使用振幅和频率,然后使用平滑过渡来获得您想要的结果。您可以将点设置为具有一般高度范围,然后让噪声算法发挥作用以在点之间创建可变性。我做了类似的事情来创建一个具有不同生物群落的 inf gen 世界,这些生物群落具有不同种类的山高和形状。

也许你可以使用像这样的逆 tan 函数

https://www.desmos.com/calculator/sn7tbepuxh

其中 h 是最大高度,s 是陡度,x 是距峰中心的距离。最后的 -1 允许忽略负值,这样山脚就不会永远延伸。

我已经将它用于一个小游戏的山峰生成器,它似乎工作正常,只要你调整你的陡度和高度值,使山峰不太尖锐。