Log in to post a comment.

// Spirographs. Created by Reinder Nijhoff 2019
// @reindernijhoff
//
// https://turtletoy.net/turtle/d07d0009b3
//

const drawRadius = 6;  // min=1 max=12 step=0.1
const drawDistance = 16; //min=5 max=32 step=0.1
const grid = 12; // min=1 max=24 step=1
const drawSteps = 500;
const spirographs = [];

const gcd = (x, y) => {
    x = Math.abs(x), y = Math.abs(y);
    while(y) {
        const t = y;
        y = x % y;
        x = t;
    }
    return x;
}

class spirograph {
    constructor(x, y, radius) {
        this.x = (x-grid/2+.5)*drawDistance;
        this.y = (y-grid/2+.5)*drawDistance;
        this.r0 = (.2 + .6 * Math.random()) * drawRadius;
        this.r1 = drawRadius - this.r0;
        this.f0 = x + 1;
        this.f1 = -(y + 1);
        this.turtle = new Turtle(this.p(0));
        this.steps = drawSteps / gcd(this.f0, this.f1) + 1;
    }
    p(step) {
        const time = step / drawSteps *  Math.PI * 2;
        return [
            this.x + this.r0*Math.sin(this.f0*time) + this.r1*Math.sin(this.f1*time),
            this.y + this.r0*Math.cos(this.f0*time) + this.r1*Math.cos(this.f1*time)
        ];
    }
    draw(step) {
        if (step > this.steps) {
            return false;
        } else {
            this.turtle.goto(this.p(step));
            return true;
        }
    }
}

for (let x=0; x<grid; x++) {
    for (let y=0; y<grid; y++) {
        spirographs.push(new spirograph(x,y));
    }    
}

function walk(i) {
    let ret = false;
    spirographs.forEach( s => {
        ret = s.draw(i) || ret;
    });
    return ret;
}