
[ad_1]
Code is commented. Credit goes to Sean McCullough.
http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
// Ported from Stefan Gustavson's java implementation
// http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
// Read Stefan's wonderful paper for particulars on how this code works.
//
// Sean McCullough banksean@gmail.com
/**
* You can go in a random quantity generator object should you like.
* It is assumed to have a random() technique.
*/
var SimplexNoise = operate(r) {
if (r == undefined) r = Math;
this.grad3 = [[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],
[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],
[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]];
this.p = [];
for (var i=0; i<256; i++) {
this.p[i] = Math.flooring(r.random()*256);
}
// To take away the necessity for index wrapping, double the permutation desk size
this.perm = [];
for(var i=0; i<512; i++) {
this.perm[i]=this.p[i & 255];
}
// A lookup desk to traverse the simplex round a given level in 4D.
// Details could be discovered the place this desk is used, within the 4D noise technique.
this.simplex = [
[0,1,2,3],[0,1,3,2],[0,0,0,0],[0,2,3,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,2,3,0],
[0,2,1,3],[0,0,0,0],[0,3,1,2],[0,3,2,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,3,2,0],
[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],
[1,2,0,3],[0,0,0,0],[1,3,0,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,3,0,1],[2,3,1,0],
[1,0,2,3],[1,0,3,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,0,3,1],[0,0,0,0],[2,1,3,0],
[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],
[2,0,1,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,0,1,2],[3,0,2,1],[0,0,0,0],[3,1,2,0],
[2,1,0,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,1,0,2],[0,0,0,0],[3,2,0,1],[3,2,1,0]];
};
SimplexNoise.prototype.dot = operate(g, x, y) {
return g[0]*x + g[1]*y;
};
SimplexNoise.prototype.noise = operate(xin, yin) {
var n0, n1, n2; // Noise contributions from the three corners
// Skew the enter house to find out which simplex cell we're in
var F2 = 0.5*(Math.sqrt(3.0)-1.0);
var s = (xin+yin)*F2; // Hairy issue for 2D
var i = Math.flooring(xin+s);
var j = Math.flooring(yin+s);
var G2 = (3.0-Math.sqrt(3.0))/6.0;
var t = (i+j)*G2;
var X0 = i-t; // Unskew the cell origin again to (x,y) house
var Y0 = j-t;
var x0 = xin-X0; // The x,y distances from the cell origin
var y0 = yin-Y0;
// For the 2D case, the simplex form is an equilateral triangle.
// Determine which simplex we're in.
var i1, j1; // Offsets for second (center) nook of simplex in (i,j) coords
if(x0>y0) {i1=1; j1=0;} // decrease triangle, XY order: (0,0)->(1,0)->(1,1)
else {i1=0; j1=1;} // higher triangle, YX order: (0,0)->(0,1)->(1,1)
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), the place
// c = (3-sqrt(3))/6
var x1 = x0 - i1 + G2; // Offsets for center nook in (x,y) unskewed coords
var y1 = y0 - j1 + G2;
var x2 = x0 - 1.0 + 2.0 * G2; // Offsets for final nook in (x,y) unskewed coords
var y2 = y0 - 1.0 + 2.0 * G2;
// Work out the hashed gradient indices of the three simplex corners
var ii = i & 255;
var jj = j & 255;
var gi0 = this.perm[ii+this.perm[jj]] % 12;
var gi1 = this.perm[ii+i1+this.perm[jj+j1]] % 12;
var gi2 = this.perm[ii+1+this.perm[jj+1]] % 12;
// Calculate the contribution from the three corners
var t0 = 0.5 - x0*x0-y0*y0;
if(t0<0) n0 = 0.0;
else {
t0 *= t0;
n0 = t0 * t0 * this.dot(this.grad3[gi0], x0, y0); // (x,y) of grad3 used for 2D gradient
}
var t1 = 0.5 - x1*x1-y1*y1;
if(t1<0) n1 = 0.0;
else {
t1 *= t1;
n1 = t1 * t1 * this.dot(this.grad3[gi1], x1, y1);
}
var t2 = 0.5 - x2*x2-y2*y2;
if(t2<0) n2 = 0.0;
else {
t2 *= t2;
n2 = t2 * t2 * this.dot(this.grad3[gi2], x2, y2);
}
// Add contributions from every nook to get the ultimate noise worth.
// The result's scaled to return values within the interval [-1,1].
return 70.0 * (n0 + n1 + n2);
};
// 3D simplex noise
SimplexNoise.prototype.noise3d = operate(xin, yin, zin) {
var n0, n1, n2, n3; // Noise contributions from the 4 corners
// Skew the enter house to find out which simplex cell we're in
var F3 = 1.0/3.0;
var s = (xin+yin+zin)*F3; // Very good and easy skew issue for 3D
var i = Math.flooring(xin+s);
var j = Math.flooring(yin+s);
var ok = Math.flooring(zin+s);
var G3 = 1.0/6.0; // Very good and easy unskew issue, too
var t = (i+j+ok)*G3;
var X0 = i-t; // Unskew the cell origin again to (x,y,z) house
var Y0 = j-t;
var Z0 = k-t;
var x0 = xin-X0; // The x,y,z distances from the cell origin
var y0 = yin-Y0;
var z0 = zin-Z0;
// For the 3D case, the simplex form is a barely irregular tetrahedron.
// Determine which simplex we're in.
var i1, j1, k1; // Offsets for second nook of simplex in (i,j,ok) coords
var i2, j2, k2; // Offsets for third nook of simplex in (i,j,ok) coords
if(x0>=y0) {
if(y0>=z0)
{ i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } // X Y Z order
else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } // X Z Y order
else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } // Z X Y order
}
else { // x0<y0
if(y0<z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; } // Z Y X order
else if(x0<z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; } // Y Z X order
else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; } // Y X Z order
}
// A step of (1,0,0) in (i,j,ok) means a step of (1-c,-c,-c) in (x,y,z),
// a step of (0,1,0) in (i,j,ok) means a step of (-c,1-c,-c) in (x,y,z), and
// a step of (0,0,1) in (i,j,ok) means a step of (-c,-c,1-c) in (x,y,z), the place
// c = 1/6.
var x1 = x0 - i1 + G3; // Offsets for second nook in (x,y,z) coords
var y1 = y0 - j1 + G3;
var z1 = z0 - k1 + G3;
var x2 = x0 - i2 + 2.0*G3; // Offsets for third nook in (x,y,z) coords
var y2 = y0 - j2 + 2.0*G3;
var z2 = z0 - k2 + 2.0*G3;
var x3 = x0 - 1.0 + 3.0*G3; // Offsets for final nook in (x,y,z) coords
var y3 = y0 - 1.0 + 3.0*G3;
var z3 = z0 - 1.0 + 3.0*G3;
// Work out the hashed gradient indices of the 4 simplex corners
var ii = i & 255;
var jj = j & 255;
var kk = ok & 255;
var gi0 = this.perm[ii+this.perm[jj+this.perm[kk]]] % 12;
var gi1 = this.perm[ii+i1+this.perm[jj+j1+this.perm[kk+k1]]] % 12;
var gi2 = this.perm[ii+i2+this.perm[jj+j2+this.perm[kk+k2]]] % 12;
var gi3 = this.perm[ii+1+this.perm[jj+1+this.perm[kk+1]]] % 12;
// Calculate the contribution from the 4 corners
var t0 = 0.6 - x0*x0 - y0*y0 - z0*z0;
if(t0<0) n0 = 0.0;
else {
t0 *= t0;
n0 = t0 * t0 * this.dot(this.grad3[gi0], x0, y0, z0);
}
var t1 = 0.6 - x1*x1 - y1*y1 - z1*z1;
if(t1<0) n1 = 0.0;
else {
t1 *= t1;
n1 = t1 * t1 * this.dot(this.grad3[gi1], x1, y1, z1);
}
var t2 = 0.6 - x2*x2 - y2*y2 - z2*z2;
if(t2<0) n2 = 0.0;
else {
t2 *= t2;
n2 = t2 * t2 * this.dot(this.grad3[gi2], x2, y2, z2);
}
var t3 = 0.6 - x3*x3 - y3*y3 - z3*z3;
if(t3<0) n3 = 0.0;
else {
t3 *= t3;
n3 = t3 * t3 * this.dot(this.grad3[gi3], x3, y3, z3);
}
// Add contributions from every nook to get the ultimate noise worth.
// The result's scaled to remain simply inside [-1,1]
return 32.0*(n0 + n1 + n2 + n3);
};
Also, should you use a PRNG with that you would be able to simply get simple re-instateable outcomes
/*
I've wrapped Makoto Matsumoto and Takuji Nishimura's code in a namespace
so it is higher encapsulated. Now you may have a number of random quantity mills
they usually will not stomp throughout eachother's state.
If you need to use this as an alternative to Math.random(), use the random()
technique like so:
var m = new MersenneTwister();
var randomNumber = m.random();
You also can name the opposite genrand_{foo}() strategies on the occasion.
If you need to use a selected seed as a way to get a repeatable random
sequence, go an integer into the constructor:
var m = new MersenneTwister(123);
and that can at all times produce the identical random sequence.
Sean McCullough (banksean@gmail.com)
*/
/*
A C-program for MT19937, with initialization improved 2002/1/26.
Coded by Takuji Nishimura and Makoto Matsumoto.
Before utilizing, initialize the state by utilizing init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Redistribution and use in supply and binary varieties, with or with out
modification, are permitted offered that the next circumstances
are met:
1. Redistributions of supply code should retain the above copyright
discover, this record of circumstances and the next disclaimer.
2. Redistributions in binary kind should reproduce the above copyright
discover, this record of circumstances and the next disclaimer within the
documentation and/or different supplies supplied with the distribution.
3. The names of its contributors might not be used to endorse or promote
merchandise derived from this software program with out particular prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Any suggestions could be very welcome.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
electronic mail: m-mat @ math.sci.hiroshima-u.ac.jp (take away house)
*/
var MersenneTwister = operate(seed) {
if (seed == undefined) {
seed = new Date().getTime();
}
/* Period parameters */
this.N = 624;
this.M = 397;
this.MATRIX_A = 0x9908b0df; /* fixed vector a */
this.UPPER_MASK = 0x80000000; /* most vital w-r bits */
this.LOWER_MASK = 0x7fffffff; /* least important r bits */
this.mt = new Array(this.N); /* the array for the state vector */
this.mti=this.N+1; /* mti==N+1 means mt[N] just isn't initialized */
this.init_genrand(seed);
}
/* initializes mt[N] with a seed */
MersenneTwister.prototype.init_genrand = operate(s) {
this.mt[0] = s >>> 0;
for (this.mti=1; this.mti<this.N; this.mti++) {
var s = this.mt[this.mti-1] ^ (this.mt[this.mti-1] >>> 30);
this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253)
+ this.mti;
/* See Knuth TAOCP Vol2. third Ed. P.106 for multiplier. */
/* In the earlier variations, MSBs of the seed have an effect on */
/* solely MSBs of the array mt[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
this.mt[this.mti] >>>= 0;
/* for >32 bit machines */
}
}
/* initialize by an array with array-length */
/* init_key is the array for initializing keys */
/* key_length is its size */
/* slight change for C++, 2004/2/26 */
MersenneTwister.prototype.init_by_array = operate(init_key, key_length) {
var i, j, ok;
this.init_genrand(19650218);
i=1; j=0;
ok = (this.N>key_length ? this.N : key_length);
for (; ok; k--) {
var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30)
this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525)))
+ init_key[j] + j; /* non linear */
this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */
i++; j++;
if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; }
if (j>=key_length) j=0;
}
for (ok=this.N-1; ok; k--) {
var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30);
this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941))
- i; /* non linear */
this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */
i++;
if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; }
}
this.mt[0] = 0x80000000; /* MSB is 1; assuring non-zero preliminary array */
}
/* generates a random quantity on [0,0xffffffff]-interval */
MersenneTwister.prototype.genrand_int32 = operate() {
var y;
var mag01 = new Array(0x0, this.MATRIX_A);
/* mag01[x] = x * MATRIX_A for x=0,1 */
if (this.mti >= this.N) (this.mt[0]&this.LOWER_MASK);
this.mt[this.N-1] = this.mt[this.M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
this.mti = 0;
y = this.mt[this.mti++];
/* Tempering */
y ^= (y >>> 11);
y ^= (y << 7) & 0x9d2c5680;
y ^= (y << 15) & 0xefc60000;
y ^= (y >>> 18);
return y >>> 0;
}
/* generates a random quantity on [0,0x7fffffff]-interval */
MersenneTwister.prototype.genrand_int31 = operate() {
return (this.genrand_int32()>>>1);
}
/* generates a random quantity on [0,1]-real-interval */
MersenneTwister.prototype.genrand_real1 = operate() {
return this.genrand_int32()*(1.0/4294967295.0);
/* divided by 2^32-1 */
}
/* generates a random quantity on [0,1)-real-interval */
MersenneTwister.prototype.random = function() {
return this.genrand_int32()*(1.0/4294967296.0);
/* divided by 2^32 */
}
/* generates a random number on (0,1)-real-interval */
MersenneTwister.prototype.genrand_real3 = function() {
return (this.genrand_int32() + 0.5)*(1.0/4294967296.0);
/* divided by 2^32 */
}
/* generates a random number on [0,1) with 53-bit resolution*/
MersenneTwister.prototype.genrand_res53 = function() {
var a=this.genrand_int32()>>>5, b=this.genrand_int32()>>>6;
return(a*67108864.0+b)*(1.0/9007199254740992.0);
}
/* These real versions are due to Isaku Wada, 2002/01/09 added */
[ad_2]