diff --git a/src/manyBody.js b/src/manyBody.js index 733b263..5a428a4 100644 --- a/src/manyBody.js +++ b/src/manyBody.js @@ -60,16 +60,11 @@ export default function() { w = x2 - x1, l = x * x + y * y; - // Limit forces for very close nodes. - // Randomize direction for exactly-coincident nodes. - if (l < distanceMin2) { - if (!l) l = Math.random() * tau, x = Math.cos(l), y = Math.sin(l), l = 1; - l = Math.sqrt(l / distanceMin2), x /= l, y /= l, l = distanceMin2; - } - // Apply the Barnes-Hut approximation if possible. + // Limit forces for very close nodes. if (w * w / theta2 < l) { if (l < distanceMax2) { + if (l < distanceMin2) l = Math.sqrt(l / distanceMin2), x /= l, y /= l, l = distanceMin2; l = quad.value * alpha / l; node.vx += x * l; node.vy += y * l; @@ -80,6 +75,13 @@ export default function() { // Otherwise, process points directly. else if (quad.length || l >= distanceMax2) return; + // Limit forces for very close nodes. + // Randomize direction for exactly-coincident nodes. + if (l < distanceMin2) { + if (!l) l = Math.random() * tau, x = Math.cos(l), y = Math.sin(l), l = 1; + l = Math.sqrt(l / distanceMin2), x /= l, y /= l, l = distanceMin2; + } + do if (quad.data !== node) { w = strengths[quad.data.index] * alpha / l; node.vx += x * w; diff --git a/src/simulation.js b/src/simulation.js index 9f7ee0b..4348feb 100644 --- a/src/simulation.js +++ b/src/simulation.js @@ -10,6 +10,9 @@ export function y(d) { return d.y; } +var initialRadius = 10, + initialAngle = Math.PI * (3 - Math.sqrt(5)); + export default function(nodes) { var simulation, iteration = 0, @@ -58,10 +61,14 @@ export default function(nodes) { function initializeNodes() { for (var i = 0, n = nodes.length, node; i < n; ++i) { node = nodes[i], node.index = i; - if (isNaN(node.x)) node.x = Math.random() * 100 - 50; - if (isNaN(node.y)) node.y = Math.random() * 100 - 50; - if (isNaN(node.vx)) node.vx = 0; - if (isNaN(node.vy)) node.vy = 0; + if (isNaN(node.x) || isNaN(node.y)) { + var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle; + node.x = radius * Math.cos(angle); + node.y = radius * Math.sin(angle); + } + if (isNaN(node.vx) || isNaN(node.vy)) { + node.vx = node.vy = 0; + } } }