noise

A bit of algorithmic 'art' from 1967. I was working as a vac job for IBM at the Technical University of Denmark in Lyngby, writing a package for the Calcomp plotter. I was asked to prepare a drawing of a super-egg for Piet Hein who had recently popularized the super-egg in a design for a Swedish roundabout. The idea was that a superegg has less sharp ends for cars than those seen in an elliptical roundabout. I liked the idea, but not that it was not continuously differentiable at the points; so I came up with an alternative based on the principle of a driver turning the steering wheel in a regular sine wave. The resulting curve is related to Lissajous figures and hypoid curves, but different. With parameters taken outside the original elongated roundabout it gives nice patterns. The fiddle above is rather more interactive than the 1 day turnaround (if lucky) that I had on runs with the plotter.

by sjpt

HTML

<!DOCTYPE html><html lang="en"><body>
<p>
Test of noise curves by smoothing/integrating fully random noise. Mainly intended for form distortion, adding the audio bits was just general interest/sonification.
</p>
smoothk: <input type="range" min="0" max="1" step="0.01" id="_smoothk" oninput="smoothk=+this.value; draw();">
smoothk2: <input type="range" min="0" max="1" step="0.01" id="_smoothk2" oninput="smoothk2=+this.value; draw();">
smoothn: <input type="range" min="0" max="8"  step="0.01" id="_smoothn" oninput="smoothn=+this.value; draw();">
n: <input type="number" min="2" max="48000"  step="1" id="_n" oninput="n=+this.value; rerand();">
<br>
<!--- vel: <input type="range" min="0" max="500" id="_v" oninput="v=+this.value; draw();"> --->
<button onclick="rerand()">rerand</button>
<button onclick="testk1n1()">testk1n1</button>
<button onclick="testk05n2()">testk0.5n2</button>
draw: <input type="checkbox" id="dodraw" checked="checked" onchange="draw()"/>
drawflat: <input type="number" min="0" max="1" step="0.1" id="_drawflat" oninput="drawflat=+this.value; draw()">
showall: <input type="checkbox" id="showall" onchange="draw()"/>
<button onclick="debugger">debug</button>
<br>
audio: <input type="checkbox" id="doaudio" onchange="audio()"/>
freq: <input type="number" min="0" max="256" step="0.1" id="_freq" oninput="freq=+this.value; audio()">
gain: <input type="number" min="0" max="1" step="0.1" id="_gainv" oninput="gainv=+this.value; audio()"">
useosc: <input type="checkbox" id="useosc" onchange="audio()"/>


<p id="msg"></p>

<canvas id="canvas" style="background: black"></canvas>
</body></html>

JavaScript

var       // must be var so o is same as window.o
smoothk = 1,       // smoothing
smoothk2 = 1,       // smoothing
smoothn = 1,  // #smooth steps
n = 128     // number of segments
freq = 1
gainv = 0.1
drawflat = 1

var keys = Array.from(document.getElementsByTagName('input')).filter(x=>x.id[0] === '_').map(x=>x.id.substring(1))
function setsliders() {
	for (const x of keys) window['_' + x].value = ''+window[x];
}

function smooth(a, k = smoothk, k2 = smoothk2) {
	// '3' set experimentally to make smoothk behaviour smooth, 
    // not sure if approriate maths woudl give a 'theoretical' good value
    // The smooth is specially noticable with fractional k used near integer values of smoothn
    // Also, k**1/3 gives very close values in the testk1n1 and testk0.5n2 experiment.
    k = k**1/3;   
	const r = new Float32Array(n);
    r[0] = 0
    for (let i=1; i < n; i++)
    	r[i] = k * r[i-1] + k2 * a[i]
    return r;
}

var normv = '?'
/** normalize */
function norm(a) {
	normv = a.reduce((c,v) => Math.max(c, Math.abs(v)), 0)
    return a.map(x => x/normv)
}

/** flatten */
function flatten(a) {
	const d = a[n-1] - a[0]
    return a.map((x, i) => x - d*i/n)
}

setsliders();
const {cos, sin, min, max, ceil, random} = Math;
onresize = draw;
var r1, r2
function rerand() { r1 = new Float32Array(n).map(_ => random()*2-1); draw(); }
rerand()
function draw() {
	for (const x of keys) window[x] = +window['_' + x].value;
    const canvas = document.querySelector('#canvas');
    const w = canvas.width = innerWidth; const h = canvas.height = innerHeight * 0.6
    const ctx = canvas.getContext('2d');
    if (!ctx) return;
    ctx.clearRect(0,0,9999,9999);
    ctx.setTransform(w/n,0, 0, h/2, 0, h/2)
    ctx.lineWidth = n/w * 0.02;
    // set line stroke and line width
    const styles = ['red', 'green', 'yellow', 'blue', 'purple'];
    r2 = r1;
    draw1(r1, smoothn === 0 ? -1 : 0);
    for (let t = 1; t <= ceil(smoothn); t++) {
        const sk = smoothk * (t > smoothn ?...