# Side detection on Rectangle collision detection?

How can I determine which of the sides on a Rectangle that was hit by another Rectangle (or Circle if that's easier)?

I originally tried creating 8 subrectangles for my main rectangle - one for each side and corner - with the appropriate length and width of one pixel. This didn't work out very well though, to my understanding it was thwarted by the speed and update frequency...

Any thoughts?

I found this to be quite a thorny problem recently. I have a fully working Box-Sphere system up and running now though.

My solution was to represent my rectangle as 4 planes. I test the sphere centre's distance from each plane and compare this to the sphere radius to see if there is an intersection (you do this with the framework Plane.DotCoordinate method). At the same time I count how many distances are positive - this is effectively a check to see if the point is in front of each plane. Finally I accumulate the the normals & distances of the intersecting planes to make a single composite 'collision vector' to deal with edge and corner collisions with multiple planes.

Once you have these 3 bits of info you can check a few things:

1. If you are in front of none of the planes, definitely a collision and just check to see which one is intersecting to find which side was hit.

a. In front of no planes, but no intersections - complete containment. This is the worst case and I cast back a ray along the objects velocity vector to see which side it hit on its way in.

1. In front of the same number of planes as there are intersections. This maybe a collision, but only if the intersection distance along the collision vector is less than the sphere radius. This case actually deals with face, edge and corner collisions (1, 2 or 3+ planes) in one go.

I hope you can follow such a long-description, but the logic is probably more important than the code.

Plus, a major upside of this this approach is it is trivially generalisable to 3D and you can add as many planes as you like to define the collision volume - provided your shape always remains convex. This technique is a version of the pattern often called Discrete Orientated Polytopes - or DOP if you want to look it up in the literature I think.

I did an online presentation for Microsoft UK Tech Days. If you want to see the slides detailing the process above, check here.

• This approach works for 2D as well I take it, just ignore the Z-part from the planes and calculate the distance form the origin of the circle and the middle of the planes? Mar 15, 2011 at 11:34
• Hi Zolomon - I believe you should be able to apply this approach to 2D rectangles & circles instead of boxes and spheres, but I'm afraid I have currently implemented it in 3D only. Mar 15, 2011 at 15:17

Compare the X and Y coordinates of both rectangles. Apart from strange cases (like one rectangle being submerged entirely in another, or one rectangle being a super-set of the other) these should be sufficient to tell you.

If you have the middle-point of the two shapes, that might also be an easier way to tell the relative positioning of the two objects.

• Another special case might be when the rectangles collide equally on 2 sides (like a corner collision). I wonder if factoring in the velocity vector would help (if the rectangles are moving). Mar 14, 2011 at 2:42

Gosh I find myself referring to my code a lot =D

What I do is check your previous position, to see if it was previously outside of the rectangle, this works flawlessly in my game engine =)

to get the previous position I use an update method, which I call once a frame.

• ifile.it/fy1n0ia Here's an example of how my collision detection and resolution stuff is working. If you're interested. Mar 14, 2011 at 21:11
            if (DestinationRectangle.Intersects(collisionRect))
{
touchingTheLeftSide = (previousPosition.X + previousPosition.Width) <= collisionRect.X;

touchingTheRightSide = previousPosition.X >= (collisionRect.X + collisionRect.Width);

sittingOnTop = (previousPosition.Y + previousPosition.Height) <= collisionRect.Y;
}

previousPosition = DestinationRectangle;

• Answers that are just code aren't too useful. Adding some explanation would make this answer better. Jun 1, 2012 at 19:15