Subdivision of space 2

Random binary subdivision of space, rotated

Log in to post a comment.

// Forked from "Subdivision of space 1" by imakerobots
// https://turtletoy.net/turtle/9906b488f3
let angle = 25;  // min=1 max=180 step=1
let splits = 5;  // min=1 max=20 step=1

// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(1);

// Global code will be evaluated once.
const turtle = new Turtle();

class Branch {
    constructor(x0,y0,x1,y1) {
        this.x0 = x0;
        this.y0 = y0;
        this.x1 = x1;
        this.y1 = y1;
    }
}

const root = new Branch(-140,-140,140,140);
const tree = [];

const rad = radians(angle);


// setup the tree
tree.push(root);

for(i=0;i<splits;++i) {
    splitTreeRandomly();
}

// only methods after this point

function radians(degrees) {
	return degrees * Math.PI / 180;
}

// returns a value [0...1) biased towards 0.5
function biasedSplit() {
    return 0.5+(Math.random()-Math.random())/2;
}

// split one branch and choose the split direction at random.
function splitBranchEitherWay(parent) {
    if( Math.random() > 0.5 ) {
        // split vertically
        split = (parent.y1-parent.y0) * biasedSplit() + parent.y0;
        c0 = new Branch(parent.x0,parent.y0,parent.x1,split);
        c1 = new Branch(parent.x0,split,parent.x1,parent.y1);
    } else {
        // split horizontally
        split = (parent.x1-parent.x0) * biasedSplit() + parent.x0;
        c0 = new Branch(parent.x0,parent.y0,split,parent.y1);
        c1 = new Branch(split,parent.y0,parent.x1,parent.y1);
    }
    parent.c0=c0;
    parent.c1=c1;
    tree.push(c0,c1);
}

// split the tree one time at a random branch that does not already have children.
function splitTreeRandomly() {
    index = 0;
    do {
        index = Math.floor(Math.random() * tree.length);
        // check for children
    } while(tree[index].c0!=null);
    
    splitBranchEitherWay(tree[index]);
}

function rotatePoint(x0,y0) {
    var x1 = x0 * Math.cos(rad) - y0 * Math.sin(rad);
    var y1 = x0 * Math.sin(rad) + y0 * Math.cos(rad);
    return [x1,y1];
}

function goto(x0,y0,x1,y1) {
    var p0 = rotatePoint(x0,y0);
    var p1 = rotatePoint(x1,y1);
    turtle.goto(
        p0[0],
        p0[1],
        p1[0],
        p1[1],
    );
}

// The walk function will be called until it returns false.
function walk(i) {
    for(var i=0;i<tree.length;++i) {
        var b = tree[i];
        turtle.penup();
        goto(b.x0,b.y0);
        turtle.pendown();
        goto(b.x1,b.y0);
        goto(b.x1,b.y1);
        goto(b.x0,b.y1);
        goto(b.x0,b.y0);
        turtle.penup();
    }
    return false;
}