function forceCollide() {
const alpha = 0.5;
let nodes = [];
function force() {
const quadtree = d3.quadtree()
.x(d => d.x)
.y(d => d.y)
.addAll(nodes);
for (const node of nodes) {
quadtree.visit((visited, x1, y1, x2, y2) => {
let updated = false;
if (visited.data && (visited.data !== node)) {
const actualDistance = distance(node, visited.data);
const minAllowedDistance = node.r + visited.data.r;
if (actualDistance < minAllowedDistance) {
const movementConstant = (actualDistance - minAllowedDistance) / actualDistance * alpha;
const deltaX = (node.x - visited.data.x) * movementConstant;
const deltaY = (node.y - visited.data.y) * movementConstant;
node.x -= deltaX;
node.y -= deltaY;
visited.data.x += deltaX;
visited.data.y += deltaY;
updated = true;
}
}
return updated;
});
}
}
force.initialize = function (_nodes) {
nodes = _nodes;
}
return force;
}