Deployable Kirigami #2

In this version, we choose the diameter instead of the number of circle. A contour circle has been added too.

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 = 6; // min=2, max=50, step=2

// starting radius
let R_min = 15; // min=1, max=50, step=1

// spacing between rings
let spacing = 2; // min=1, max=50, step=0.5

// desired overall diameter (including outer circle)
let diameter = 100; // min=10, max=1000, step=1

// overlap amount
let overlap = 5; // min=1, max=50, step=1

// computed automatically
let circle_number = Math.floor(
    (diameter / 2 - R_min) / spacing
);

// ----------------------
// SLOPE FUNCTIONS
// ----------------------

let mode = 1; // min=1, max=4, step=1

if (mode == 1) {
    function D_slope(n) {
        return overlap;
    }
}
else if (mode == 2) {
    function D_slope(n) {
        return 0.5 * overlap + n * 0.3;
    }
}
else if (mode == 3) {
    function D_slope(n) {
        return 0.25 * overlap - n * 0.1;
    }
}
else {
    function D_slope(n) {
        return overlap * (1 + 0.4 * Math.sin(n / 4));
    }
}

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

function draw_arc(radius, start, end) {

    const steps = 20;
    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;

    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 = 1; j <= part; j++) {

            if (n % 2 === 0) {

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

            } else {

                draw_arc(
                    r,
                    start2 - eps / r,
                    end2 + eps / 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;
        }

        r += spacing;
    }

    // draw one extra full circle
    draw_circle(r);

    return false;
}

walk(0);