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.

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?

share|improve this question

4 Answers 4

up vote 2 down vote accepted

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.

1b) 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.

2) 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.

By coincidence, I am presenting online on Wed 24 March on this very topic for Microsoft UK Tech Days. If you want to see the system in action, see some slides detailing the process above, or ask questions then you can register here.

share|improve this answer
    
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? –  Zolomon Mar 15 '11 at 11:34
    
Thank you for the link, can't seem to find the slides though! –  Zolomon Mar 15 '11 at 11:41
1  
Hi Zolomon - the talk is next Wednesday (24 March 2011), so slides and movies will be posted in time for that. 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. –  VeraShackle Mar 15 '11 at 15:17
    
(Link is broken at the moment.) –  Zolomon Mar 25 '11 at 13:30
    
Hi Zolomon - I've fixed the link, it seems everything got moved once the meeting was done. Apologies. –  VeraShackle Mar 30 '11 at 13:58

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.

share|improve this answer
    
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). –  Michael Coleman Mar 14 '11 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.

share|improve this answer
    
ifile.it/fy1n0ia Here's an example of how my collision detection and resolution stuff is working. If you're interested. –  ultifinitus Mar 14 '11 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;
share|improve this answer
    
Answers that are just code aren't too useful. Adding some explanation would make this answer better. –  Byte56 Jun 1 '12 at 19:15

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.