Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am working on an Android game and I have two objects A and B (both rectangles) and when they collide I simply want to know which side of B was hit. I have detected the collision fine, but I am having trouble figuring out which side of the rectangle B took the hit? Any ideas? Thanks!

share|improve this question
    
Already answered here : gamedev.stackexchange.com/questions/9741/… –  Takumi Feb 17 '12 at 13:28
    
Read that. Didn't help me, just made me more confused haha. –  Alex_Hyzer_Kenoyer Feb 17 '12 at 13:30
    
Can you maybe explain how you "detected the collision"? This will help understand the kind of information that is available. –  Sam Hocevar Feb 17 '12 at 14:08
    
I have two objects both have bounding boxes. The bounding boxes are of the type RectF. There is a function Android called RectF.intersects(RectF one, RectF two) that I use to determine if they are colliding. From here I just can't seem to get determine which side of object B (the stationary rect) is being hit by object A (the moving rect). –  Alex_Hyzer_Kenoyer Feb 17 '12 at 14:12

4 Answers 4

up vote 2 down vote accepted

You can calculate the centroid (it's easy to calculate, google for a formula) of both rectangles and compare them.

I'm saying this, because it's a general solution, i have no idea how you do your collision detection, there are plenty of variables here like size and speed of the rectangles (if your rectangles move too fast and you're not doing sweep testing, then you might "overshoot" and it'll look like the collision was from the other side). It's not the most elegant solution either, but you only do this once when the collision happens, so it shouldn't be too bad, though that depends on the amount of collisions. You're not giving enough information.

share|improve this answer
    
I will look into this. It seems like it might do the trick. I only have two objects colliding and the collision detection is done through bounding boxes. –  Alex_Hyzer_Kenoyer Feb 17 '12 at 14:30

I suggest computing the Minkowski sum of B and A, which is a new rectangle, and checking where the centre of A lies relatively to the diagonals of that rectangle:

float wy = (A.width() + B.width()) * (A.centerY() - B.centerY());
float hx = (A.height() + B.height()) * (A.centerX() - B.centerX());

if (wy > hx)
    if (wy > -hx)
        /* top */
    else
        /* left */
else
    if (wy > -hx)
        /* right */
    else
        /* bottom */

Edit: use Minkowski sum and fix variable names

share|improve this answer
    
But what happens when object A is coming down on top of object B where the center x of object A is less than the center x of object B –  Alex_Hyzer_Kenoyer Feb 17 '12 at 14:58
    
Correct. I thought "side" only meant left or right. I will update my answer. –  Sam Hocevar Feb 17 '12 at 15:07
    
Hmmm... I have done exactly what you posted and it seems to sort of work haha. I have found that it has problems with corners as well as problems with the top and bottom. I'll play around with this a bit though. Thanks! –  Alex_Hyzer_Kenoyer Feb 17 '12 at 15:39
    
@Alex_Hyzer_Kenoyer: I am pretty confident this algorithm works properly for rectangles. But I see in another comment that A may actually be a ball, not a rectangle. Could that be the problem? If so, you should change the question (or maybe ask another one), because it changes the complexity of the problem. –  Sam Hocevar Feb 17 '12 at 16:00
    
My plan is to make this collision work with a ball hitting a rectangle. Right now I just wanted to play around with the rectangle on rectangle collision. I have gotten it very close. I have a ball image bouncing around the screen and it bounces off of the rectangle correctly but there is obviously some problem because my image is a circle... Do you think I should just go down the road of asking a question about a ball hitting a rectangle? –  Alex_Hyzer_Kenoyer Feb 17 '12 at 16:09

Compare A and B to see where they are in regards to each other.

A width 20 height 20 A xmin + pos, xmax + pos A ymin + pos, ymax + pos

Same above for B.

if A xmax + pos (left side) < B xmin + pos A is on left of B, B left side hit..

etc etc.

share|improve this answer

Are you using the Rect class? http://developer.android.com/reference/android/graphics/Rect.html

If so, some simple comparisons will left you know which side collided... From the Rect class, you have attributes for the top (or North), the bottom (or South), the left (or West), and the right (or East).

For example, this test will determine if rectB's left side crossed rectA's right side:

if ((rectB.left >= rectA.left) && (rectB.left <= rectA.right))

Remember that rectB could collide with two sides. Image rect B's lower left hand corner crossing over rect A's upper right...rect B would've crossed over rectA's top and right edges.

Remember that if rectB is completely inside rectA, that would look like it crossed over all four sides of rectA!

share|improve this answer
    
This does work for me, though like you said with the corners it is not perfect... I have changed my image to a ball, and I guess I will need to take into account that the ball has very small point of contact so I can't do this completely with rectangles. Though I think I am getting close. Thanks! –  Alex_Hyzer_Kenoyer Feb 17 '12 at 14:31
    
You could use a bounding rectangle around your other shapes and/or sprites –  amb Feb 17 '12 at 14:47
    
@Alex_Hyzer_Kenoyer: You need to calculate the time-of-impact over the last frame, this will give you the exact collision point between the two rectangles. Based on how deep the collision is, and the velocities of the two objects, you should be able to calculate how long ago they would have collided, which will give you an accurate picture over which side(s) the collision happened on. –  Nic Foster Feb 17 '12 at 15:07

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.