pack = (polygon, circles, rmin = 1, rmax = 20, pad = 1) => {
const [[x1, y1], [x2, y2]] = geometric.polygonBounds(polygon),
width = x2 - x1,
height = y2 - y1;
let r, x, y;
let safe = false,
iters = 0;
while (!safe){
let intersection = false;
r = max(rmin, random() * rmax);
x = x1 + r + random() * (width - (r * 2));
y = y1 + r + random() * (height - (r * 2));
const p = [x, y];
if (geometric.pointInPolygon(p, polygon) && circleInPolygon(x, y, r, polygon)){
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 + pad)){
intersection = true;
break;
}
}
safe = !intersection;
}
else {
safe = false;
}
iters++;
}
if (safe) {
circles.push({ x, y, r, iters, index: circles.length });
}
}