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;
}