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