vasturiano / d3-force-3d

Force-directed graph layout in 1D, 2D or 3D using velocity Verlet integration.
https://observablehq.com/@vasturiano/multi-dimensional-d3-force-simulation
MIT License
369 stars 52 forks source link

manyBody for loop bug? #7

Closed izhanghongbo closed 5 years ago

izhanghongbo commented 5 years ago

Hi,

I use d3-force-3d to do 3 dimensions graph visualization, when I drag a node, all the nodes linked with it will crowded together, is it because the parameters at accumulate are not correct? since it used d3-octree, it's tree node have 8 children, when I change 4 to 8 in for loop ,this problem seems fixed.

BTW, your repositories are so awesome! get lots of inspiration from it.

9859FAAB-06AC-41E3-BE62-6F795FB5A19D

  function accumulate(treeNode) {
    var strength = 0, q, c, weight = 0, x, y, z, i;

    // For internal nodes, accumulate forces from children.
    if (treeNode.length) {
      for (x = y = z = i = 0; i < 4; ++i) {
        if ((q = treeNode[i]) && (c = Math.abs(q.value))) {
          strength += q.value, weight += c, x += c * (q.x || 0), y += c * (q.y || 0), z += c * (q.z || 0);
        }
      }
      treeNode.x = x / weight;
      if (nDim > 1) { treeNode.y = y / weight; }
      if (nDim > 2) { treeNode.z = z / weight; }
    }

    // For leaf nodes, accumulate forces from coincident nodes.
    else {
      q = treeNode;
      q.x = q.data.x;
      if (nDim > 1) { q.y = q.data.y; }
      if (nDim > 2) { q.z = q.data.z; }
      do strength += strengths[q.data.index];
      while (q = q.next);
    }

    treeNode.value = strength;
  } 

is this line un correct when on 3 dimensions?

      for (x = y = z = i = 0; i < 4; ++i) 
izhanghongbo commented 5 years ago

3d-force-graph's example seems have that problem too, some times charge layout(manyBody) won't bounce nodes normal F51E1723-618C-4205-B2DE-AD236896CE0F unnormal image

vasturiano commented 5 years ago

@izhanghongbo thanks for your report, this is a great catch!

The loop should indeed iterate through all the children (8 for octree, 4 for quadtree and 2 for binary tree). I've fixed the code and I think this will solve the issue with the non-repelling nodes, which has actually been bothering me for some time. Thanks again for debugging and bringing this up. 👍