Multi-level Spirograph

Spinners all the way down.

Log in to post a comment.

// LL 2021

Canvas.setpenopacity(0.75)

const spinners = 3; // min=1 max=10 step=1
const factor = 0.15; // min=0.0 max=2 step=0.01
const reduce = .12; // min=0 max=1 step=0.01
const slow = 1; // min=0 max=1 step=1 (No,Yes)

const turtle = new Turtle();

const spinner_list = []

var max_value = 1, startXY;

function walk(i) {
    if (i == 0) {
        for (var j=0; j<spinners; j++) {
            spinner_list.push({ angle: 0, rate: 0.001 + j * factor / spinners, radius: 50 * (1 - j * reduce) });
        }

        var count = 0;
        startXY = getXY(); [x, y] = getXY();
        while (spinner_list[0].angle < 1 || Math.hypot(x - startXY[0], y - startXY[1]) > 1) {
            [x, y] = getXY();
            max_value = Math.max(Math.max(max_value, x), y);
            if (count++ > 100000) break;
        }
        spinner_list[0].angle = 0;
        turtle.jump(startXY[0] * 80 / max_value, startXY[1] * 80 / max_value);
    }
    
    [x, y] = getXY();
    turtle.goto(x * 80 / max_value, y * 80 / max_value);

    if (slow) { start = Date.now(); while (Date.now() - start < 1); }

    if (spinner_list[0].angle < 1 || Math.hypot(x - startXY[0], y - startXY[1]) > 1) return true;

    turtle.goto(startXY[0] * 80 / max_value, startXY[1] * 80 / max_value);
    return false;
}

function getXY() {
    var x = 0, y = 0;
    for (var j=0; j<spinners; j++) {
        const xx = x + spinner_list[j].radius * Math.cos(spinner_list[j].angle);
        const yy = y + spinner_list[j].radius * Math.sin(spinner_list[j].angle);
        spinner_list[j].angle += spinner_list[j].rate;
        x = xx; y = yy;
    }
    return [x, y];
}