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.

The title is fairly self-explanatory. I have a 2D racing game that utilizes per-pixel collision detection (the track is essentially two bitmaps, one for the graphics, one for collision data). The problem I'm running into is that I can't figure out how to implement the collision response. I can figure this out for situations where I have a box colliding with another box, but the fact that my objects can essentially be any shape has me stumped.

The one approach that I've had some success with is to just sample a couple of pixels near the pixels that collide, build vectors out of those and then take the cross product of that, but it fails in many scenarios. Plus, it just seems like overengineering. In fact, I'm about 103% sure that I'm just overthinking the whole problem.

Has anyone tackled this problem?

share|improve this question
    
IIRC, you can't take the cross product of a 2D vector. Not physically possible. :) –  The Communist Duck Jul 5 '11 at 21:04
    
I don't know the terminology brilliantly well, but essentially I've been taking the vector that's between the two 2D vectors. The average of them, I suppose. I really need to study some more math at some point. :) –  drowsy Jul 5 '11 at 21:07
    
I guess you can use my answer here :gamedev.stackexchange.com/questions/14355/… –  Ali.S Jul 5 '11 at 21:14

2 Answers 2

up vote 2 down vote accepted

When you have a collision you should try to understand where the collision occurred, the involved forces, the consequences of the involved forces.

Simplest case (I can tink of):

  • The impact occurs in the frame the collision is detected (no compenetration)
  • The colliding objects are perfectly elastic (no energy loss due deformation)
  • The colliding object are disks (to be removed as soon as possible)

Under those circumstances there is conservation of total momentum and kinetic energy.

When a collision occours, there is a contact surface between the colliding bodies: they can exchange energy only through this surface; in other words the impact forces are always perpendicular to this surface.

The main conseguence to this is that you can decompone the kinetic energy vector in a radial component (perpendicular to the contact surface) and a tangential component (parallel to the contact surface) seeing that the tangential one stays the same.

Knowing the value for a component, we can consider the collision be monodimensional, restricted to the radial direction.

If we consider the second body to be still, we have some formulas for the velocity after the collision:

V1 after impact vs V1 before impact

V2 after impact vs V1 before impact

It is possible to compute the velocity after impact knowing the velocity before the impact for the radial coponent we needed. (the kinetic energy is ½·m·v²).

You can resolve the case where the second body is moving, by superimpose the collision effects (first-moving-second-still + first-still-second-moving) or by change the inertial reference to be linked to the second body before the impact; it is the same.


We can spice up the simulation by removing the geometric simplification.

First you need to compute the contact surface and to find the contat point. (I left the problem to you but you can consider to simplify the contat mode to colliding boxes)

With your contact surface you can compute the resulting kinetic energy vector - as explained before - but then? We have to "allocate" this energy because a rigid body can move and rotate and some energy is required to change linear or angular velocity.

To know around what point our body will rotate, we need to know the position for the center of mass: this can be precomputed since depends just by the object shape and mass distribution.

If you have a collision bitmap you can consider to sum up the position for each "on" pixel then divide for how many "on" pixel there are: this implies that the object has the same density in each point.

If you like you can use a graymap to store the density for each point: black for 0 density (body absence) and white for maximum density; by multiplying the position by the density, you can compute a weighted average: your center of mass

When you know the center of mass you need to know the moment of inertia: multiply the density of each point by the square of the distance from the center of mass and sum up.

Knowing the center of mass and the collision point, you can decompose the kinetic energy vector in a radial component (starting from collision point and pointing toward the center of mass) and a tangential component.

The radial component tells us how many impact enercy becomes kinetic energy, while the tangential component tells us how many impact enercy becomes rotational energy.

As well as the velocity is bounded to the kinetic energy so Et = ½mV², also the angular velocity is bounded to the rotational energy so Er = ½Iω², where I is the moment of inertia and ω the rotational velocity in radians per second.

Using those two formulas you can compute the velocity vector and the angular velocity to add to your body.

The last triky part is how to know if ω has to be clock/counterclok wise, since you will ever get a positive value.

Let I be the impact point and M the center of mass point, compute d = C - I;

Let Er be the tangential component for the impact kinetic energy, compute cross product in 2D, this will give you a right-handed perpendicular vector.

Now compute d·E if positive the rotation is CW else CCW

share|improve this answer

Well, In my flash games, I do have a lot of per-pixel collision detection. Since you have not mentioned your platform I'm assuming you use AS3 since, I code in as3. Well, even if you are not an Actionscript Developer, You will surely find this library useful. Just call a PixelPerfectCollisionDetection.isColliding() and pass obj1, obj2, stage, and [(true for per-pixel collision detection) or default value of false uses bounding boxes for collision checking]

PixelPerfectCollisionDetection

Hoping, you'd find this useful.

share|improve this answer

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.