如何用Python的Perlin Noise生成类Minecraft正弦曲线地形?
解决方案
首先,你的核心问题是误用了3D Perlin Noise填充整个三维空间,而Minecraft式地形本质是2D高度场(X-Y平面上每个点对应一个Z轴高度值),同时需要叠加正弦曲线来实现预期的起伏形态。以下是修改后的完整代码,附带详细说明:
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import noise # 地形参数 width = 256 height = 256 scale = 0.08 # 控制噪声起伏的尺度 octaves = 6 persistence = 0.5 lacunarity = 2.0 sin_scale = 0.03 # 正弦曲线的波长控制 # 初始化2D高度场(X-Y平面对应高度Z) terrain_height = np.zeros((height, width)) terrain_type = np.zeros((height, width), dtype=str) # 存储地形类型 # 生成高度场:Perlin噪声 + 正弦曲线叠加 for y in range(height): for x in range(width): # 2D Perlin噪声生成基础地形起伏 noise_val = noise.pnoise2(x * scale, y * scale, octaves=octaves, persistence=persistence, lacunarity=lacunarity) # 叠加正弦曲线,沿X方向生成连绵的正弦起伏 sin_val = np.sin(x * sin_scale) * 0.3 # 合并噪声与正弦值,归一化到[0, 1]范围 terrain_height[y][x] = (noise_val + sin_val + 1) / 2 # 偏移后确保非负 # 划分地形类型 for y in range(height): for x in range(width): h = terrain_height[y][x] if h < 0.2: terrain_type[y][x] = 'river' # 低海拔为河流 elif h < 0.5: terrain_type[y][x] = 'grassland' # 中低海拔为草原 elif h < 0.75: terrain_type[y][x] = 'hill' # 中高海拔为丘陵 else: terrain_type[y][x] = 'mountain' # 高海拔为山脉 # 可视化设置 x_coords, y_coords = np.meshgrid(np.arange(width), np.arange(height)) fig = plt.figure(figsize=(12, 8)) ax = fig.add_subplot(111, projection='3d') ax.set_title('Minecraft-like Terrain with Sinusoidal Patterns') # 用颜色映射对应地形类型 color_map = {'river': 'blue', 'grassland': 'green', 'hill': 'tan', 'mountain': 'gray'} colors = np.array([[color_map[t] for t in row] for row in terrain_type]) # 绘制3D曲面 surf = ax.plot_surface(x_coords, y_coords, terrain_height, facecolors=colors, rstride=2, cstride=2, alpha=0.8) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Elevation') plt.show()
关键修改说明
从3D体素改为2D高度场:
原代码生成的是三维空间中每个点的噪声值,而Minecraft地形是基于平面的高度映射,所以改用2D数组存储每个(X,Y)对应的Z轴高度,符合真实地形的生成逻辑。叠加正弦曲线实现预期形态:
在Perlin噪声的基础上,添加了沿X方向的正弦函数(np.sin(x * sin_scale)),你可以调整sin_scale来控制正弦波的疏密,也可以改为沿Y方向或XY双方向叠加,实现不同的正弦起伏效果。地形类型划分:
通过高度阈值区分河流、草原、丘陵、山脉,你可以调整阈值(比如h < 0.2)来改变各地形的占比,河流也可以结合额外的噪声来生成蜿蜒形态(比如添加一个低频率噪声判断是否为河流)。优化可视化效果:
用plot_surface替代散点图,更直观展示地形起伏,同时用自定义颜色映射区分不同地形类型,符合Minecraft的视觉风格。
内容的提问来源于stack exchange,提问作者user20983853
相关产品推荐
相关产品推荐

