window.addEventListener('load', function() { const canvas = this.document.getElementById('canvas1'); const ctx = canvas.getContext('2d'); canvas.width = 1500; canvas.height = 500; class Perlin { // number of points to generate #NUM_POINTS = 101; // number of prime numbers in each array #NUM_PRIMES = 5; #PRIME5 = [ 15731, 16069, 17579, 31963, 22453]; #PRIME6 = [ 789221, 790289, 811081, 211777, 566173]; #PRIME10 = [1376312589, 1480028201, 1500450271, 1000075057, 1023465798]; constructor(persist, octave) { this.persist = persist; this.octave = octave; this.#init(); console.log("p5d: " + this.p5d); console.log("p6d: " + this.p6d); console.log("p10d: " + this.p10d); console.log("points:"); console.log(this.points); } #init() { this.points = []; for(let i = 0; i < this.#NUM_POINTS; i++) { this.points[i] = this.#perlin1D(this.persist, this.octave, 0.1 * i); } this.p5d = this.#PRIME5[Math.floor(Math.random() * 5)]; this.p6d = this.#PRIME6[Math.floor(Math.random() * 5)]; this.p10d = this.#PRIME10[Math.floor(Math.random() * 5)]; } #perlin1D(persist, octave, x) { let total = 0.0; let freq = 0.0; let amp = 0.0; for(let i = 0; i < octave; i++) { freq = Math.pow(2,i); console.log("freq: " + freq); amp = Math.pow(persist, i); console.log("amp: " + amp); total += this.#interpolateNoise(x * freq) * amp; console.log("total: " + total); } return total; } /* * #interpolateNoise - performs a successive smoothing function on * the input value. * ARGUMENT: * x: float value to be smoothed. */ #interpolateNoise(x) { console.log("interpolateNoise: " + x); let intX = Math.floor(x); console.log("intX: " + intX); let fractionX = x - intX; console.log("fractionX: " + fractionX); let v1 = this.#smoothedNoise(intX); console.log("v1: " + v1); let v2 = this.#smoothedNoise(intX + 1); console.log("v2: " + v2); return this.#cosineInterpolation(v1, v2, fractionX); } /* * #smoothedNoise - smooths the output to make it look less random * * ARGUMENTS: * x: integer value to be smoothed. It is done by averaging between * the points before and after the given point. * * RETURNS: * a float value that has been "smoothed". */ #smoothedNoise(x) { return (this.#findNoise(x) /2) + (this.#findNoise(x - 1) / 4) + (this.#findNoise(x+1)/4); } #cosineInterpolation(a, b, x) { let ft = (x * Math.PI); console.log("ft: " + ft); let f = (1 - Math.cos(ft)) * 0.5; console.log("f: " + f); console.log("#cosineInterp: " + (a * (1 - f) + (b * f))); return a * (1 - f) + (b * f); } /* * findNoise - Random number generator. Unlike other RNG this method * will return the same number for the same input. * * ARGUMENTS: * x: an integer value * * RETURNS: * returns a floating point number between -1.0 and 1.0. * * NOTE: * original return value as published on * http://freespace.virgin.net/hugo.elias/models/m_perlin.htm */ #findNoise(x) { console.log("findNoise: " + x); let z = (x << 13) ^ x; console.log("z: " + z); let y = 1.0 - ( z * (z * z * this.p5d + this.p6d) + this.p10d); console.log("y: " + y); return y; } } let perlin1 = new Perlin(0.3, 4); //let perlin2 = new Perlin(0.3, 0.4); });