Log in to post a comment.

Canvas.setpenopacity(1);

const turtle = new Turtle();

// adjust to fit canvas
let scale = 1; // min=0, max=10, step=0.1

// ----------------------
// PARAMETERS
// ----------------------

// number of sections
let part = 4; // min=2, max=50, step=2 number of sections

// starting radius
let R_min = 15; // min=1, max=50, step=1 Radius of the inner circle

// desired overall diameter
let diameter = 124; // min=10, max=1000, step=1 Diameter of the outer circle

// base spacing between rings
let spacing = 2; // min=1, max=50, step=0.5 Width between consecutive arcs

let spacing_min = spacing;
let spacing_max = 2*spacing;

// ----------------------
// SPACING MODES
// ----------------------

let spacing_mode = 1;  // min=1, max=3, step=1 Width variation mode
// 1 = constant spacing
// 2 = increasing spacing
// 3 = decreasing spacing

if (spacing_mode == 1) {

    function spacing_slope(n) {
        return spacing;
    }

} else if (spacing_mode == 2) {

    function spacing_slope(r) {

    let t = (r - R_min) / (diameter/2 - R_min);

    return spacing_min +
           (spacing_max - spacing_min) * t;

}

} else if (spacing_mode == 3) {
    function spacing_slope(r) {

    let t = (r - R_min) / (diameter/2 - R_min);

    return spacing_min -
           (spacing_max - spacing_min) * t;

}

}

// overlap amount
let overlap = 6; // min=1, max=50, step=1 Overlaping length

// ----------------------
// OVERLAP MODES
// ----------------------

let overlap_mode = 1; // min=1, max=4, step=1 Overlaping variation mode

if (overlap_mode == 1) {

    function D_slope(n) {
        return overlap;
    }

} else if (overlap_mode == 2) {

    function D_slope(n) {
        return 0.5 * overlap + n * 0.3;
    }

} else if (overlap_mode == 3) {

    function D_slope(n) {
        return 0.25 * overlap - n * 0.15;
    }

} else {

    function D_slope(n) {
        return overlap * (1 + 0.4 * Math.sin(n / 4));
    }

}


// spiral amount
let offset = 0; // min=0, max=10, step=0.1 Spiraling amount

// ----------------------
// COMPUTE NUMBER OF RINGS
// ----------------------

let circle_number = 0;
let temp_r = R_min;

while (temp_r < diameter / 2) {

    temp_r += spacing_slope(circle_number);
    circle_number++;

}

// ----------------------
// DRAW ARC
// ----------------------

function draw_arc(radius, start, end) {

    const steps = 100;
    const step = (end - start) / steps;

    for (let k = 0; k <= steps; k++) {

        let angle = start + k * step;

        let x = scale * radius * Math.cos(angle);
        let y = scale * radius * Math.sin(angle);

        if (k === 0) {

            turtle.penup();
            turtle.goto(x, y);
            turtle.pendown();

        } else {

            turtle.goto(x, y);

        }
    }
}

// ----------------------
// DRAW FULL CIRCLE
// ----------------------

function draw_circle(radius) {

    const steps = Math.max(
        200,
        Math.floor(2 * Math.PI * radius)
    );

    for (let k = 0; k <= steps; k++) {

        let angle = 2 * Math.PI * k / steps;

        let x = scale * radius * Math.cos(angle);
        let y = scale * radius * Math.sin(angle);

        if (k === 0) {

            turtle.penup();
            turtle.goto(x, y);
            turtle.pendown();

        } else {

            turtle.goto(x, y);

        }
    }
}

// ----------------------
// WALK
// ----------------------

function walk(i) {

    if (i > 0) return false;

    let r = R_min;

    // cumulative spiral angle
    let spiral = 0;

    for (let n = 0; n < circle_number; n++) {

        let eps = D_slope(n);

        let start = 0;
        let end = start + 2 * Math.PI / part;

        let start2 = end;
        let end2 = start2 + 2 * Math.PI / part;

        for (let j = 0; j < part; j++) {

            if (n % 2 === 0) {

                draw_arc(
                    r,
                    start + spiral - eps / r,
                    end + spiral + eps / r
                );

            } else {

                draw_arc(
                    r,
                    start2 + spiral - eps / r,
                    end2 + spiral + eps / r
                );

            }

            // advance the spiral
            spiral += offset / r;

            start = end + 2 * Math.PI / part;
            end = start + 2 * Math.PI / part;

            start2 = end2 + 2 * Math.PI / part;
            end2 = start2 + 2 * Math.PI / part;
        }

        // use selected spacing mode
        r += spacing_slope(n);
    }

    // outer boundary
    draw_circle(r);

    return false;
}

walk(0);