(random: RandomFn = Math.random)
| 109 | * @returns {NoiseFunction2D} |
| 110 | */ |
| 111 | export function createNoise2D(random: RandomFn = Math.random): NoiseFunction2D { |
| 112 | const perm = buildPermutationTable(random); |
| 113 | // precalculating this yields a little ~3% performance improvement. |
| 114 | const permGrad2x = new Float64Array(perm).map(v => grad2[(v % 12) * 2]); |
| 115 | const permGrad2y = new Float64Array(perm).map(v => grad2[(v % 12) * 2 + 1]); |
| 116 | return function noise2D(x: number, y: number): number { |
| 117 | // if(!isFinite(x) || !isFinite(y)) return 0; |
| 118 | let n0 = 0; // Noise contributions from the three corners |
| 119 | let n1 = 0; |
| 120 | let n2 = 0; |
| 121 | // Skew the input space to determine which simplex cell we're in |
| 122 | const s = (x + y) * F2; // Hairy factor for 2D |
| 123 | const i = fastFloor(x + s); |
| 124 | const j = fastFloor(y + s); |
| 125 | const t = (i + j) * G2; |
| 126 | const X0 = i - t; // Unskew the cell origin back to (x,y) space |
| 127 | const Y0 = j - t; |
| 128 | const x0 = x - X0; // The x,y distances from the cell origin |
| 129 | const y0 = y - Y0; |
| 130 | // For the 2D case, the simplex shape is an equilateral triangle. |
| 131 | // Determine which simplex we are in. |
| 132 | let i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords |
| 133 | if (x0 > y0) { |
| 134 | i1 = 1; |
| 135 | j1 = 0; |
| 136 | } // lower triangle, XY order: (0,0)->(1,0)->(1,1) |
| 137 | else { |
| 138 | i1 = 0; |
| 139 | j1 = 1; |
| 140 | } // upper triangle, YX order: (0,0)->(0,1)->(1,1) |
| 141 | // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and |
| 142 | // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where |
| 143 | // c = (3-sqrt(3))/6 |
| 144 | const x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords |
| 145 | const y1 = y0 - j1 + G2; |
| 146 | const x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords |
| 147 | const y2 = y0 - 1.0 + 2.0 * G2; |
| 148 | // Work out the hashed gradient indices of the three simplex corners |
| 149 | const ii = i & 255; |
| 150 | const jj = j & 255; |
| 151 | // Calculate the contribution from the three corners |
| 152 | let t0 = 0.5 - x0 * x0 - y0 * y0; |
| 153 | if (t0 >= 0) { |
| 154 | const gi0 = ii + perm[jj]; |
| 155 | const g0x = permGrad2x[gi0]; |
| 156 | const g0y = permGrad2y[gi0]; |
| 157 | t0 *= t0; |
| 158 | // n0 = t0 * t0 * (grad2[gi0] * x0 + grad2[gi0 + 1] * y0); // (x,y) of grad3 used for 2D gradient |
| 159 | n0 = t0 * t0 * (g0x * x0 + g0y * y0); |
| 160 | } |
| 161 | let t1 = 0.5 - x1 * x1 - y1 * y1; |
| 162 | if (t1 >= 0) { |
| 163 | const gi1 = ii + i1 + perm[jj + j1]; |
| 164 | const g1x = permGrad2x[gi1]; |
| 165 | const g1y = permGrad2y[gi1]; |
| 166 | t1 *= t1; |
| 167 | // n1 = t1 * t1 * (grad2[gi1] * x1 + grad2[gi1 + 1] * y1); |
| 168 | n1 = t1 * t1 * (g1x * x1 + g1y * y1); |
no test coverage detected