如何生成圆形/方形渐变并存储到二维数组,用于程序化岛屿生成?
渐变生成及程序化岛屿实现思路
圆形渐变实现
你要实现的中心低、边缘高的圆形渐变可按以下逻辑计算,最终结果直接存入二维数组即可:
- 先确定二维数组的宽
w、高h,计算中心点坐标cx = w / 2,cy = h / 2 - 计算中心到数组角落的最大距离
maxDist = Math.sqrt(cx * cx + cy * cy) - 遍历数组每个坐标
(x,y):- 计算当前点到中心的欧氏距离
dist = Math.sqrt((x - cx) ** 2 + (y - cy) ** 2) - 归一化得到渐变值
gradient[y][x] = Math.pow(dist / maxDist, 2),指数可按需调整,数值越大渐变边缘越陡峭
- 计算当前点到中心的欧氏距离
方形渐变实现
方形渐变核心是取横纵方向偏移的最大值,逻辑如下:
- 同样先确定数组宽
w、高h和中心点(cx, cy) - 遍历数组每个坐标
(x,y):- 计算x方向归一化偏移
xOffset = Math.abs(x - cx) / cx - 计算y方向归一化偏移
yOffset = Math.abs(y - cy) / cy - 取两个偏移的最大值作为渐变值
gradient[y][x] = Math.pow(Math.max(xOffset, yOffset), 2),指数调整规则和圆形渐变一致
- 计算x方向归一化偏移
与Simplex噪声结合生成岛屿
步骤如下:
- 生成和渐变数组尺寸相同的Simplex噪声数组,将噪声值归一化到
[0, 1]区间 - 逐点计算最终高程值:
elevation[y][x] = noise[y][x] - gradient[y][x] - 阈值筛选:高程值大于0的区域判定为陆地,小于0的区域判定为海洋,还可以对正高程做进一步分层,对应沙滩、平原、山地等不同地形
简化实现示例(JavaScript)
// 配置参数 const width = 256; const height = 256; const curvature = 2; // 渐变曲率 const landThreshold = 0; // 1. 生成圆形渐变数组 const gradient = new Array(height).fill(0).map(() => new Array(width).fill(0)); const cx = width / 2; const cy = height / 2; const maxDist = Math.sqrt(cx * cx + cy * cy); for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { const dist = Math.sqrt((x - cx) ** 2 + (y - cy) ** 2); gradient[y][x] = Math.pow(dist / maxDist, curvature); } } // 2. 生成simplex噪声数组(此处假设你已经引入simplex-noise库) const noise = new Array(height).fill(0).map(() => new Array(width).fill(0)); // 你的噪声生成逻辑,确保输出归一化到[0,1] // 示例逻辑:引入simplex-noise后调用 const noise2D = createNoise2D(); // 然后赋值 noise[y][x] = (noise2D(x/32, y/32) + 1) / 2; // 3. 计算最终地形 const terrain = new Array(height).fill(0).map(() => new Array(width).fill(0)); for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { terrain[y][x] = noise[y][x] - gradient[y][x]; // 可直接做二分类:terrain[y][x] = terrain[y][x] > landThreshold ? 1 : 0; } }
内容的提问来源于stack exchange,提问作者olawrdhalpme
相关产品推荐
相关产品推荐

