Return intersection position and size

2019-09-15 01:07发布

问题:

I'm developing a minigame using the HTML5 canvas tag and I've found a problem (that you can see here) and, to solve it, I need to check a intersection between every rect in a array (done) and return the intersection position and size (and I can't do this since I've a really poor math knowledge). Can someone help me?

Here's the rect array collision detection:

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

And here is the entire code, in JSFiddle

The objective of this calculation is that I need to disable any collision between the hero and a rectangle inside a rectangle intersection. e.g. this area:

回答1:

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

If you have 2 rects defined like this:

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:

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


回答2:

This jsfiddle will give you the intersecting rectangle for two rectangle. Width will be zero for no intersection.

function rectangle(left,top, width, height) {
    this.left=left;
    this.top=top;
    this.width=width;
    this.height=height;
    this.right=this.left+this.width;
    this.bottom=this.top+this.height;

    //method
    this.intersect=intersect;
}

function intersect(rect) {
    if(this.left>rect.left) {
        var rightRect=this;
        var leftRect=rect;
    }
    else {
        var rightRect=rect;
        var leftRect=this;
    }
    if(this.top>rect.top) {
        var topRect=rect;
        var botRect=this;
    }
    else {
        var topRect=this;
        var botRect=rect;
    }
    if(this.right>rect.right) {
        var furtherRect=this;
        var nearerRect=rect;
    }
    else {
        var furtherRect=rect;
        var nearerRect=this;
    }
    if(this.bottom>rect.bottom) {
        var lowerRect=this;
        var upperRect=rect;
    }
    else {
        var lowerRect=rect;
        var upperRect=this;
    }
    if(rightRect.left>leftRect.left+leftRect.width || botRect.top>topRect.top+topRect.height) {
        var intersection=new rectangle(0,0,0,0);
    }
    else {
        var intersection=new rectangle(rightRect.left,botRect.top,nearerRect.right-rightRect.left,upperRect.bottom-botRect.top);
    }
    return intersection;

}

However if there are more than two rectangles where do you want the collision to be disabled. For example which of the two yellow areas below?

EDIT Image corrected

Of course there are then various ways that 3 rectangles, R1, R2 an R3 can intersect

R1 with R2 but neither with R3

R1 with R2 and R1 with R3 but with the intersections of R1 with R2 and R1 with R3 not intersecting

and various other ways.

The more rectangles the more possibilities.