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;
}