【问题标题】:rect collision detection d3js矩形碰撞检测d3js
【发布时间】:2013-10-12 16:30:29
【问题描述】:

我正在尝试在我的 svg 强制布局 (d3js) 中创建碰撞检测。 我已经按照this 教程进行了圆形碰撞。

由于某种原因,它不适用于矩形。我尝试过使用面纱中的参数。

这是我的代码:

var node = svg.selectAll(".node")
    .data(json.nodes)
      .enter().append("g")
        .attr("class", "node")
        .call(force.drag);

    node
        .append("rect")
            .attr("class", "tagHolder")
            .attr("width", 60)
            .attr("height", 60)
            .attr("rx", 5)
            .attr("ry", 5)
            .attr("x", -10)
            .attr("y", -10);  

还有这个:

 svg.selectAll(".node")
      .attr("x", function(d) { return d.x; })
      .attr("y", function(d) { return d.y; });

    link.attr("x1", function(d) 
        { 
            return d.source.x; 
        })
          .attr("y1", function(d) { return d.source.y; })
          .attr("x2", function(d) { return d.target.x; })
          .attr("y2", function(d) { return d.target.y; });

    node.attr("transform", function(d) 
    { 
        return "translate(" + d.x + "," + d.y + ")"; 
    });
});

和碰撞函数:

function collide(node) {
    var r = 30,
        nx1 = node.x - r,
        nx2 = node.x + r,
        ny1 = node.y - r,
        ny2 = node.y + r;

    return function(quad, x1, y1, x2, y2) 
    {
        if (quad.point && (quad.point !== node)) 
        {
            var x = node.x - quad.point.x,
                y = node.y - quad.point.y,
                l = Math.sqrt(x * x + y * y),
                r = 30 + quad.point.radius;
            if (l < r) 
            {
                l = (l - r) / l * .5;
                node.x -= x *= l;
                node.y -= y *= l;
                quad.point.x += x;
                quad.point.y += y;
            }
        }

        return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
     };
}

如何检测矩形的碰撞?

谢谢!!!

【问题讨论】:

  • 我有同样的问题,虽然可能比你的例子更进一步。我对碰撞函数所做的更改有些不对劲,因为我在矩形之间得到了太多的排斥:bl.ocks.org/dobbs/1d353282475013f5c156

标签: javascript jquery svg d3.js


【解决方案1】:

d3 示例中的碰撞函数通过比较圆心l = Math.sqrt(x * x + y * y) 与其半径之和r = node.radius + quad.point.radius 之间的距离来计算圆的重叠。当l &lt; r 圆圈重叠时,两个圆圈相互移开以纠正重叠。

类似的矩形碰撞函数以相同的方式工作,通过计算矩形的重叠并将每个矩形移开:

function collide(node) {
  var nx1, nx2, ny1, ny2, padding;
  padding = 32;
  nx1 = node.x - padding;
  nx2 = node.x2 + padding;
  ny1 = node.y - padding;
  ny2 = node.y2 + padding;
  return function(quad, x1, y1, x2, y2) {
    var dx, dy;
    if (quad.point && (quad.point !== node)) {
      if (overlap(node, quad.point)) {
        dx = Math.min(node.x2 - quad.point.x, quad.point.x2 - node.x) / 2;
        node.x -= dx;
        quad.point.x += dx;
        dy = Math.min(node.y2 - quad.point.y, quad.point.y2 - node.y) / 2;
        node.y -= dy;
        quad.point.y += dy;
      }
    }
    return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
  };
};

宽度重叠为dx = Math.min(node.x2 - quad.point.x, quad.point.x2 - node.x) / 2;,高度重叠为dy = Math.min(node.y2 - quad.point.y, quad.point.y2 - node.y) / 2;,这表明您的节点必须知道矩形的两个角:左上角(x, y)和右下角(x2, y2)

在此处查看完整示例:http://bl.ocks.org/dobbs/1d353282475013f5c156。该示例使用咖啡脚本,并且仅沿 y 轴 'cos 将矩形移开,以更好地匹配我自己的情况所需的内容。

【讨论】:

  • 非常好,非常感谢。我一直在寻找这样的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多