Polygon Spiro

Mandala, Spirograph, Polygon, Circular

Log in to post a comment.

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

// Global code will be evaluated once.
const turtle = new Turtle();
turtle.penup();
turtle.goto(-50,-20);
turtle.pendown();

function linspace(a,b,n) {
    if(typeof n === "undefined") n = Math.max(Math.round(b-a)+1,1);
    if(n<2) { return n===1?[a]:[]; }
    var i,ret = Array(n);
    n--;
    for(i=n;i>=0;i--) { ret[i] = (i*b+(n-i)*a)/n; }
    return ret;
}

function drawPolygon(n, x, y, r, rot) {
    const phi = linspace(0+rot, 2*Math.PI+rot, n+1)
    
    turtle.penup()
    turtle.goto(r*Math.sin(phi[0])+x, r*Math.cos(phi[0])+y)
    turtle.pendown()
    
    for(i=n;i>=0;i--) { 
        turtle.goto(r*Math.sin(phi[i])+x, r*Math.cos(phi[i])+y)
    }
    turtle.penup()
}

const nMain = 8
const nSub = 12
const subAngleInc = 0.03
const subRotInc = 0.05
const subRadiusInc = -0.8
const mainRadius = 40
const polygonRadius = 50
const polygonN = 6
const rotOffset = -60.0/360*2*Math.PI

// The walk function will be called until it returns false.
function walk(i) {
    const phi = linspace(0, 2*Math.PI, nMain+1)
    const phiInc = linspace(0, subAngleInc*nSub, nSub)
    const rotInc = linspace(0, subRotInc*nSub, nSub)
    const radiusInc = linspace(0, subRadiusInc*nSub, nSub)
    
    let x
    let y
    
    for(i=nMain;i>=0;i--) { 
        for(j=nSub;j>=0;j--) { 
            x = (mainRadius+radiusInc[j])*Math.cos(phi[i]+phiInc[j])
            y = (mainRadius+radiusInc[j])*Math.sin(phi[i]+phiInc[j])   
            drawPolygon(polygonN, x, y, polygonRadius, phi[i]+rotInc[j]+rotOffset)
        }
    }
    return false;
}