javascript - Collisionoverlap detection of circles in a d3 transition - Stack Overflow

I'm using d3 to animate a route (path) on a map. When the route reaches a point along the route I&

I'm using d3 to animate a route (path) on a map. When the route reaches a point along the route I'd like to popup some information.

Most of my code is based on the following example. . I'm really just trying to determine if there is a way to detect when the transitioning circle collides or overlaps any of the stationary circles in this example.

I'm using d3 to animate a route (path) on a map. When the route reaches a point along the route I'd like to popup some information.

Most of my code is based on the following example. http://bl.ocks/mbostock/1705868. I'm really just trying to determine if there is a way to detect when the transitioning circle collides or overlaps any of the stationary circles in this example.

Share Improve this question asked Feb 21, 2015 at 15:42 shadcshadc 331 silver badge4 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

You can detect collision in your tween function. Define a collide function to be called from inside the tween function as follows:

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;
}

Where points are the stationary points, and node is the transitioning element. What collide does is check whether node overlaps with any of the points (as shown in collision detection example here).

Because we need the node to be passed to the tween function, we replace attrTween used in Mike's example, with tween:

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

Finally, the tween function calling our 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")
    };
  };
}

See the full demo here

The easiest way is to just check how "close" the transitioning circle is to the other points.

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 + ")";
    };
  };
}

The faster the circle moves the greater your epsilon will need to be.

Example here.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744310979a4567944.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信