我试图找出办法有用于固定的规模:钻石广场算法固定大小
https://en.wikipedia.org/wiki/Diamond-square_algorithm
我看到算法要求的2(+1)大小的力量阵列。
我遇到的问题是,我想有不管决议产生相同的高度图。所以如果我有一个512的分辨率,它看起来与分辨率256相同,但是只有更少的细节。我只是无法弄清楚如何做到这一点。
我的初始想法是总是创建在某一尺寸如高度图1024和下采样到我想要的水库。问题是我希望较高的分辨率相当高(比如说4096),并且这会严重降低较低分辨率下的性能,因为我们必须以最高分辨率运行算法。
目前该算法是在JavaScript这里是一个片段:
function Advanced() {
var adv = {},
res, max, heightmap, roughness;
adv.heightmap = function() {
// heightmap has one extra pixel this is ot remove it.
var hm = create2DArray(res-1, res-1);
for(var x = 0;x< res-1;x++) {
for(var y = 0;y< res-1;y++) {
hm[x][y] = heightmap[x][y];
}
}
return hm;
}
adv.get = function(x,y) {
if (x < 0 || x > max || y < 0 || y > max) return -1;
return heightmap[x][y];
}
adv.set = function(x,y,val) {
if(val < 0) {
val = 0;
}
heightmap[x][y] = val;
}
adv.divide = function(size) {
var x, y, half = size/2;
var scale = roughness * size;
if (half < 1) return;
for (y = half; y < max; y += size) {
for (x = half; x < max; x += size) {
adv.square(x, y, half, Math.random() * scale * 2 - scale);
}
}
for (y = 0; y <= max; y += half) {
for (x = (y + half) % size; x <= max; x += size) {
adv.diamond(x, y, half, Math.random() * scale * 2 - scale);
}
}
adv.divide(size/2);
}
adv.average = function(values) {
var valid = values.filter(function(val) {
return val !== -1;
});
var total = valid.reduce(function(sum, val) {
return sum + val;
}, 0);
return total/valid.length;
}
adv.square = function(x, y, size, offset) {
var ave = adv.average([
adv.get(x - size, y - size), // upper left
adv.get(x + size, y - size), // upper right
adv.get(x + size, y + size), // lower right
adv.get(x - size, y + size) // lower left
]);
adv.set(x, y, ave + offset);
}
adv.diamond = function(x, y, size, offset) {
var ave = adv.average([
adv.get(x, y - size), // top
adv.get(x + size, y), // right
adv.get(x, y + size), // bottom
adv.get(x - size, y) // left
]);
adv.set(x, y, Math.abs(ave + offset));
}
adv.generate = function(properties, resolution) {
Math.seedrandom(properties.seed);
res = resolution + 1;
max = res - 1;
heightmap = create2DArray(res, res);
roughness = properties.roughness;
adv.set(0, 0, max);
adv.set(max, 0, max/2);
adv.set(max, max, 0);
adv.set(0, max, max/2);
adv.divide(max);
}
function create2DArray(d1, d2) {
var x = new Array(d1),
i = 0,
j = 0;
for (i = 0; i < d1; i += 1) {
x[i] = new Array(d2);
}
for (i=0; i < d1; i += 1) {
for (j = 0; j < d2; j += 1) {
x[i][j] = 0;
}
}
return x;
}
return adv;
}
有谁这样做过?
貌似没有再笑! – Dave3of5