Simple rectangle 2d colision detection -Am I the only one who doesn't get it?

Started by
5 comments, last by Zahlman 15 years, 2 months ago
Note: I've extensively searched the internet and this site for answers to no avail. It seems that this is such a simple problem that no one has cared to talk about it. I am not coming here as a first resort so no www.google.com or RTFM posts please. Having been hung on this issue for more than 3 months (passively for more than a year), this is probably my last resort before I give up for a while. Basically what I need to be able to do is know what side of rectangle B rectangle A has just hit. This is for a platformer I am making, I need to know weather to stop the player from going left, right, up, or down. Most things sort of worked, but all had times where a collision from one part would detected as another. I am at the point where I have no idea what I am doing. I hate doing this on forums, but how the heck do I do this? I'm generally a great problem solver, I am generally very good with these types of things, I'm sure if I see someone else's working code I will be able to do it too. Thanks in advance for your help.
Advertisement
Okay so it sounds like you've got the collision detection part pretty much sorted out, but you're having trouble with the collision response. For AABB's (axis-aligned bounding boxes), a common way to handle it is to figure out which direction would require the smallest movement to prevent the collision. Then you just move one of the boxes in that direction, and adjust the velocity.

In code it looks something like this...
BoundingBox box1 = object1.GetBoundingBox();BoundingBox box2 = object2.GetBoundingBox();if (box1.Intersects(box2)){                                                    const float stepUpTolerance = 2.0f;    float left = Abs(box1.max.X - box2.min.X);    float down = Abs(box1.max.Y - box2.min.Y);    float right = Abs(box1.min.X - box2.max.X);    float up = Abs(box1.min.Y - box2.max.Y) - stepUpTolerance;	float minComponent = Min(Min(Min(left, right), up), down);        collisionResponse = Vector2.Zero;    if (minComponent == left)        collisionResponse.X = -minComponent;    if (minComponent == right)        collisionResponse.X = minComponent;    if (minComponent == down)        collisionResponse.Y = -minComponent;    if (minComponent == up)        collisionResponse.Y = minComponent + stepUpTolerance;    Vector2 oldObject1Position = object1.Position - (object1.Velocity * dt);    object1.Position += collisionResponse;    object1.Velocity = (object1.Position - oldObject1Position) / dt;}


It's pretty simple. If the two boxes collide, figure out the direction you can move it where you'd have to move it the least. The stepUpTolerance part is optional...if you have this it lets your character "step up" small distances, for instances things like stairs.
Sounds like it will work, I'll try it as soon as I can. Thanks a ton!
Quote:Original post by Daniel B
Basically what I need to be able to do is know what side of rectangle B rectangle A has just hit.

You should be aware that in some situations there's no clear answer to this. The corners could overlap, or one box could entirely contain the other.
Construct (Free open-source game creator)
Quote:Original post by AshleysBrain
You should be aware that in some situations there's no clear answer to this. The corners could overlap, or one box could entirely contain the other.
That's only true if all you know is the current position. Usually you have both the current position and the previous position allowing you to construct an approximate, but generally accurate, linear path between the two points; alternatively if the object's motion is calculated as a function of time then the exact path may already be known. You can then determine (either mathematically or by multi-sampling) the point along the path that the two boxes collided and so find the edges at which that collision took place.
Quote:Original post by Daniel B
Note: I've extensively searched the internet and this site for answers to no avail...I am at the point where I have no idea what I am doing. I hate doing this on forums, but how the heck do I do this?
The math is fairly simple linear algebra. That should help your search.

Although you might be able to fumble along without the education, you really should learn the math properly. Either get very comfortable with a college textbook and do all the problems, or take a class on the subject (or both).

Quote:I'm sure if I see someone else's working code I will be able to do it too.
If you can't figure out the math on paper, there is no way you can write code for it.

Writing code is explaining to the computer how to do the process. If you don't already know the process, then explaining it is impossible.
Quote:Original post by Daniel B
I am not coming here as a first resort so no www.google.com or RTFM posts please. Having been hung on this issue for more than 3 months (passively for more than a year), this is probably my last resort before I give up for a while.


I do not understand how that could possibly be true.

When I google for collision detection, the fourth hit is for this tutorial, which explains partway down:

Quote:
If the objects overlap along all of the possible separating axes, then they are definitely overlapping each other; we've found a collision, and this means we need to determine the projection vector, which will push the two objects apart.

At this point, we've already done most of the work: each axis is a potential direction along which we can project the objects. So, all we need to do is find the axis with the smallest amount of overlap between the two objects, and we're done -- the direction of the projection vector is the same as the axis direction, and the length of the projection vector is equal to the size of the overlap along that axis.


The "projection vector" here indicates which side was hit - in fact, it gives you the information you need directly ("how do I move the object in order to restore it to be just touching instead of intersecting?").

This topic is closed to new replies.

Advertisement