Expanding circs

Adaptation of mathrabbit's Expanding Rects, but it's just circs.
(Expanding Rects)

Thanks chatgpt for this horrendous mess

Log in to post a comment.

let NUM_CIRCLES = 500; // min=0, max=1000, step=10
let CENTER_RAD = 1; // min=0.5, max=5, step=0.1
let SHRINK = 1; // min=-10, max=10, step=1
let HIT_SIDES_CHANCE = 0.2; // min=0, max=1, step=0.1
let OUTER_PADDING = 10; // min=0, max=50, step=1
let SEED_PADDING = 30; // min=0, max=50, step=1
let MIN_RAD = 2; // min=0, max=20, step=0.5
let MAX_RAD = 10; // min=0, max=20, step=0.5

// The overlap can be a fun parameter to experiment with.
let OVERLAP_ALLOWANCE = 2; // min=0, max=10, step=0.5

// Booleans
let DO_EXPAND = 1; // min=0, max=1, step=1
let DRAW_CENTERS = 0; // min=0, max=1, step=1
let DRAW_FRAME = 1; // min=0, max=1, step=1
let DRAW_X = 0; // min=0, max=1, step=1

// Hatching options
let HATCH_CHANCE = 0.8; // min=0, max=1, step=0.1
let HATCH_SPACING = 1.5; // min=1, max=10, step=0.5
let SPARSE_HATCH_CHANCE = 0.15; // min=0, max=1, step=0.1
let R_SPACING = 15; // min=5, max=45, step=5
let R_SPACING_VARIANCE = 5; // min=0, max=20, step=1
let R_SPACING_MIN = 5; // min=1, max=20, step=1

let HATCH_TYPE_CHANCE = 0.5; 

Canvas.setpenopacity(1);
const turtle = new Turtle();
turtle.pendown();

let rand = (min, max) => Math.random() * (max - min) + min;
let randInt = (min, max) => Math.floor(rand(min, max));
let degreesToRadians = degrees => degrees * (Math.PI / 180);

let intersect = (circle1, circle2) => {
    let dx = circle1.x - circle2.x;
    let dy = circle1.y - circle2.y;
    let distance = Math.sqrt(dx * dx + dy * dy);
    return distance < circle1.r + circle2.r - OVERLAP_ALLOWANCE;
};

let Circle = (x, y, r) => {
    let circle = {
        x: x,
        y: y,
        r: r,
    };

    circle.draw = () => {
        if (DRAW_FRAME) {
            turtle.jump(circle.x, circle.y - circle.r);
            turtle.circle(circle.r);
        }

        if (DRAW_CENTERS) {
            turtle.jump(circle.x, circle.y - 0.5);  // Adjust the 0.5 to the desired dot radius
            turtle.circle();
        }

        if (Math.random() < HATCH_CHANCE) {
        let isRadialHatch = Math.random() < HATCH_TYPE_CHANCE;
        
        let spacing = HATCH_SPACING;
        if (Math.random() < SPARSE_HATCH_CHANCE) {
            spacing *= 2;
        }

        // Adjust the spacing based on variance and minimum spacing for radial hatching
        let randomSpacing = R_SPACING + (Math.random() - 0.5) * 2 * R_SPACING_VARIANCE;
        randomSpacing = Math.max(randomSpacing, R_SPACING_MIN);

        if (isRadialHatch) {
            for (let angle = 0; angle < 360; angle += randomSpacing) {
                turtle.jump(circle.x + circle.r * Math.cos(degreesToRadians(angle)), circle.y + circle.r * Math.sin(degreesToRadians(angle)));
                turtle.goto(circle.x, circle.y);
            }
        } else {
            // 45° hatching using the original 'spacing' value
            let distance = Math.SQRT2 * circle.r;  // This ensures hatching covers the entire circle
            let x1 = circle.x - distance / 2;
            let y1 = circle.y + distance / 2;
            let x2 = circle.x + distance / 2;
            let y2 = circle.y - distance / 2;

            for (let i = -distance/2; i <= distance/2; i += spacing) {
                turtle.jump(x1 + i, y1);
                turtle.goto(x2 + i, y2);
          
                }
            }
        }
    };

    circle.expand = (amt) => {
        circle.r += amt;
    };

    circle.isValid = () => circle.r > 0;

    return circle;
};

let circles = [];

for (let ii = 0; ii < NUM_CIRCLES; ii++) {
    let limit = 100 - SEED_PADDING;
    let x = randInt(-limit, limit);
    let y = randInt(-limit, limit);
    let r = randInt(MIN_RAD, MAX_RAD);
    let circle = Circle(x, y, r);
    let intersects = false;
    for (let jj = 0; jj < circles.length; jj++) {
        if (intersect(circles[jj], circle)) {
            intersects = true;
            break;
        }
    }
    if (!intersects) {
        circles.push(circle);
    }
}
console.log('' + circles.length + ' circles');

for (let c of circles) {
    c.expand(-1);
}
circles = circles.filter(c => c.isValid());

function walk(ii) {
    circles[ii].draw();
    return ii < circles.length-1;
}