From 8590161a59f14744fcc3a91edb6d5fb7d38792dd Mon Sep 17 00:00:00 2001 From: Quinton Ashley Date: Fri, 7 Jun 2024 13:28:36 -0500 Subject: [PATCH] 1.9.42 --- package.json | 2 +- src/q5-math.js | 224 ++++++++++++++++++++++++++++--------------------- 2 files changed, 130 insertions(+), 96 deletions(-) diff --git a/package.json b/package.json index b683ee6..88f4d3c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "q5", - "version": "1.9.41", + "version": "1.9.42", "description": "The sequel to p5.js!", "author": "quinton-ashley", "contributors": [ diff --git a/src/q5-math.js b/src/q5-math.js index 1300662..84dea25 100644 --- a/src/q5-math.js +++ b/src/q5-math.js @@ -81,10 +81,18 @@ Q5.modules.math = ($) => { return a; }; - $.Noise = Q5.P5Noise; + $.PERLIN = 'perlin'; + $.P5_PERLIN = 'p5-perlin'; + $.SIMPLEX = 'simplex'; + + $.Noise = Q5.P5PerlinNoise; let _noise; - $.noiseMode = (mode) => {}; + $.noiseMode = (mode) => { + if (mode == $.PERLIN) $.Noise = Q5.PerlinNoise; + else if (mode == $.P5_PERLIN) $.Noise = Q5.P5PerlinNoise; + // else if (mode == $.SIMPLEX) $.Noise = Q5.SimplexNoise; + }; $.noiseSeed = (seed) => { _noise = new $.Noise(seed); }; @@ -297,7 +305,125 @@ Q5.modules.math = ($) => { Q5.Noise = class { constructor() {} }; -Q5.P5Noise = class extends Q5.Noise { + +Q5.PerlinNoise = class extends Q5.Noise { + constructor(seed) { + super(); + 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.octaves = 4; + this.falloff = 0.25; + this.p = Array.from({ length: 256 }, () => Math.floor(Math.random() * 256)); + if (seed !== undefined) { + this.p = this.seedPermutation(seed); + } + this.perm = Array.from({ length: 512 }, (_, i) => this.p[i & 255]); + } + + seedPermutation(seed) { + let p = []; + for (let i = 0; i < 256; i++) { + p[i] = i; + } + + let n, q; + for (let i = 255; i > 0; i--) { + seed = (seed * 16807) % 2147483647; + n = seed % (i + 1); + q = p[i]; + p[i] = p[n]; + p[n] = q; + } + + return p; + } + + dot(g, x, y, z) { + return g[0] * x + g[1] * y + g[2] * z; + } + + mix(a, b, t) { + return (1 - t) * a + t * b; + } + + fade(t) { + return t * t * t * (t * (t * 6 - 15) + 10); + } + + noise(x, y, z) { + let total = 0; + let frequency = 1; + let amplitude = 1; + let maxAmplitude = 0; + + for (let i = 0; i < this.octaves; i++) { + const X = Math.floor(x * frequency) & 255; + const Y = Math.floor(y * frequency) & 255; + const Z = Math.floor(z * frequency) & 255; + + const xf = x * frequency - Math.floor(x * frequency); + const yf = y * frequency - Math.floor(y * frequency); + const zf = z * frequency - Math.floor(z * frequency); + + const u = this.fade(xf); + const v = this.fade(yf); + const w = this.fade(zf); + + const A = this.perm[X] + Y; + const AA = this.perm[A] + Z; + const AB = this.perm[A + 1] + Z; + const B = this.perm[X + 1] + Y; + const BA = this.perm[B] + Z; + const BB = this.perm[B + 1] + Z; + + const lerp1 = this.mix( + this.dot(this.grad3[this.perm[AA] % 12], xf, yf, zf), + this.dot(this.grad3[this.perm[BA] % 12], xf - 1, yf, zf), + u + ); + const lerp2 = this.mix( + this.dot(this.grad3[this.perm[AB] % 12], xf, yf - 1, zf), + this.dot(this.grad3[this.perm[BB] % 12], xf - 1, yf - 1, zf), + u + ); + const lerp3 = this.mix( + this.dot(this.grad3[this.perm[AA + 1] % 12], xf, yf, zf - 1), + this.dot(this.grad3[this.perm[BA + 1] % 12], xf - 1, yf, zf - 1), + u + ); + const lerp4 = this.mix( + this.dot(this.grad3[this.perm[AB + 1] % 12], xf, yf - 1, zf - 1), + this.dot(this.grad3[this.perm[BB + 1] % 12], xf - 1, yf - 1, zf - 1), + u + ); + + const mix1 = this.mix(lerp1, lerp2, v); + const mix2 = this.mix(lerp3, lerp4, v); + + total += this.mix(mix1, mix2, w) * amplitude; + + maxAmplitude += amplitude; + amplitude *= this.falloff; + frequency *= 2; + } + + return total / maxAmplitude; + } +}; + +Q5.P5PerlinNoise = class extends Q5.Noise { constructor(seed) { super(); this.YWRAPB = 4; @@ -376,95 +502,3 @@ Q5.P5Noise = class extends Q5.Noise { return r; } }; - -Q5.PerlinNoise = class extends Q5.Noise { - constructor(seed) { - super(); - 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.octaves = 4; - this.falloff = 0.25; - this.p = Array.from({ length: 256 }, () => Math.floor(Math.random() * 256)); - if (seed !== undefined) { - this.p = this.seedPermutation(seed); - } - this.perm = Array.from({ length: 512 }, (_, i) => this.p[i & 255]); - } - - seedPermutation(seed) { - let p = []; - for (let i = 0; i < 256; i++) { - p[i] = i; - } - - let n, q; - for (let i = 255; i > 0; i--) { - seed = (seed * 16807) % 2147483647; - n = (seed % (i + 1)); - q = p[i]; - p[i] = p[n]; - p[n] = q; - } - - return p; - } - - dot(g, x, y, z) { - return g[0] * x + g[1] * y + g[2] * z; - } - - mix(a, b, t) { - return (1 - t) * a + t * b; - } - - fade(t) { - return t * t * t * (t * (t * 6 - 15) + 10); - } - - noise(x, y, z) { - let total = 0; - let frequency = 1; - let amplitude = 1; - let maxAmplitude = 0; - - for (let i = 0; i < this.octaves; i++) { - const X = Math.floor(x * frequency) & 255; - const Y = Math.floor(y * frequency) & 255; - const Z = Math.floor(z * frequency) & 255; - - const xf = x * frequency - Math.floor(x * frequency); - const yf = y * frequency - Math.floor(y * frequency); - const zf = z * frequency - Math.floor(z * frequency); - - const u = this.fade(xf); - const v = this.fade(yf); - const w = this.fade(zf); - - const A = this.perm[X] + Y; - const AA = this.perm[A] + Z; - const AB = this.perm[A + 1] + Z; - const B = this.perm[X + 1] + Y; - const BA = this.perm[B] + Z; - const BB = this.perm[B + 1] + Z; - - const lerp1 = this.mix(this.dot(this.grad3[this.perm[AA] % 12], xf, yf, zf), this.dot(this.grad3[this.perm[BA] % 12], xf - 1, yf, zf), u); - const lerp2 = this.mix(this.dot(this.grad3[this.perm[AB] % 12], xf, yf - 1, zf), this.dot(this.grad3[this.perm[BB] % 12], xf - 1, yf - 1, zf), u); - const lerp3 = this.mix(this.dot(this.grad3[this.perm[AA + 1] % 12], xf, yf, zf - 1), this.dot(this.grad3[this.perm[BA + 1] % 12], xf - 1, yf, zf - 1), u); - const lerp4 = this.mix(this.dot(this.grad3[this.perm[AB + 1] % 12], xf, yf - 1, zf - 1), this.dot(this.grad3[this.perm[BB + 1] % 12], xf - 1, yf - 1, zf - 1), u); - - const mix1 = this.mix(lerp1, lerp2, v); - const mix2 = this.mix(lerp3, lerp4, v); - - total += this.mix(mix1, mix2, w) * amplitude; - - maxAmplitude += amplitude; - amplitude *= this.falloff; - frequency *= 2; - } - - return total / maxAmplitude; - } -};