Deterministic initialization!
Rather than initialize the node positions randomly, use a phyllotaxis. This is just as good, and means the resulting behavior will be deterministic as long as no nodes are exactly coincident.
This commit is contained in:
parent
ec754db14f
commit
aa410cf32e
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user