Search code examples
javascripthtml5-canvascollision-detection

Return intersection position and size


I'm developing a game and I've found (a problem) and, to solve it, I need to return the intersection position and size.

Here's the rectangle collision detection code:

for (var i = 0; i < rects.length; i++) {
    for (var others = 0; others < rects.length; others++) {
        if (others != i) {
            if (rects[others].y + rects[others].height >= rects[i].y &&
                rects[others].x + rects[others].width >= rects[i].x &&
                rects[others].x <= rects[i].x + rects[i].width &&
                rects[others].y <= rects[i].y + rects[i].height) {
                // They're intersecting!
                intery = 0; // Intersection Y
                interx = 0; // Intersection X
                interw = 0; // Intersection Width
                interh = 0; // Intersection Height
            }
        }
    }
}


Solution

  • A Demo: http://jsfiddle.net/m1erickson/TqRxG/

    If you have 2 rects defined like this:

    enter image description here

    var r1={
      x:40,
      y:40,
      w:50,
      h:30,
    }
    
    var r2={
      x:60,
      y:60,
      w:50,
      h:30,
    }
    

    Then you can calculate their intersection rectangle (if any) like this:

    enter image description here

    function intersectingRect(r1,r2){
      var x=Math.max(r1.x,r2.x);
      var y=Math.max(r1.y,r2.y);
      var xx=Math.min(r1.x+r1.w,r2.x+r2.w);
      var yy=Math.min(r1.y+r1.h,r2.y+r2.h);
      return({x:x,y:y,w:xx-x,h:yy-y});
    }
    

    [ Addition: detect circle-rectangle collision ]

    If you have a circle defined like this:

    var c={
        x:50,
        y:50,
        r:15
    }
    

    Then you can determine if the circle and rectangle are colliding like this:

    function RectCircleColliding(circle,rect){
        var distX = Math.abs(circle.x - rect.x-rect.w/2);
        var distY = Math.abs(circle.y - rect.y-rect.h/2);
        if (distX > (rect.w/2 + circle.r)) { return false; }
        if (distY > (rect.h/2 + circle.r)) { return false; }
        if (distX <= (rect.w/2)) { return true; } 
        if (distY <= (rect.h/2)) { return true; }
        var dx=distX-rect.w/2;
        var dy=distY-rect.h/2;
        return (dx*dx+dy*dy<=(circle.r*circle.r));
    }