ハッシュ関数を書くことができます:
function hash(x, y) {
// You cast the int parts and decimal parts of your entries as 16-bits signed integers.
var xi = x & 0xFFFF;
var xf = (((x-xi) * (1 << 16)) & 0xFFFF);
var yi = y & 0xFFFF;
var yf = (((y-yi) * (1 << 16)) & 0xFFFF);
// You hash theses numbers
var r1 = ((39769 * xi) & 0xFFFF);
r1 = ((r1 + xf) * 23747) & 0xFFFF;
r1 = ((r1 + yi) * 19073) & 0xFFFF;
r1 = ((r1 + yf) * 25609) & 0xFFFF;
var r2 = ((25609 * xf) & 0xFFFF);
r2 = ((r2 + yf) * 39769) & 0xFFFF;
r2 = ((r2 + xi) * 23747) & 0xFFFF;
r2 = ((r2 + yi) * 19073) & 0xFFFF;
// And returns a floating number between 0 and 1.
return ((r1&0xFF)/(1<<24)) + ((r2&0xFFFF)/(1<<16));
}
この関数は、int 部分の最初の 16 ビットのみを保持するため、各 65536 をラップしますが、アイデアはここにあります。ハッシュ関数を変更できます。はるかに良い方法は次のとおりです。
var arrayBuffer = new ArrayBuffer(8);
var dataView = new DataView(arrayBuffer);
function hash(x, y) {
dataView.setFloat32(0, x);
dataView.setFloat32(4, y);
var xi = dataView.getUint16(0);
var xf = dataView.getUint16(2);
var yi = dataView.getUint16(4);
var yf = dataView.getUint16(6);
// You hash theses numbers
var r1 = ((39769 * xi) & 0xFFFF);
r1 = ((r1 + xf) * 23747) & 0xFFFF;
r1 = ((r1 + yi) * 19073) & 0xFFFF;
r1 = ((r1 + yf) * 25609) & 0xFFFF;
var r2 = ((25609 * xf) & 0xFFFF);
r2 = ((r2 + yf) * 39769) & 0xFFFF;
r2 = ((r2 + xi) * 23747) & 0xFFFF;
r2 = ((r2 + yi) * 19073) & 0xFFFF;
// And returns a floating number between 0 and 1.
dataView.setUint16(0, r1);
dataView.setUint16(2, r2);
return Math.abs(dataView.getFloat32(0) % 1);
}
この最後の方法では WebGLTypedArray
を使用します。これにより、エントリの一部にアクセスでき、より優れたハッシュが得られます。しかし、私の経験からすると、これは本当に遅くなります (私のコンピューターの最初のメソッドでは 8 億回の呼び出し/秒、2 番目のメソッドではわずか 200 万回です。参考までに、従来のランダム関数は 2 億回の呼び出し/秒です)。すべてのブラウザで利用できるわけではありません。