diff --git a/index.html b/index.html new file mode 100644 index 0000000..6d8a241 --- /dev/null +++ b/index.html @@ -0,0 +1,15 @@ + + + + + + + HTML Template + + + + + + + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..69ea160 --- /dev/null +++ b/script.js @@ -0,0 +1,122 @@ +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("points:"); + console.log(this.points); + } + + #init() { + this.points = []; + + 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)]; + + for(let i = 0; i < this.#NUM_POINTS; i++) { + this.points[i] = this.#perlin1D(this.persist, this.octave, 0.1 * i); + } + + } + + #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); + amp = Math.pow(persist, i); + total += this.#interpolateNoise(x * freq) * amp; + } + + return total; + } + + /* + * #interpolateNoise - performs a successive smoothing function on + * the input value. + * ARGUMENT: + * x: float value to be smoothed. + */ + #interpolateNoise(x) { + let intX = Math.floor(x); + let fractionX = x - intX; + + let v1 = this.#smoothedNoise(intX); + let v2 = this.#smoothedNoise(intX + 1); + + 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); + let f = (1 - Math.cos(ft)) * 0.5; + + 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) { + let z = (x << 13) ^ x; + + let y = (1.0 - (( z * (z * z * this.p5d + this.p6d) + this.p10d) + & 0x7fffffff ) / 1073741824.0); + return y; + } + + } + + let perlin1 = new Perlin(0.3, 4); + let perlin2 = new Perlin(0.3, 0.4); + +}); + diff --git a/style.css b/style.css new file mode 100644 index 0000000..e7173d3 --- /dev/null +++ b/style.css @@ -0,0 +1,16 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +#canvas1 { + border: 5px solid black; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: #4d79bc; + max-width: 80%; + max-height: 100%; +} \ No newline at end of file