Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Итак, подход таков: пусть наш ландшафт изначально задуман гигантских размеров (например, 16777216x16777216 пикселей, хотя это далеко не предел).


function randFromPair(x, y) {
var s = seed * 1972854929;
s ^= (x * 2971902361) ^ (y * 3572953751);
s = 0x6C078965 * s;// & 0xFFFFFFFF;
/*
s ^= s >> 11;
s ^= (s << 7) & 0x9D2C5680;
s ^= (s << 15) & 0xEFC60000;
s ^= s >> 18;
*/
return (s & 0x7FFFFFFF) * 4.656612875245796924105750827168e-10; //(1./2147483647.);;
}

@deNULL После некоторых размышлений я пришел к выводу, что быстрого способа преобразовать две координаты в число, которое было бы мало скоррелировано с ними, в принципе невозможно. В итоге я остановился на такой функции, которая дает приемлимые результаты из-за многократного взятия чисел по простым модулям
function rerandom(seed) {
// всякая инициализационная хрень
if (this instanceof rerandom === false) {
return new rerandom(seed);
}
var self = this;
this.p1 = 2654435761;
this.p2 = 2246822519;
this.p3 = 3266489917;
this.p4 = 668265263;
this.p5 = 374761393;
this.p=[this.p1,this.p2,this.p3,this.p4,this.p5];
this.cut = 2097151;
this.seed = seed;
}
rerandom.prototype.GetXzHash = function(x, y) {
if(!y) y=0;
for (var i = 0; i < 80; i++) {
var xm7 = x % 7;
var xm13 = x % 13;
var xm1301081 = x % 1301081;
var ym8461 = y % 8461;
var ym105467 = y % 105467;
var ym105943 = y % 105943;
y = x + this.seed;
x += (xm7 + xm13 + xm1301081 + ym8461 + ym105467 + ym105943);
}
return (xm7 + xm13 + xm1301081 + ym8461 + ym105467 + ym105943) & this.cut;
};
rerandom.prototype.GetXxHash = function() {
let buf = arguments
let h32;
let index = 0;
let len = buf.length;
if (len >= 4) {
let limit = len - 4;
let v1 = this.seed + this.p1 + this.p2;
let v2 = this.seed + this.p2;
let v3 = this.seed + 0;
let v4 = this.seed - this.p1;
while (index <= limit) {
v1 = this.CalcSubHash (v1, buf[index]);
index++;
v2 = this.CalcSubHash (v2, buf[index]);
index++;
v3 = this.CalcSubHash (v3, buf[index]);
index++;
v4 = this.CalcSubHash (v4, buf[index]);
index++;
}
h32 = this.RotateLeft (v1, 1) + this.RotateLeft (v2, 7) + this.RotateLeft (v3, 12) + this.RotateLeft (v4, 18);
}
else {
h32 = this.seed + this.p5;
}
h32 += len * 4;
while (index < len) {
h32 += buf[index] * this.p3;
h32 = this.RotateLeft (h32, 17) * this.p4;
index++;
}
h32 ^= h32 >> 15;
h32 *= this.p2;
h32 ^= h32 >> 13;
h32 *= this.p3;
h32 ^= h32 >> 16;
return h32&this.cut;
};
rerandom.prototype.RotateLeft = function(value, count) {
return (value << count) | (value >> (32 - count));
}
rerandom.prototype.CalcSubHash = function(value, read_value) {
value += read_value * this.p2;
value = this.RotateLeft (value, 13);
value *= this.p1;
return value;
}
rerandom.prototype.rnd = rerandom.prototype.GetXxHash;
//rerandom.prototype.rnd = rerandom.prototype.GetXzHash;
Алгоритм «diamond-square» для построения фрактальных ландшафтов