Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » collision between two rectangles and resulting angle

This thread is locked; no one can reply to it. rss feed Print
collision between two rectangles and resulting angle
kazzmir
Member #1,786
December 2001
avatar

I have two rectangles that collide with each other, this isnt hard to figure out. I cant quite get how to make them bounce off each other. I dont want to simply exchange velocities and angles. What should happen is if the first square's top edge hits the second square's bottom edge and the first square was moving at an angle of 45 degrees, the first square's angle after collision should be 315 degrees. Like so:
before

     ----
     |  |
     ----
      * ( collision here )
    ---
    | |
    ---
  ' ( moving this way, 45 degrees )
 /
/

after:

    ----
    |  |
    ----
      ---
      | |
      ---
          \
           \
            ' ( moving this way, 315 degrees )

I do some estimations to see which side was hit and then calculate the resulting angle. The problem is when the estimation fails becuase the rectangles hit each other on a corner and its impossible to tell if the side or bottom was hit. Ill post the code I use to determine this estimation, but is there any better way to determine this kind of physics?

orz
Member #565
August 2000

... if your squares use floating point coordinates, a corner bounce should be VERY rare, such that you can simply treat it as a bounce on one of the edges instead (pick an edge, any edge). If your rectangle locations use integer values, the it's a much more common case, so you might consider pretending that the corners are rouned instead (45 degree angle or somesuch) for purposes of corner collisions... or maybe not, if you don't like how that looks. Picking an arbitrary side to collide with for exact matches isn't bad.

Joe Olivieri
Member #2,286
May 2002
avatar

I'm not quite sure which one you want but it may be atan2... I did this same thing - I think I added or subtracted 90 degrees and used atan2 to figure out the resulting angle. I would tell you definitively but I'm working on resuerecting my source repository now... :(

Once I get my repository back up I'll post a real answer unless someone else does. I know I did the exact same thing in my space shooter.

Carrus85
Member #2,633
August 2002
avatar

It shouldn't be to difficult to do it using vectors, right? I mean, you have the two coordinates of the corners, correct? Calculate the vectors for those coordinates, calculate the resulting vector, apply that to the entire rectangle. Bingo. Simple as pie.

Now, if only I could find my code for that...

Basically you would have to find a tangent to the motions of both of the squares and reflect the vector across it. Dang, I wish my hard drive wasn't fried.

David Layne
Member #2,053
March 2002

Since your dealing with rectangles only, the situation is greatly simplified.

All you have to do is this: If a the top and bottom of a rectangle collide, invert the y component of the velocity. If the left and right collide, invert the x component.

for a given velocity (a speed S and direction theta), the components are:

x = S * cos(theta);
y = S * sin(theta);

so what you do when you detect a collision is this:

-break the velocity down to x/y components.
-flip the x or y velocity.
-re-compose the components back to a speed and an angle.

to re-compose, just do this:

S = S (the speed does not change, only the directional component of the velocity)

the angle is atan2(y, x)

Just be careful to convert between degrees and radians where appropriate and you should be all set.

P.S. I had to deal with this sort of thing in my game Worminator when making the mortars bounce around. I just keep the x/y components of the velocity stored seperately as two floats. That way its easier to move objects around, flip velocity components, and change the direction of the character. For example, if you want to move left while falling in the air, you just set the x component to -1 units/sec or whatever you want, and you dont have to worry about recomputing the new angle of the velocity which would be an ugly sum of the gravity vector and the force you apply to the object to make it move sideways.

Plucky
Member #1,346
May 2001
avatar

A recent thread on collisions:
http://www.allegro.cc/forums/view_thread.php?_id=335389

Vector method would work for both circles and rectangles (assuming you're ignoring angular momentum). Would handle rectangle corner collisions easily.

Johan Halmén
Member #1,550
September 2001

orz said:

Picking an arbitrary side to collide with for exact matches isn't bad.

Right, because if you have perfect rectangles, the corners will never collide. There's always an epsilon distance. In the real world this is also true, but there are also these angular momentum issues involved. And when two real world boxes collide (almost) by the corners, the corners will break and act like if the corners were rounded in the first place. In your simulation you have to decide how much of the real world stuff you leave. Neglecting the corner collision is just one level of simplification.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

Go to: