circletransform

circletransform

Log in to post a comment.

function Translate(x,y) { return p => [p[0]+x, p[1]+y]; }
function Scale(s) { return p => [p[0]*s, p[1]*s]; }
function Circle(r) { return p => { let ry = r - p[1]; a = p[0]/r;
                                   return [ry*Math.cos(a), ry*Math.sin(a)]; } }

const turtle = new Tortoise();
turtle.addTransform(Circle(50));
turtle.forward(50*Math.PI); 
turtle.forward(50*Math.PI);

const numHouses = 14;

function walk(i) {
    const h = new Tortoise();
    h.addTransform(Scale(.2));
    h.addTransform(Translate(i * 50*Math.PI*2 / numHouses, 0));
    h.addTransform(Circle(50));
    drawHouse(h);
    
    return i < numHouses - 1;
}

// House
function drawHouse(t) {
    square(t, [-10,-20], [30,0]);
    square(t, [-5,-15], [2,-8]);
    square(t, [7,0], [14,-15]);
    square(t, [19,-15], [25,-8]);
    square(t, [-25,-15], [-15,-8]);
    for (let i=-20; i<=20; i+=4) {
        t.jmp(i,-30); t.goto(i+10,-20);
    }
    t.jmp(-20,-30); t.goto(20,-30);
    t.jmp(-20,-30); t.goto(-30,-20);
    t.jmp(-30,-20); t.goto(-30,0);
    t.jmp(-30,0); t.goto(-10,0);
}
function square(t, lt, rb) {
    t.jmp(lt); t.goto(lt[0], rb[1]); t.goto(rb), t.goto(rb[0], lt[1]); t.goto(lt);
}

////////////////////////////////////////////////////////////////
// Tortoise utility code (Minimal Turtle and Transforms)
// https://turtletoy.net/turtle/102cbd7c4d
////////////////////////////////////////////////////////////////

function Tortoise(x, y) {
    class Tortoise extends Turtle {
        constructor(x, y) {
            super(x, y);
            this.ps = Array.isArray(x) ? [...x] : [x || 0, y || 0];
            this.transforms = [];
        }
        addTransform(t) {
            this.transforms.push(t);
            this.jump(this.ps);
            return this;
        }
        applyTransforms(p) {
            if (!this.transforms) return p;
            let pt = [...p];
            this.transforms.map(t => { pt = t(pt); });
            return pt;
        }
        goto(x, y) {
            const p = Array.isArray(x) ? [...x] : [x, y];
            const pt = this.applyTransforms(p);
            if (this.isdown() && (this.pt[0]-pt[0])**2 + (this.pt[1]-pt[1])**2 > 4) {
               this.goto((this.ps[0]+p[0])/2, (this.ps[1]+p[1])/2);
               this.goto(p);
            } else {
                super.goto(pt);
                this.ps = p;
                this.pt = pt;
            }
        }
        position() { return this.ps; }
    }
    return new Tortoise(x,y);
}