# Two rectangles colliding

## Recommended Posts

There is a tutorial here that explain how to check if two 2D-rectangles collide. It works excellent in most cases in my game.
There is an other case where I need to check if the unit is colliding from the right, left, up or down. I am having trouble getting this function to work.

Anyone have or know a piece of code that works(C/C++/Java/C#)?

##### Share on other sites
I use to solve this by having a "direction" of the objects. If you have for example an enemy object then you can use
if(x1.intersects(x2)){

if(enemy.dx == 1)
- do something
if(enemy.dx == -1)
- do something
if(enemy.dy == 1)
- do something
if(enemy.dy == -1)
- do something

Maybe that's a bad method, but I use it

##### Share on other sites
You can use Dot Product for this purpose.

Consider [b]PlayerDir [/b]as a vector pointing in direction the player looks and [b]EnemyDir[/b] is the direction in which an enemy moves.

Using following calculation :
[CODE]
(PlayerDir.x * EnemyDir.x + PlayerDir.y * EnemyDir.y);
[/CODE]

you get the value of cosine between their directions. Importantly, make sure that [b]PlayerDir [/b]and [b]EnemyDir [/b]are normalized! Otherwise you have to divide your result by length of both vectors!

If result was positive it means, that player and enemy moved in the same direction, so the player was hit in the back. If negative than, they moved in opposite directions. If you get value really close to 0, it means the player was hit from the side. Edited by DgekGD

##### Share on other sites
I've implemented a simple collision detection/response method for a 2d platform game project. At the moment, the only response I've coded is between player and platform collisions.

Collision util functions are defined here:
https://github.com/larsbutler/gamedemo/blob/master/src/com/larsbutler/gamedemo/math/Collision.java

And everything is used here:
https://github.com/larsbutler/gamedemo/blob/master/src/com/larsbutler/gamedemo/core/GameState.java#L95

This method would need to be optimized for lots of collisions, but for a low number it works well; it's reliable and stable.

I hope that helps.

##### Share on other sites
We have rectangles R1 and R2. R1 has middle point (x1,y1), height h1, width w1, and is moving at velocity (vx1, vy1). Same stuff for R2.

Now let's assume we know there's a sideways collision between rectangles R1 and R2. It's really easy to determine which side the collision is on: you just look at their relative velocities. If vx2-vx1>0, R2 hit R1 from the left, otherwise it hit R1 from the right. If we know we have a vertical collision, same thing, we check vy2-vy1>0.

Looking at the middle points, x2-x1>0, would also work if the rectangles move slowly relative to their size. If they move so fast that one rectangle is already more than halfway inside the other when the collision check happens, this will produce a collision from the wrong side whereas velocities would produce the right result. Of course, if the rectangles move even faster, they will get past each other entirely before the collision check happens. To prevent that you'd have use a different strategy to check for collisions in the first place.

So that was trivial. The more interesting part is determining whether your collision is sideways or vertical. This is how I'd go about checking it:
1) For a collision to have happened, the rectangles must now be overlapping in both x and y directions.
2) We assume this is the first frame when the collision happens.
3) Therefore, on the last frame, the collision was not happening, and that means either the rectangles were overlapping in x direction, overlapping in y direction, or neither.
4) The last direction of those two directions which came to overlap is the collision direction.
(how to check presence of overlap between two rectangles in x-direction: abs(x1-x2) < (w1+w2)/2)
5) We check overlap between oldR1 and oldR2.
(we can get the old coordinates from new coordinates and velocity; oldx1 = x1-vx1, oldy1 = y1-vy1 and so on).
6) If there was x overlap between oldR1 and oldR2, the collision is vertical, because it's impossible for two rectangles overlapping in x direction to move in a straight line and collide horizontally. If there was y overlap between oldR1 and oldR2, the collision is horizontal.
7) In the special case that there was no x-overlap and no y-overlap, both overlaps occurred between last frame and this frame. Now it is slightly harder to figure out which of those overlaps occurred first and which occurred last. We'll call the moment of time when x overlap happened as timex and its counterpart as timey. With the exact same logic as before, if timex < timey is true, the collision is vertical, otherwise it is horizontal.
8) How to get timex and timey? It's elementary physics; distance divided by velocity equals time. In this case, the distance is the gap between the rectangles, and the velocity is the rectangles' [i]relative[/i] velocity.
(timex = gapx / vx = (abs(oldx2-oldx1)-(w1+w2)/2) / abs(vx2-vx1)) Edited by Stroppy Katamari

##### Share on other sites
Thanks for the help.
I have resolved this problem.

I appreciate the great help, looking forward to stay here

##### Share on other sites
[quote name='P0jahn' timestamp='1354064350' post='5004771']
I have resolved this problem.
[/quote]It would be considerate to tell [i]how[/i] you resolved your problem, both for the benefit of those who have the same problem later, and for the benefit of those who tried to give you advice.

##### Share on other sites
Funny you should mention this, I just finished posting a two part tutorial on bounding box collisions.

[url="http://www.gamefromscratch.com/post/2012/11/26/GameDev-math-recipes-Collision-detection-using-an-axis-aligned-bounding-box.aspx"]Part One[/url] -- covers the concept of an AABB in the first place, as well as having the code to check for a rectangle on rectangle collision.
[url="http://www.gamefromscratch.com/post/2012/11/28/GameDev-math-recipes-Collision-detection-using-an-axis-aligned-bounding-box-part-2.aspx"]Part Two[/url] -- which I literally posted 15 minutes ago, covers resizing the bounding box as your sprite rotates.

Both samples have a running example in the browser ( JavaScript using Easel ), but break out the math specific parts into their own section and have a complete explanation how everything works. Although the samples are in JavaScript, the code is basically 90% compatible with C#/C++/Java, so you only need to change a few key words to get it to compile in your language of choice ( which is why I went with JavaScript for examples... that and obviously it runs in the browser ).

##### Share on other sites
My solution is irrelevant because uses variables that are exclusive to my game(and not to an actual rectangle) to calculate this. Edited by P0jahn

##### Share on other sites
Well my so called "solution" was limited to work with one single situation and the code is not reusable.
I want a global method to check this, so I have looked a bit closer at Stroppy Katamaris post.
With all due respect, your text is cryptic. Why is velocity needed? [i]Old[/i] R2? timex/timey?

##### Share on other sites
The simplest method is to 1st move the object in the X-axis, check if it's intersects anything; if so, you know if u hit it on left or right (based on velocity), and you should move it back along the x-axies.

Then, move it on the y-axis, and check if it collided, and, if so, you know if it hit top or bottom based on Y velocity.

The obvious downside is you do 2 checks, but it's probably not a problem unless you have tons of objects you are checking against. If so, you should do some spatial hashing, but don't worry about that unless you have to.

Good luck.

##### Share on other sites
Sounds like a working solution. But what would happen if this test is performed when they are intersecting already?

##### Share on other sites
[quote name='P0jahn' timestamp='1355425481' post='5010316']
But what would happen if this test is performed when they are intersecting already?
[/quote]

How can that happen, and why is it any different from any other collision test check? If you've written your code right, you should never enter a new movement loop when your character is already intersecting with something else, unless it's meant to be.

##### Share on other sites
It can happen if you have a moving object that's driving collision detection and a moving object that's not. I ran into that problem in my breakout clone - the ball drives collision, but the paddle can also move (and thus come to intersect the ball).

I solved that by adding a property to the paddle that caused it to cease being collidable for a few frames after collision. There was no other reasonable response in that case since the paddle does not react to the ball physically. In terms of objects that follow the normal rules of physics, though, the answer is simply to run testing for all objects as they move.

##### Share on other sites
[quote name='P0jahn' timestamp='1355419633' post='5010278']
Well my so called "solution" was limited to work with one single situation and the code is not reusable.
I want a global method to check this, so I have looked a bit closer at Stroppy Katamaris post.
With all due respect, your text is cryptic. Why is velocity needed? [i]Old[/i] R2? timex/timey?
[/quote]If you just have the locations of two overlapping rectangles, there is no way to tell accurately whether they collided vertically or horizontally. You have to know where they came from, in other words, where they were at last frame. Current position minus velocity gives you that last position, so you don't have to store the last position separately.

I have revised the post. It was indeed cryptic but should be a lot easier to follow now. I also made an error with a formula that is now fixed. Please follow the logic of the numbered steps, trying to understand each one before moving to the next, and ask for help if you get stuck at some specific part.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628347
• Total Posts
2982204

• 10
• 9
• 24
• 11
• 9