Using Perlin noise to create geometry similar to the dragon curve
en.wikipedia.org/wiki/dragon_curve
en.wikipedia.org/wiki/perlin_noise
Log in to post a comment.
// You can find the Turtle API reference here: https://turtletoy.net/syntax Canvas.setpenopacity(1); // Global code will be evaluated once. const turtles = []; let seed = 1000; // min=1 max=1000000 step=1 const bits = 20; const samples = 150000; const mod = 1<<bits; const turtles_count = 700; // min = 1 max = 1000 step = 1 const steps = 250; // min = 1 max = 1000 step = 1 const spawn_range = 70; // min = 0 max = 100 step = 1 const perlin_const = 10; // min = 1 max = 20 step = 1 const line_orientation = 0; //min=0 max=1 step=1 (Rectangular, Random) for(let i = turtles_count; i > 0; i--) { let turtle = new Turtle; turtle.penup(); if(line_orientation == 1) { turtle.setheading(random() * 360); } r = random() * spawn_range; theta = random() * 2 * Math.PI; turtle.setx(r * Math.cos(theta)); turtle.sety(r * Math.sin(theta)); turtle.pendown(); turtles.push(turtle); } //////////////////////////////////////////////////////////////// // Pseudorandom number generator. Created by Reinder Nijhoff 2024 // https://turtletoy.net/turtle/a2274fd1fe //////////////////////////////////////////////////////////////// function random() { // returns a number [0, 1[ let r = 1103515245 * (((seed+=12345) >> 1) ^ seed); r = 1103515245 * (r ^ (r >> 3)); r = r ^ (r >> 16); return (r % mod) / mod; } //////////////////////////////////////////////////////////////// // Perlin noise field generator. Taken from turtle below // https://turtletoy.net/turtle/04036becc3 //////////////////////////////////////////////////////////////// class Perlin { constructor(size, gridSize) { this.size = size; this.gridSize = gridSize; this.grid = []; for (let i = 0; i <= gridSize; i++) { let table = []; for (let j = 0; j <= gridSize; j++) { let angle = random() * 2 * Math.PI; let x = Math.cos(angle); let y = Math.sin(angle); table.push([x, y]); } this.grid.push(table); } } get(x, y) { x = x / 2 + this.size / 2; y = y / 2 + this.size / 2; if (x < 0) x = 0; if (x >= this.size) x = this.size - 0.01; if (y < 0) y = 0; if (y >= this.size) y = this.size - 0.01; let posx = x * this.gridSize / this.size; let posy = y * this.gridSize / this.size; let x1 = Math.floor(posx); let x2 = x1 + 1; let y1 = Math.floor(posy); let y2 = y1 + 1; let scal = []; scal.push(this.scalar(posx, posy, x1, y1)); scal.push(this.scalar(posx, posy, x2, y1)); scal.push(this.scalar(posx, posy, x1, y2)); scal.push(this.scalar(posx, posy, x2, y2)); let int1 = this.interpolate(posx - x1, scal[0], scal[1]); let int2 = this.interpolate(posx - x1, scal[2], scal[3]); return this.interpolate(posy - y1, int1, int2); } scalar(x, y, vx, vy) { x -= vx; y -= vy; return x * this.grid[vx][vy][0] + y * this.grid[vx][vy][1]; } smooth(v) { if (v < 0) v = 0; if (v > 1) v = 1; return v ** 2 * (3 - 2 * v); } interpolate(x, a, b) { return a + (b - a) * this.smooth(x); } } let perlin_angle = new Perlin(100, perlin_const); // The walk function will be called until it returns false. function walk(i) { for(let j = turtles_count-1; j > 0; j--) { turtles[j].forward(1); current_perlin = perlin_angle.get(turtles[j].x(),turtles[j].y()); let right = 0; if(current_perlin < -0.5) { right = 180; } else if(current_perlin < 0) { right = 90; } else if(current_perlin < 0.5) { right = 0; } else{ right = 270; } turtles[j].right(right); } return i < steps; }