From 6a374ac226228cc64981f4cb7a3ed3f105f36361 Mon Sep 17 00:00:00 2001 From: Jonas Wagner Date: Sun, 10 Jul 2022 12:23:48 +0200 Subject: [PATCH] rename noiseFunctionND to createNoiseND, docs --- README.md | 69 +++++++++++++-- alea.md | 19 ---- simplex-noise.ts | 6 +- test/module-compatibility/commonjs.js | 6 +- test/module-compatibility/esm.mjs | 4 +- test/simplex-noise-test.ts | 26 +++--- test/visual.ts | 123 ++++++++++++++------------ 7 files changed, 147 insertions(+), 106 deletions(-) delete mode 100644 alea.md diff --git a/README.md b/README.md index ad2cf39..d6be6d4 100644 --- a/README.md +++ b/README.md @@ -28,35 +28,35 @@ Created something awesome with simplex-noise? Let me know so I can add it to the ```javascript // import the noise functions you need -import { noiseFunction2D } from 'simplex-noise'; +import { createNoise2D } from 'simplex-noise'; ``` ### CommonJS Require ```javascript // import the noise functions you need -const { noiseFunction2D } = require('simplex-noise'); +const { createNoise2D } = require('simplex-noise'); ``` ### 2D ```javascript // initialize the noise function -const noise2D = noiseFunction2D(); +const noise2D = createNoise2D(); console.log(noise2D(x, y)); ``` ### 3D ```javascript -const noise3D = noiseFunction3D(); +const noise3D = createNoise3D(); console.log(noise3D(x, y, z)); ``` ### 4D ```javascript -const noise4D = noiseFunction4D(); +const noise4D = createNoise4D(); console.log(noise4D(x, y, z, w)); ``` @@ -65,10 +65,15 @@ console.log(noise4D(x, y, z, w)); By default simplex-noise.js will use Math.random() to seed the noise. You can pass in a PRNG function to use your own seed value. +```bash +# install the alea prng +npm install -S alea +``` + ```javascript import Alea from 'alea'; // create a new random function based on the seed -const alea = new Alea('seed'); +const alea = Alea('seed'); // use the seeded random function to initialize the noise function const noise2D = noiseFunction2D(alea); console.log(noise2D(x, y)); @@ -107,8 +112,58 @@ There are some simple unit tests for this library to run them npm install && npm test ``` +## Migrating from 3.x to 4.x + +### random initialization +```javascript +// 3.x +import SimplexNoise from 'simplex-noise'; +const simplex = new SimplexNoise(); +const value2d = simplex.noise2D(x, y); +// 4.x +// import the functions you need +import { createNoise2D } from 'simplex-noise'; +const noise2D = createNoise2D(); +const value2d = noise2D(x, y); +``` + +### Initialization with a seed +```javascript +// 3.x +import SimplexNoise from 'simplex-noise'; +const simplex = new SimplexNoise('seed'); +const value2d = simplex.noise2D(x, y); +// 4.x +// npm install -S alea +import { createNoise2D } from 'simplex-noise'; +import Alea from 'alea'; +const noise2D = createNoise2D(Alea('seed')); +const value2d = noise2D(x, y); + +// IMPORTANT: If you use multiple noise functions (for example 2d and 3d) +// and want compatible output with 3.x you will need to pass a fresh instance +// of alea to each create call. If you reuse the alea instance you will +// get different outputs compared to simplex-noise 3.x. +const seed = 'seed'; +const noise2D = createNoise2D(Alea(seed)); +const noise3D = createNoise3D(Alea(seed)); +``` + +### Emulating the 3.x and older API +```javascript +const simplex = { + noise2D: createNoise2D(Alea(seed)), + noise3D: createNoise3D(Alea(seed)), + noise4D: createNoise4D(Alea(seed)), +}; +``` + ## Changelog +### 4.0.0 +- Reworked the API so you can import the noise functions individually. + When combined with tree-shaking this helps with build sizes. + ### 3.0.1 - Include simplex-noise.ts as source file, fixes sourcemap warnings. @@ -159,7 +214,7 @@ you will need to use a polyfill like [typedarray.js](http://www.calormen.com/pol ## License -Copyright (c) 2021 Jonas Wagner, licensed under the MIT License (enclosed) +Copyright (c) 2022 Jonas Wagner, licensed under the MIT License (enclosed) ## Credits This is mostly a direct javascript port of the [Java implementation](http://webstaff.itn.liu.se/~stegu/simplexnoise/SimplexNoise.java) diff --git a/alea.md b/alea.md deleted file mode 100644 index b20988c..0000000 --- a/alea.md +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2010 by Johannes Baagøe - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/simplex-noise.ts b/simplex-noise.ts index 7ffce8e..a6be806 100644 --- a/simplex-noise.ts +++ b/simplex-noise.ts @@ -77,7 +77,7 @@ export type NoiseFunction2D = (x: number, y: number) => number; * @param random the random function that will be used to build the permutation table * @returns {NoiseFunction2D} */ -export function noiseFunction2D(random: RandomFn = Math.random): NoiseFunction2D { +export function createNoise2D(random: RandomFn = Math.random): NoiseFunction2D { const perm = buildPermutationTable(random); const permMod12 = perm.map(v => v % 12); return function noise2D(x: number, y: number): number { @@ -153,7 +153,7 @@ export type NoiseFunction3D = (x: number, y: number, z: number) => number; * @param random the random function that will be used to build the permutation table * @returns {NoiseFunction3D} */ -export function noiseFunction3D(random: RandomFn = Math.random): NoiseFunction3D { +export function createNoise3D(random: RandomFn = Math.random): NoiseFunction3D { const perm = buildPermutationTable(random); const permMod12 = perm.map(v => v % 12); @@ -294,7 +294,7 @@ export type NoiseFunction4D = (x: number, y: number, z: number, w: number) => nu * @param random the random function that will be used to build the permutation table * @returns {NoiseFunction3D} */ -export function noiseFunction4D(random: RandomFn = Math.random) { +export function createNoise4D(random: RandomFn = Math.random) { const perm = buildPermutationTable(random); return function noise4D(x: number, y: number, z: number, w: number): number { let n0, n1, n2, n3, n4; // Noise contributions from the five corners diff --git a/test/module-compatibility/commonjs.js b/test/module-compatibility/commonjs.js index e677c46..8ad0db2 100644 --- a/test/module-compatibility/commonjs.js +++ b/test/module-compatibility/commonjs.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const noiseFunction2D = require('simplex-noise').noiseFunction2D; +/* eslint-disable @typescript-eslint/no-var-requires */ +const createNoise2D = require('simplex-noise').createNoise2D; console.log(require('simplex-noise')); -console.log(noiseFunction2D()(1, 2)); \ No newline at end of file +console.log(createNoise2D()(1, 2)); \ No newline at end of file diff --git a/test/module-compatibility/esm.mjs b/test/module-compatibility/esm.mjs index 80768cc..f6043a0 100644 --- a/test/module-compatibility/esm.mjs +++ b/test/module-compatibility/esm.mjs @@ -1,2 +1,2 @@ -import {noiseFunction2D} from 'simplex-noise'; -console.log(noiseFunction2D()(1, 2)); \ No newline at end of file +import {createNoise2D} from 'simplex-noise'; +console.log(createNoise2D()(1, 2)); \ No newline at end of file diff --git a/test/simplex-noise-test.ts b/test/simplex-noise-test.ts index 05ca1f0..a3c230f 100644 --- a/test/simplex-noise-test.ts +++ b/test/simplex-noise-test.ts @@ -1,4 +1,4 @@ -import { noiseFunction2D, noiseFunction3D, noiseFunction4D } from '../simplex-noise'; +import { createNoise2D, createNoise3D, createNoise4D } from '../simplex-noise'; import { buildPermutationTable } from '../simplex-noise'; import alea from 'alea'; import { assert } from 'chai'; @@ -38,8 +38,8 @@ describe('buildPermutationTable', function () { }); }); -describe('noiseFunction2D', () => { - const noise2D = noiseFunction2D(getRandom()); +describe('createNoise2D', () => { + const noise2D = createNoise2D(getRandom()); describe('noise2D', () => { it('should return the same value for the same input', function () { assert.equal(noise2D(0.1, 0.2), noise2D(0.1, 0.2)); @@ -48,11 +48,11 @@ describe('noiseFunction2D', () => { assert.notEqual(noise2D(0.1, 0.2), noise2D(0.101, 0.202)); }); it('should return the same output with the same seed', function () { - const noise2D2 = noiseFunction2D(getRandom()); + const noise2D2 = createNoise2D(getRandom()); assert.equal(noise2D(0.1, 0.2), noise2D2(0.1, 0.2)); }); it('should return a different output with a different seed', function () { - const noise2D2 = noiseFunction2D(getRandom('other seed')); + const noise2D2 = createNoise2D(getRandom('other seed')); assert.notEqual(noise2D(0.1, 0.2), noise2D2(0.1, 0.2)); }); it('should return values between -1 and 1', function () { @@ -73,8 +73,8 @@ describe('noiseFunction2D', () => { }); }); -describe('noiseFunction3D', () => { - const noise3D = noiseFunction3D(getRandom()); +describe('createNoise3D', () => { + const noise3D = createNoise3D(getRandom()); describe('noise3D', () => { it('should return the same value for the same input', function () { assert.equal(noise3D(0.1, 0.2, 0.3), noise3D(0.1, 0.2, 0.3)); @@ -83,11 +83,11 @@ describe('noiseFunction3D', () => { assert.notEqual(noise3D(0.1, 0.2, 0.3), noise3D(0.101, 0.202, 0.303)); }); it('should return the same output with the same seed', function () { - const noise3D2 = noiseFunction3D(getRandom()); + const noise3D2 = createNoise3D(getRandom()); assert.equal(noise3D(0.1, 0.2, 0.3), noise3D2(0.1, 0.2, 0.3)); }); it('should return a different output with a different seed', function () { - const noise3D2 = noiseFunction3D(getRandom('other seed')); + const noise3D2 = createNoise3D(getRandom('other seed')); assert.notEqual(noise3D(0.1, 0.2, 0.3), noise3D2(0.1, 0.2, 0.3)); }); it('should return values between -1 and 1', function () { @@ -108,8 +108,8 @@ describe('noiseFunction3D', () => { }); }); -describe('noiseFunction4D', () => { - const noise4D = noiseFunction4D(getRandom()); +describe('createNoise4D', () => { + const noise4D = createNoise4D(getRandom()); describe('noise4D', () => { it('should return the same value for the same input', function () { assert.equal(noise4D(0.1, 0.2, 0.3, 0.4), noise4D(0.1, 0.2, 0.3, 0.4)); @@ -118,11 +118,11 @@ describe('noiseFunction4D', () => { assert.notEqual(noise4D(0.1, 0.2, 0.3, 0.4), noise4D(0.101, 0.202, 0.303, 0.404)); }); it('should return the same output with the same seed', function () { - const noise4D2 = noiseFunction4D(getRandom()); + const noise4D2 = createNoise4D(getRandom()); assert.equal(noise4D(0.1, 0.2, 0.3, 0.4), noise4D2(0.1, 0.2, 0.3, 0.4)); }); it('should return a different output with a different seed', function () { - const noise4D2 = noiseFunction4D(getRandom('other seed')); + const noise4D2 = createNoise4D(getRandom('other seed')); assert.notEqual(noise4D(0.1, 0.2, 0.3, 0.4), noise4D2(0.1, 0.2, 0.3, 0.4)); }); it('should return values between -1 and 1', function () { diff --git a/test/visual.ts b/test/visual.ts index e58d7d4..a662a89 100644 --- a/test/visual.ts +++ b/test/visual.ts @@ -1,67 +1,72 @@ - import SimplexNoise from '../simplex-noise'; - - function visualize(title, fn) { - var canvas = document.createElement('canvas'); - var s = 512; - canvas.width = s; - canvas.height = s; - var ctx = canvas.getContext('2d'); - var imageData = ctx.getImageData(0, 0, s, s); - for (var i = 0; i < imageData.data.length; i++) { - var x = (fn(i % 512, ~~(i / 512)) + 1) * 128; - imageData.data[i * 4] = x; - imageData.data[i * 4 + 1] = x; - imageData.data[i * 4 + 2] = x; - imageData.data[i * 4 + 3] = 255; - } - ctx.putImageData(imageData, 0, 0); - var h2 = document.createElement('h2'); - h2.innerHTML = title; - document.body.appendChild(h2); - document.body.appendChild(canvas); - } +import { createNoise2D, createNoise3D, createNoise4D } from '../simplex-noise'; +import Alea from 'alea'; - var simplex = new SimplexNoise(); - visualize('noise2D x1', function (x, y) { - return simplex.noise2D(x, y); - }); - visualize('noise2D x20', function (x, y) { - return simplex.noise2D(x / 20, y / 20); - }); +const noise2D = createNoise2D(); +const noise3D = createNoise3D(); +const noise4D = createNoise4D(); - visualize('noise2D x256', function (x, y) { - return simplex.noise2D(x / 256, y / 256); - }); +function visualize(title, fn) { + const canvas = document.createElement('canvas'); + const s = 512; + canvas.width = s; + canvas.height = s; + const ctx = canvas.getContext('2d'); + if (ctx == null) throw new Error('Canvas 2d not supported'); + const imageData = ctx.getImageData(0, 0, s, s); + for (let i = 0; i < imageData.data.length; i++) { + const x = (fn(i % 512, ~~(i / 512)) + 1) * 128; + imageData.data[i * 4] = x; + imageData.data[i * 4 + 1] = x; + imageData.data[i * 4 + 2] = x; + imageData.data[i * 4 + 3] = 255; + } + ctx.putImageData(imageData, 0, 0); + const h2 = document.createElement('h2'); + h2.innerHTML = title; + document.body.appendChild(h2); + document.body.appendChild(canvas); +} - visualize('noise3D z0 x256', function (x, y) { - return simplex.noise3D(x / 256, y / 256, 0); - }); +visualize('noise2D x1', function (x, y) { + return noise2D(x, y); +}); +visualize('noise2D x20', function (x, y) { + return noise2D(x / 20, y / 20); +}); - visualize('noise3D z0 x20', function (x, y) { - return simplex.noise3D(x / 20, y / 20, 0); - }); +visualize('noise2D x256', function (x, y) { + return noise2D(x / 256, y / 256); +}); - visualize('noise3D z0.01 x20', function (x, y) { - return simplex.noise3D(x / 20, y / 20, 0.01); - }); +visualize('noise3D z0 x256', function (x, y) { + return noise3D(x / 256, y / 256, 0); +}); - visualize('noise3D z1 x20', function (x, y) { - return simplex.noise3D(x / 20, y / 20, 1); - }); +visualize('noise3D z0 x20', function (x, y) { + return noise3D(x / 20, y / 20, 0); +}); - visualize('noise4D z1 w1 x20', function (x, y) { - return simplex.noise4D(x / 20, y / 20, 1, 1); - }); +visualize('noise3D z0.01 x20', function (x, y) { + return noise3D(x / 20, y / 20, 0.01); +}); - simplex = new SimplexNoise('seed'); - visualize('seed noise2D', function (x, y) { - return simplex.noise2D(x / 20, y / 20); - }); - simplex = new SimplexNoise('seed'); - visualize('same seed noise2D', function (x, y) { - return simplex.noise2D(x / 20, y / 20); - }); - simplex = new SimplexNoise('different seed'); - visualize('different seed noise2D', function (x, y) { - return simplex.noise2D(x / 20, y / 20); - }); \ No newline at end of file +visualize('noise3D z1 x20', function (x, y) { + return noise3D(x / 20, y / 20, 1); +}); + +visualize('noise4D z1 w1 x20', function (x, y) { + return noise4D(x / 20, y / 20, 1, 1); +}); + +const seededNoise2D = createNoise2D(Alea('seed')); +visualize('seed noise2D', function (x, y) { + return seededNoise2D(x / 20, y / 20); +}); +const sameNoise2D = createNoise2D(Alea('seed')); +visualize('same seed noise2D', function (x, y) { + return sameNoise2D(x / 20, y / 20); +}); +const differentNoise2D = createNoise2D(Alea('different seed')); +visualize('different seed noise2D', function (x, y) { + return differentNoise2D(x / 20, y / 20); +}); \ No newline at end of file