A fork with extra config options.
I lied in a sunbeam, feeling the Sun's hot kiss when, through my closed eyelids, I read its name.
Log in to post a comment.
// Forked from "way wavy way" by ge1doot // https://turtletoy.net/turtle/65cb465053 // You can find the Turtle API reference here: https://turtletoy.net/syntax Canvas.setpenopacity(0.33); const ySpacing = 1.6; //min=0 max=3 step=.1 const octaves = 3; //min=1 max=10 step=1 const seed = 257; //min=1 max=1000 step=1 const xScale = 1; //min=.1 max=5 step=0.1 const yScale = 0.5; //min=.1 max=5 step=0.1 const xOffset = 0; //min=-1000 max=1000 step=1 const yOffset = -54; //min=-1000 max=1000 step=1 const lineCount = 282; //min=1 max=1000 step=1 /* Seedrandom function from https://github.com/davidbau/seedrandom/blob/released/seedrandom.js Copyright 2019 David Bau. See source for complete copyright information. The source has been modified slightly from the original to make it shorter. */ (function (global, pool, math) { var width = 256, // each RC4 output is 0 <= x < 256 chunks = 6, // at least six RC4 outputs for each double digits = 52, // there are 52 significant digits in a double rngname = 'random', // rngname: name for Math.random and Math.seedrandom startdenom = math.pow(width, chunks), significance = math.pow(2, digits), overflow = significance * 2, mask = width - 1 function seedrandom(seed, options, callback) { var key = []; options = (options == true) ? { entropy: true } : (options || {}); var shortseed = mixkey(flatten( options.entropy ? [seed, tostring(pool)] : (seed == null) ? autoseed() : seed, 3), key); var arc4 = new ARC4(key); var prng = function() { var n = arc4.g(chunks), d = startdenom, x = 0; while (n < significance) { n = (n + x) * width; d *= width; x = arc4.g(1); } while (n >= overflow) { n /= 2; d /= 2; x >>>= 1; } return (n + x) / d; }; prng.int32 = function() { return arc4.g(4) | 0; } prng.quick = function() { return arc4.g(4) / 0x100000000; } prng.double = prng; mixkey(tostring(arc4.S), pool); return (options.pass || callback || function(prng, seed, is_math_call, state) { if (state) { if (state.S) { copy(state, arc4); } prng.state = function() { return copy(arc4, {}); } } if (is_math_call) { math[rngname] = prng; return seed; } else return prng; })( prng, shortseed, 'global' in options ? options.global : (this == math), options.state); } function ARC4(key) { var t, keylen = key.length, me = this, i = 0, j = me.i = me.j = 0, s = me.S = []; if (!keylen) { key = [keylen++]; } while (i < width) { s[i] = i++; } for (i = 0; i < width; i++) { s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))]; s[j] = t; } (me.g = function(count) { var t, r = 0, i = me.i, j = me.j, s = me.S; while (count--) { t = s[i = mask & (i + 1)]; r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))]; } me.i = i; me.j = j; return r; })(width); } function copy(f, t) { t.i = f.i; t.j = f.j; t.S = f.S.slice(); return t; }; function flatten(obj, depth) { var result = [], typ = (typeof obj), prop; if (depth && typ == 'object') { for (prop in obj) { try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {} } } return (result.length ? result : typ == 'string' ? obj : obj + '\0'); } function mixkey(seed, key) { var stringseed = seed + '', smear, j = 0; while (j < stringseed.length) { key[mask & j] = mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++)); } return tostring(key); } function autoseed() { try { var out; out = new Uint8Array(width); (global.crypto || global.msCrypto).getRandomValues(out); return tostring(out); } catch (e) { var browser = global.navigator, plugins = browser && browser.plugins; return [+new Date, global, plugins, global.screen, tostring(pool)]; } } function tostring(a) {return String.fromCharCode.apply(0, a);} mixkey(math.random(), pool); math['seed' + rngname] = seedrandom; })((typeof self !== 'undefined') ? self : this,[],Math); const turtle = new Turtle(); class Noise { // http://mrl.nyu.edu/~perlin/noise/ constructor(octaves = 1) { this.p = new Uint8Array(512); this.octaves = octaves; var rng = new Math.seedrandom(seed) for (let i = 0; i < 512; ++i) { this.p[i] = rng() * 256; } } lerp(t, a, b) { return a + t * (b - a); } grad2d(i, x, y) { const v = (i & 1) === 0 ? x : y; return (i & 2) === 0 ? -v : v; } noise2d(x2d, y2d) { const X = Math.floor(x2d) & 255; const Y = Math.floor(y2d) & 255; const x = x2d - Math.floor(x2d); const y = y2d - Math.floor(y2d); const fx = (3 - 2 * x) * x * x; const fy = (3 - 2 * y) * y * y; const p0 = this.p[X] + Y; const p1 = this.p[X + 1] + Y; return this.lerp( fy, this.lerp( fx, this.grad2d(this.p[p0], x, y), this.grad2d(this.p[p1], x - 1, y) ), this.lerp( fx, this.grad2d(this.p[p0 + 1], x, y - 1), this.grad2d(this.p[p1 + 1], x - 1, y - 1) ) ); } noise(x, y) { let e = 1, k = 1, s = 0; for (let i = 0; i < this.octaves; ++i) { e *= 0.5; s += e * (1 + this.noise2d(k * x, k * y)) / 2; k *= 2; } return s; } } const perlin = new Noise(octaves); turtle.up(); function walk(i) { for (let j = -100; j < 101; j++) { const h = perlin.noise(100 + j * 0.01, 100 + i * 0.01); turtle.goto(xOffset + j * xScale, yOffset + yScale * ySpacing * i + yScale * h * 200 - 100); turtle.down(); } turtle.up(); return i < lineCount; }