Recursion - Veins

by soulwire

HTML

<canvas id="world" width="800" height="800"></canvas>

JavaScript

var canvas = document.getElementById('world');
var context = canvas.getContext('2d');

var Branch = function(x, y, a, s) {

    this.x = x;
    this.y = y;
    this.a = a;
    this.s = s;
    this.points = [];
    this.children = [];
};

Branch.prototype.grow = function() {

    // Grow all children
    for (var i = 0, n = this.children.length; i < n; i++) {
        this.children[i].grow();
    }

    // Grow if not too big
    if (this.s > 0.75) {

        // Branch
        if (this.children.length < 3 && Math.random() < 0.05) {
            var angle = this.a + (Math.random() - 0.5) * Math.PI;
            var scale = this.s * 0.9;
            var child = new Branch(this.x, this.y, angle, scale);
            this.children.push(child);
        }

        // Grow
        this.a += (Math.random() - 0.5) * 0.75;
        this.x += Math.cos(this.a) * this.s * 1.0;
        this.y += Math.sin(this.a) * this.s * 1.0;

        this.points.push({
            x: this.x,
            y: this.y,
            s: this.s
        });

        this.s *= 0.98;
    }
};

Branch.prototype.render = function(ctx) {

    // Render all children
    for (var i = 0, n = this.children.length; i < n; i++) {
        this.children[i].render(ctx);
    }

    ctx.strokeStyle = '#333';
    ctx.fillStyle = '#fff';

    if (this.points.length > 0) {
        var p = this.points[this.points.length - 1];

        ctx.beginPath();
        ctx.arc(p.x, p.y, p.s, 0, Math.PI * 2);
        ctx.closePath();
        ctx.stroke();
        ctx.fill();
    }

/*
    for(var i = 0, n = this.points.length; i < n; i++) {
        p = this.points[i];
        
        ctx.beginPath();
        ctx.arc(p.x, p.y, p.s, 0, Math.PI*2);
        ctx.closePath();
        ctx.stroke();
        ctx.fill();
    }
    */
};

Branch.prototype.destroy = function() {
    this.points = [];
    this.children = [];
};

var trees = [];
var mouse = {
    x: 200,
    y: 200
};

function init() {

    var tree, i;

    for (i = 0, n =...