pack = ({ inPolygon, outPolygon, circles }) => {
const [[x1, y1], [x2, y2]] = geometric.polygonBounds(inPolygon),
width = x2 - x1,
height = y2 - y1;
let r, x, y;
let safe = false,
iters = 0;
while (!safe) {
let intersection = false;
r = 1 + Math.random() * (size / 10);
x = x1 + r + Math.random() * (width - r * 2);
y = y1 + r + Math.random() * (height - r * 2);
const p = [x, y];
if (
geometric.pointInPolygon(p, inPolygon) &&
!geometric.pointInPolygon(p, outPolygon) &&
circleInPolygon({ x, y, r, polygon: outPolygon })
) {
for (let i = 0, l = circles.length; i < l; i++) {
const c = circles[i];
const l = geometric.lineLength([p, [c.x, c.y]]);
if (l < r + c.r + 1) {
intersection = true;
break;
}
}
safe = !intersection;
} else {
safe = false;
}
iters++;
}
if (safe) {
circles.push({ x, y, r, iters, index: circles.length });
}
}