簡體   English   中英

d3過渡中圓的碰撞/重疊檢測

[英]Collision/overlap detection of circles in a d3 transition

我正在使用d3為地圖上的路徑(路徑)設置動畫。 當路線到達路線上的某個點時,我想彈出一些信息。

我的大多數代碼都基於以下示例。 http://bl.ocks.org/mbostock/1705868 我真的只是想確定是否有一種方法來檢測過渡圓在這個例子中何時碰撞或重疊任何靜止圓圈。

您可以檢測補間功能中的沖突 定義要從補間函數內部調用的collide函數,如下所示:

function collide(node){
    var trans = d3.transform(d3.select(node).attr("transform")).translate,
      x1 = trans[0],
      x2 = trans[0] + (+d3.select(node).attr("r")),
      y1 = trans[1],
      y2 = trans[1] + (+d3.select(node).attr("r"));

  var colliding = false;
  points.each(function(d,i){
    var ntrans = d3.transform(d3.select(this).attr("transform")).translate,
      nx1 = ntrans[0],
      nx2 = ntrans[0] + (+d3.select(this).attr("r")),
      ny1 = ntrans[1],
      ny2 = ntrans[1] + (+d3.select(this).attr("r"));


      if(!(x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1))
        colliding=true;
  })

  return colliding;
}

其中points是靜止點, node是過渡元素。 collide作用是檢查node是否與任何node 重疊 (如此處的碰撞檢測示例所示)。

因為我們需要將node傳遞給補間函數,所以我們將替換Mike示例中使用的attrTweentween

circle.transition()
      .duration(10000)
      .tween("attr", translateAlong(path.node()))
      .each("end", transition);

最后,調用我們collide的補間函數:

function translateAlong(path) {
  var l = path.getTotalLength();
  return function(d, i, a) {
    return function(t) {
      var p = path.getPointAtLength(t * l);

      d3.select(this).attr("transform","translate(" + p.x + "," + p.y + ")");

      if(collide(this))
        d3.select(this).style("fill", "red")
       else
        d3.select(this).style("fill", "steelblue")
    };
  };
}

請在此處查看完整演示

最簡單的方法是檢查過渡圓圈與其他點的“接近”程度。

var pop = d3.select("body").append("div")
    .style("position","absolute")
    .style("top",0)
    .style("left",0)
    .style("display", "none")
    .style("background", "yellow")
    .style("border", "1px solid black");

// Returns an attrTween for translating along the specified path element.
function translateAlong(path) {
  var l = path.getTotalLength();
  var epsilon = 5;
  return function(d, i, a) {
    return function(t) {
      var p = path.getPointAtLength(t * l);
      points.forEach(function(d,i){
        if ((Math.abs(d[0] - p.x) < epsilon) && 
            (Math.abs(d[1] - p.y) < epsilon)){
          pop.style("left",d[0]+"px")
            .style("top",d[1]+20+"px")
            .style("display","block")
            .html(d);
          return false;
        }
      })
      return "translate(" + p.x + "," + p.y + ")";
    };
  };
}

圓圈移動得越快,你的epsilon就越大。

這里的例子。

在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM