如何在有界区域正确模拟重力?

时间:2017-09-29 14:34:45

标签: javascript d3.js

我正在尝试用一个装有球的容器,像重力一样吸引到地板上。我接近做得很好,但球最终融为一体,然后不保持其可见度。

See the demo here

我认为问题来自引力函数本身,因为不考虑每个节点的半径:

d3.selectAll("circle.node")
  .attr("cx", function(d,i){ return Math.max(radius, Math.min(width - radius, d.x)); })
  .attr("cy", function(d,i){ return Math.max(radius, Math.min(height - radius, d.y)); });

或者来自模拟动画中的边界函数(勾选),对于上面的相同问题

{{1}}

在这种情况下,如何区分每个球?

编辑:我发现解决方案很快就会分享

2 个答案:

答案 0 :(得分:0)

有一个名为planck.js的图书馆。我知道它与D3无关,但您可以随时查看代码以获得灵感。

祝你好运!

答案 1 :(得分:0)

好的,我终于阅读了文档并理解了这个问题!

<强> See the demo here

所有关于每个节点之间的碰撞,在forceSimulation中正确地集成它,以及在tick函数中绑定计算:

...


  // Change values below to modify the physic
  var simulation = d3.forceSimulation()
    .velocityDecay(0.3)
    .force("y", d3.forceY(height).strength(.035)) // gravity at bottom
    .force("collide", d3.forceCollide().radius(radius).strength(1.5).iterations(10))
    .nodes(nodes)
    .on('tick', tick);

  function tick() {
    // bound
    node.attr('cx', function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); })
        .attr('cy', function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); });
  }