//////////////////////////////////////////////////////////////
// http://mrl.nyu.edu/~perlin/noise/
// Adapting from PApplet.java
// which was adapted from toxi
// which was adapted from the german demo group farbrausch
// as used in their demo "art": http://www.farb-rausch.de/fr010src.zip
// someday we might consider using "improved noise"
// http://mrl.nyu.edu/~perlin/paper445.pdf
// See: https://github.com/shiffman/The-Nature-of-Code-Examples-p5.js/
// blob/master/introduction/Noise1D/noise.js
/**
* @module Math
* @submodule Noise
* @for p5
* @requires core
*/
import p5 from '../core/main';
const PERLIN_YWRAPB = 4;
const PERLIN_YWRAP = 1 << PERLIN_YWRAPB;
const PERLIN_ZWRAPB = 8;
const PERLIN_ZWRAP = 1 << PERLIN_ZWRAPB;
const PERLIN_SIZE = 4095;
let perlin_octaves = 4; // default to medium smooth
let perlin_amp_falloff = 0.5; // 50% reduction/octave
const scaled_cosine = i => 0.5 * (1.0 - Math.cos(i * Math.PI));
let perlin; // will be initialized lazily by noise() or noiseSeed()
/**
* Returns the Perlin noise value at specified coordinates. Perlin noise is
* a random sequence generator producing a more natural ordered, harmonic
* succession of numbers compared to the standard random() function.
* It was invented by Ken Perlin in the 1980s and been used since in
* graphical applications to produce procedural textures, natural motion,
* shapes, terrains etc.
The main difference to the
* random() function is that Perlin noise is defined in an infinite
* n-dimensional space where each pair of coordinates corresponds to a
* fixed semi-random value (fixed only for the lifespan of the program; see
* the noiseSeed() function). p5.js can compute 1D, 2D and 3D noise,
* depending on the number of coordinates given. The resulting value will
* always be between 0.0 and 1.0. The noise value can be animated by moving
* through the noise space as demonstrated in the example above. The 2nd
* and 3rd dimension can also be interpreted as time.
The actual
* noise is structured similar to an audio signal, in respect to the
* function's use of frequencies. Similar to the concept of harmonics in
* physics, perlin noise is computed over several octaves which are added
* together for the final result.
Another way to adjust the
* character of the resulting sequence is the scale of the input
* coordinates. As the function works within an infinite space the value of
* the coordinates doesn't matter as such, only the distance between
* successive coordinates does (eg. when using noise() within a
* loop). As a general rule the smaller the difference between coordinates,
* the smoother the resulting noise sequence will be. Steps of 0.005-0.03
* work best for most applications, but this will differ depending on use.
*
*
* @method noise
* @param {Number} x x-coordinate in noise space
* @param {Number} [y] y-coordinate in noise space
* @param {Number} [z] z-coordinate in noise space
* @return {Number} Perlin noise value (between 0 and 1) at specified
* coordinates
* @example
*
* let xoff = 0.0;
*
* function draw() {
* background(204);
* xoff = xoff + 0.01;
* let n = noise(xoff) * width;
* line(n, 0, n, height);
* }
*
* let noiseScale=0.02;
*
* function draw() {
* background(0);
* for (let x=0; x < width; x++) {
* let noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);
* stroke(noiseVal*255);
* line(x, mouseY+noiseVal*80, x, height);
* }
* }
*
*
* let noiseVal;
* let noiseScale = 0.02;
*
* function setup() {
* createCanvas(100, 100);
* }
*
* function draw() {
* background(0);
* for (let y = 0; y < height; y++) {
* for (let x = 0; x < width / 2; x++) {
* noiseDetail(2, 0.2);
* noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale);
* stroke(noiseVal * 255);
* point(x, y);
* noiseDetail(8, 0.65);
* noiseVal = noise(
* (mouseX + x + width / 2) * noiseScale,
* (mouseY + y) * noiseScale
* );
* stroke(noiseVal * 255);
* point(x + width / 2, y);
* }
* }
* }
*
* let xoff = 0.0;
*
* function setup() {
* noiseSeed(99);
* stroke(0, 10);
* }
*
* function draw() {
* xoff = xoff + .01;
* let n = noise(xoff) * width;
* line(n, 0, n, height);
* }
*
*