Basic recursive tree. Plotter friendly by lifting the pen infrequently.
Log in to post a comment.
// LL 2021 Canvas.setpenopacity(.6); const turtle = new Turtle(); const max_depth = 11; // min=1, max=20, step=1 const split = 2; // min = 1, max = 10, step=1 const turn_factor = 0.69; // min = 0.1, max = 1, step=0.001 const scale = 3.3; // min=1, max=50, step=0.1 const angleInc = 0.62; // min=-3.14, max=3.14, step=0.01 const min_length = 0.1; // min=0.01, max=0.5, step=0.001 const max_length = 1.214; // min=0.01, max=100, step=0.001 const count = 3; // min=1, max=100, step=1 const rdiff = 0.84; // min=-6.3, max=6.3, step=0.001 const offset = 1; // min=0, max=1, step=0.01 const startAngle = 0; // min=-3.14, max=3.14, step=0.01 const seed = 0; // min=0, max=100, step=1 const root_x = 0; const root_y = 0; const imprecision = 0.0; var rdiff2; function Branch(x, y, length, angle, depth) { this.x = x; this.y = y; this.length = length; this.angle = angle; this.depth = depth; this.branches = []; } Branch.prototype.draw = function() { if (this.length < max_length) { const xi1 = imprecision * (Math.random() - 0.5) * 2; const yi1 = imprecision * (Math.random() - 0.5) * 2; const xi2 = imprecision * (Math.random() - 0.5) * 2; const yi2 = imprecision * (Math.random() - 0.5) * 2; const x2 = this.x + Math.cos(this.angle) * this.length; const y2 = this.y + Math.sin(this.angle) * this.length; turtle.goto(xi1 + root_x + this.x * scale, yi1 + root_y + this.y * scale); turtle.pendown(); turtle.goto(xi2 + root_x + x2 * scale, yi2 + root_y + y2 * scale); } else { turtle.penup(); } for (var c=0; c<this.branches.length; c++) { this.branches[c].draw(); } if (this.length < max_length) { const xi1 = imprecision * (Math.random() - 0.5) * 2; const yi1 = imprecision * (Math.random() - 0.5) * 2; const xi2 = imprecision * (Math.random() - 0.5) * 2; const yi2 = imprecision * (Math.random() - 0.5) * 2; const x2 = this.x + Math.cos(this.angle) * this.length; const y2 = this.y + Math.sin(this.angle) * this.length; turtle.goto(xi2 + root_x + x2 * scale, yi2 + root_y + y2 * scale); turtle.pendown(); turtle.goto(xi1 + root_x + this.x * scale, yi1 + root_y + this.y * scale); } else { turtle.penup(); } } function create_branch(parent, offset, factor, angleChange) { if (parent.depth > max_depth) return; var x = parent.x + Math.cos(parent.angle) * parent.length * offset; var y = parent.y + Math.sin(parent.angle) * parent.length * offset; var length = parent.length * factor; var angle = parent.angle + angleChange; var depth = parent.depth + 1; if (length < min_length) return; var branch = new Branch(x, y, length, angle, depth); parent.branches.push(branch); create_branches(branch); } function create_branches(parent) { var offset2 = offset; var factor = turn_factor; var angleChange = angleInc; for (var s=0; s<split; s++) { if ((s>0) && (!(s&1))) { offset2 *= 0.5; factor *= 0.5; } angleChange *= -1; var rangle = rdiff2; if (seed) { randomSeed(seed + (parent.depth+100) * ((Math.floor(parent.x) + 500) * 1000 + Math.floor(parent.y)) * 94568946); rangle = (random()-0.5) * 2 * rdiff2; } create_branch(parent, offset2, factor, angleChange + rangle); } } // The walk function will be called until it returns false. function walk(i, t) { rdiff2 = rdiff * (Math.cos(t * Math.PI * 2) + 1) * 0.5; //rdiff2 = rdiff + t * Math.PI * 2; if (i==0) { randomSeed(seed); turtle.penup(); } const length = 10; const angle = -Math.PI * 0.5; var root = new Branch(0, 0, length, startAngle + angle + Math.PI * 2 * i / (count), 0); create_branches(root); root.draw(); return (i+1)<count; } //////////////////////// // Utils //////////////////////// function sleep(milliseconds) { const date = Date.now(); let currentDate = null; do { currentDate = Date.now(); } while (currentDate - date < milliseconds); } /////////////// var rseed = 0; var r_a = 1664525; // a - 1 should be divisible by m's prime factors var r_m = 4294967296; // c and m should be co-prime var r_c = 1013904223; function randomSeed(val) { if (val == null) val = 0; rseed = (val == 0 ? Math.random() * r_m : val) >>> 0; } function random() { rseed = (r_a * rseed + r_c) % r_m; var rand = rseed / r_m; return rand; }