function circleGenerator(maxRadius) {
const quadtree = d3.quadtree().extent([[0, 0], [width, height]]);
return k => {
let bestX, bestY, bestDistance = 0;
for (var i = 0; i < k; ++i) {
const x = Math.random() * width;
const y = Math.random() * height;
const rx1 = x - maxRadius * 2;
const rx2 = x + maxRadius * 2;
const ry1 = y - maxRadius * 2;
const ry2 = y + maxRadius * 2;
let distance = maxRadius;
quadtree.visit((node, x1, y1, x2, y2) => {
if (!node.length) {
do {
const [px, py, pr] = node.data;
const dx = x - px;
const dy = y - py;
const d2 = dx * dx + dy * dy;
const r2 = pr * pr;
if (d2 < r2) return distance = 0, true;
const d = Math.sqrt(d2) - pr;
if (d < distance) distance = d;
} while (node = node.next);
}
return !distance || x1 > rx2 || x2 < rx1 || y1 > ry2 || y2 < ry1;
});
if (distance > bestDistance) bestX = x, bestY = y, bestDistance = distance;
}
if (bestDistance <= padding) return null;
const best = [bestX, bestY, bestDistance - padding];
quadtree.add(best);
return best;
};
}