You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 02:55:29