I have two rectangles which I must return in a function whether they intersect or not.
They are represented by [ x0, y0, x1, y1 ]
pairs that represent the top-left and bottom-right corner of the rectangles. Alternatively, your solution could be [ x0, y0, width, height ]
if its somehow simpler, I can adapt my function's parameter input by it.
I tried to see if any of the two corners from rectangle A are included in rectangle B but if A is larger than B and B is partially included in A, it will say it doesn't overlap. Now I could try A and B but this seems to be a bad way to do things.
I can't premake a big grid and occupy cells by the rectangles because it is unknown what rectangles come as. All I can tell is that they are unsigned integers, min 0 and with an unknown max.
If you want to check if 2 rotated rectangles collide you have to make projection of one rectangle corner on the axes of the other. If all projections of rectA hit the rectB, and rectB projections hit rectA then the two rectangles collide. Some projection don't collide here, the 2 rectangles are not collide.
It is easy to visualize that the given two rectangles can not be intersect if one of the following conditions is true. Condition 1: When left edge of R1 is on the right of R2's right edge. ( That is , R1 is completely on the right of R2). Condition 2: When right edge of R1 is on the left of R2's left edge.
Check for the cases where the rectangles are definitely not intersecting. If none of these cases are true then the rectangles must intersect. i.e.:
public boolean rectanglesIntersect(
float minAx, float minAy, float maxAx, float maxAy,
float minBx, float minBy, float maxBx, float maxBy ) {
boolean aLeftOfB = maxAx < minBx;
boolean aRightOfB = minAx > maxBx;
boolean aAboveB = minAy > maxBy;
boolean aBelowB = maxAy < minBy;
return !( aLeftOfB || aRightOfB || aAboveB || aBelowB );
}
This illustrates the concept but could be made slightly faster by inlining the booleans so as to take advantage of the short-circuiting behavior of ||
After a time I decided to redo a complete answer about detecting collision between 2 rotated rectangles: How to detect when rotated rectangles are colliding each other
If you want to check if 2 rotated rectangles collide you have to make projection of one rectangle corner on the axes of the other. If all projections of rectA hit the rectB, and rectB projections hit rectA then the two rectangles collide.
Some projection don't collide here, the 2 rectangles are not collide.
The 4 projections hit the other rectangle, the 2 rectangles are collide.
I have made a presentation on this JSFiddle for more comprehension.
You can check the function is_collide
for more example
The case turns out to be quite simple if we look at the problem (algorithm) from the other side.
It means that instead of answering the question: "Are the rectangles overlap?", we will answer the question: "Are the rectangles do not overlap?".
In the end, both questions resolve the same problem but the answer to the second question is simpler to implement because rectangles do not overlap only when one is under the other or when one is more to the left of the other (it is enough for one of these cases to take place, but of course it may happen that both will happen simultaneously - here a good understanding of the logical condition "or" is important). This reduces many cases that need to be considered on the first question.
The whole matter is also simplified by the use of appropriate variable names:
const areRectanglesOverlap = (rect1, rect2) => {
let [left1, top1, right1, bottom1] = [rect1[0], rect1[1], rect1[2], rect1[3]],
[left2, top2, right2, bottom2] = [rect2[0], rect2[1], rect2[2], rect2[3]];
// The first rectangle is under the second or vice versa
if (top1 < bottom2 || top2 < bottom1) {
return false;
}
// The first rectangle is to the left of the second or vice versa
if (right1 < left2 || right2 < left1) {
return false;
}
// Rectangles overlap
return true;
}
Even if we have a different representation of a rectangle, it is easy to adapt the above function to it by modifying only the section where the variables changes are defined. The further part of the function remains unchanged (of course, the comments are not really needed here, but I added them so that everyone could quickly understand this simple algorithm).
An equivalent but maybe a little less readable form of the above function may look like this:
const areRectanglesOverlap = (rect1, rect2) => {
let [left1, top1, right1, bottom1] = [...rect1],
[left2, top2, right2, bottom2] = [...rect2];
return !(top1 < bottom2 || top2 < bottom1 || right1 < left2 || right2 < left1);
}
Two rectangles are overlapping if both the x and the y areas Overlap. If any of the x co-ordinates overlap the other rectangles, then there will be an over lap.
Along the x axis, either the first point is within the other two rectangles, the second point is within the other two, or two points are on opposite sides of the other points.
function checkRectOverlap(rect1, rect2) {
/*
* Each array in parameter is one rectangle
* in each array, there is an array showing the co-ordinates of two opposite corners of the rectangle
* Example:
* [[x1, y1], [x2, y2]], [[x3, y3], [x4, y4]]
*/
//Check whether there is an x overlap
if ((rect1[0][0] < rect2[0][0] && rect2[0][0] < rect1[1][0]) //Event that x3 is inbetween x1 and x2
|| (rect1[0][0] < rect2[1][0] && rect2[1][0] < rect1[1][0]) //Event that x4 is inbetween x1 and x2
|| (rect2[0][0] < rect1[0][0] && rect1[1][0] < rect2[1][0])) { //Event that x1 and x2 are inbetween x3 and x4
//Check whether there is a y overlap using the same procedure
if ((rect1[0][1] < rect2[0][1] && rect2[0][1] < rect1[1][1]) //Event that y3 is between y1 and y2
|| (rect1[0][1] < rect2[1][1] && rect2[1][1] < rect1[1][1]) //Event that y4 is between y1 and y2
|| (rect2[0][1] < rect1[0][1] && rect1[1][1] < rect2[1][1])) { //Event that y1 and y2 are between y3 and y4
return true;
}
}
return false;
}
Give rectangle 1 with points UL1 and LR1 and rectangle 2 with points UR2 and LR2 -
Check if UL1 is in r2 or LR1 is in r2 (case 1 and case 2 in diagram). Finally check if one of UR2 / LR2 is in r1 (case 3 in diagram).
You check if a point is in a rectangle by checking that x and y are between min and max of a rectangles' x and y range.
Clear?
Blue is R1, Purple is R2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With