Lost Familiarity

The city no longer feels the same.

Log in to post a comment.

Canvas.setpenopacity(-0.33);

const size = 200;
const nBoxes = 15;
const minBoxSize = 12;
const maxBoxSize = 24;
const headingStep = 0.1256;
const step = 0.256;
const p = 0.03+Math.random()*0.03;
const q = 0.05+Math.random()*0.05;

let turtles = [];
let boxes = [];
let nt;
let iter = 0;
let heading = 270-headingStep;

const coord = () => {
    const pos = maxBoxSize + ((100 - maxBoxSize) * Math.random());
    return Math.random() < 0.5 ? pos : -pos;
};

boxes = [...Array(nBoxes)].map(() => {
    const x = coord();
    const y = coord();
    return [x-maxBoxSize/2, y-maxBoxSize/2, Math.min(x+maxBoxSize/2+(maxBoxSize-minBoxSize), 100), Math.min(y+maxBoxSize/2+(maxBoxSize-minBoxSize), 100)];
});

Turtle.prototype.withinBounds = function(side) {
    const mod = maxBoxSize*this.mod+1
    const x = this.x()+mod;
    const y = this.y()+mod;
    const ret = Math.abs(x-mod) <= 100 && Math.abs(y-mod) <= 100 && !this.bounds.find(bounds => {
        if (side==1) {
            if (y > 0) {
                return Math.floor(y) == Math.round(bounds[1]) && x >= bounds[0] && x < bounds[2];    
            } else {
                return Math.ceil(y) == Math.round(bounds[3]) && x >= bounds[0] && x < bounds[2];    
            }
        }
        else if (side==2) {
            if (x > 0) {
                return Math.floor(x) == Math.round(bounds[0]) && y >= bounds[1] && y < bounds[3];    
            } else {
                return Math.ceil(x) == Math.round(bounds[2]) && y >= bounds[1] && y < bounds[3];    
            }
        }
        return x >= bounds[0] && y >= bounds[1] && x < bounds[2] && y < bounds[3]
    })
    return ret;
}

const spawnTurtle = (x = 0, y = 0, angle = heading) => {
    const turtle = new Turtle();
    turtle.penup();
    turtle.goto(x, y);
    turtle.seth(angle);
    turtle.root = true;
    turtle.bounds = boxes;
    turtle.pendown();
    return turtle;
}

function walk(i) {
    if (turtles.length) {
        turtles.map((turtle, idx) => {
            turtle.mod = 0.22*Math.sin(p*turtle.x())*Math.cos(q*turtle.y());
            turtle.forward(step);
            turtle.right(turtle.mod);
        });
        turtles = turtles.filter(turtle => {
            if (!turtle.withinBounds(Math.floor(iter/(360/headingStep)))) {
                heading += headingStep;
                iter++;
                return false;
            }
            return true;
        });
    }
    else {
        nt = spawnTurtle(0, 0, heading);
        turtles.push(nt);
    }
    return iter < 4*(360/headingStep);
}