6
\$\begingroup\$

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!

\$\endgroup\$
4
  • \$\begingroup\$ Already answered here : gamedev.stackexchange.com/questions/9741/… \$\endgroup\$ Feb 17, 2012 at 13:28
  • \$\begingroup\$ Read that. Didn't help me, just made me more confused haha. \$\endgroup\$ Feb 17, 2012 at 13:30
  • \$\begingroup\$ Can you maybe explain how you "detected the collision"? This will help understand the kind of information that is available. \$\endgroup\$ Feb 17, 2012 at 14:08
  • \$\begingroup\$ 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). \$\endgroup\$ Feb 17, 2012 at 14:12

4 Answers 4

2
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$ Feb 17, 2012 at 14:30
8
\$\begingroup\$

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

\$\endgroup\$
7
  • \$\begingroup\$ 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 \$\endgroup\$ Feb 17, 2012 at 14:58
  • \$\begingroup\$ Correct. I thought "side" only meant left or right. I will update my answer. \$\endgroup\$ Feb 17, 2012 at 15:07
  • \$\begingroup\$ 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! \$\endgroup\$ Feb 17, 2012 at 15:39
  • \$\begingroup\$ @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. \$\endgroup\$ Feb 17, 2012 at 16:00
  • \$\begingroup\$ 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? \$\endgroup\$ Feb 17, 2012 at 16:09
0
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

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!

\$\endgroup\$
3
  • \$\begingroup\$ 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! \$\endgroup\$ Feb 17, 2012 at 14:31
  • \$\begingroup\$ You could use a bounding rectangle around your other shapes and/or sprites \$\endgroup\$
    – amb
    Feb 17, 2012 at 14:47
  • \$\begingroup\$ @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. \$\endgroup\$
    – Nic Foster
    Feb 17, 2012 at 15:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .