Based on codepen.io/ge1doot/pen/vymqvp
Log in to post a comment.
// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(0.5);
// Global code will be evaluated once.
const turtle = new Turtle();
turtle.penup();
class Noise {
// http://mrl.nyu.edu/~perlin/noise/
constructor(setup) {
this.p = new Uint8Array(512);
this.octaves = setup.octaves || 1;
const p = new Uint8Array(256);
for (let i = 0; i < 256; i++) p[i] = i;
for (let i = 255; i > 0; i--) {
const n = Math.floor((i + 1) * Math.random());
const q = p[i];
p[i] = p[n];
p[n] = q;
}
for (let i = 0; i < 512; i++) {
this.p[i] = p[i & 255];
}
}
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: 2 });
let y = 100;
const line = Array.from({ length: 200 }, () => 100);
// The walk function will be called until it returns false.
function walk(i) {
y -= 0.3;
turtle.goto(-100, y);
turtle.down();
let v = false;
for (let x = -100; x < 100; x++) {
let z = y + 0.25 * (
(2048 * perlin.noise(x * 0.02, 6 + y * 0.04)) & (16 + 32 + 0 + 128 + 256)
);
if (z > -100) v = true;
if (z > line[x]) z = line[x] - 0.01;
line[x] = z;
turtle.goto(x, z);
}
turtle.up();
return v;
}