Spirograph

A basic spirograph, i.e., one circle rolling on another.

Log in to post a comment.

// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(1);

let r1 = 20;          // min = 1, max = 100, step = 1
let r2 = 65;          // min = 1, max = 100, step = 1
// rPen is the position on the second circle, it's a percentage of the radius. value > 100 are outside of the circle
let rPen = 140;         // min = 1, max = 200, step = 1
//const turns = 1;        // min = 1, max = 50, step = 1
rPen /= 100;

// Global code will be evaluated once.
const turtle = new Turtle();

function getTurns(x, y){
    let tmp = 0;
    if(y > x){
        tmp = x;
        x = y;
        y = tmp;
    }
    
    let yy = y;
    let r = y;
    let rr = r;
    while(r != 0){
        rr = r;
        r = x % yy;
//        console.log(x, yy, r, rr);
        x = yy;
        yy = r;
    }
    
    return y / rr;
}

let turns = getTurns(r1, r2);

if(r1 > r2){
    turns *= r2 * ((r2 + r1) / r1);
}

r1 /= 3;
r2 /= 3;


//console.log(turns);

// The walk function will be called until it returns false.
function walk(i) {

    let theta = Math.PI * i / 180;
    
    let cx = Math.cos(theta) * (r1 + r2);
    let cy = Math.sin(theta) * (r1 + r2);
    
    let rx = rPen * Math.cos(theta * (r2 + r1) / r1) * r2;
    let ry = rPen * Math.sin(theta * (r2 + r1) / r1) * r2;
    
    if(i) turtle.goto(cx + rx, cy + ry);
    else  turtle.jump(cx + rx, cy + ry);
    
    return i <= 360 * turns;
}