forcePolar = function(radius, x, y, angle) {
var nodes,
strength = constant(0.1),
strengths,
radii,
angles;
if (angle !== undefined && angle !== null && typeof angle !== "function")
angle = constant(+angle);
if (radius !== undefined && radius !== null && typeof radius !== "function")
radius = constant(+radius);
if (x == null) x = 0;
if (y == null) y = 0;
function force(alpha) {
for (var i = 0, n = nodes.length; i < n; ++i) {
var node = nodes[i],
dx = node.x - x || 1e-6,
dy = node.y - y || 1e-6,
r = Math.hypot(dy, dx);
if (radius) {
var k = ((radii[i] - r) * strengths[i] * alpha) / r;
node.vx += dx * k;
node.vy += dy * k;
}
if (angle) {
var a = Math.atan2(dy, dx),
diff = angles[i] - a,
k = r * Math.sin(diff) * (strengths[i] * alpha);
k *= Math.hypot(1, Math.tan(diff / 2));
node.vx += -k * Math.sin(a);
node.vy += k * Math.cos(a);
}
}
}
function initialize() {
if (!nodes) return;
var i,
n = nodes.length;
strengths = new Array(n);
angles = new Array(n);
radii = new Array(n);
for (i = 0; i < n; ++i) {
if (angle) angles[i] = +angle(nodes[i], i, nodes) * (Math.PI / 180);
if (radius) radii[i] = +radius(nodes[i], i, nodes);
strengths[i] =
(angle && isNaN(angles[i])) || (radius && isNaN(radii[i]))
? 0
: +strength(nodes[i], i, nodes);
}
}
force.initialize = function(_) {
(nodes = _), initialize();
};
force.strength = function(_) {
return arguments.length
? ((strength = typeof _ === "function" ? _ : constant(+_)),
initialize(),
force)
: strength;
};
force.angle = function(_) {
return arguments.length
? ((angle = typeof _ === "function" ? _ : constant(+_)),
initialize(),
force)
: angle;
};
force.radius = function(_) {
return arguments.length
? ((radius = typeof _ === "function" ? _ : constant(+_)),
initialize(),
force)
: radius;
};
force.x = function(_) {
return arguments.length ? ((x = +_), force) : x;
};
force.y = function(_) {
return arguments.length ? ((y = +_), force) : y;
};
return force;
}