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