I'm developing a 2D game including collisions between many disks. I would like to know how I can get the angle corresponding to the new direction of each disk.
For every disk I have this information : direction (integer), speed (float), and position ($x$;$y$, which are both integers).

Of course I know that the new direction will be the opposite of where the collision happens (disk hit on the bottom-left will go to the top-right), but I don't know how to calculate exactly the new angle.

Direction and position are integers? Does this mean the circles only exist at discrete grid points? Also presumably these are equal-mass circles with elastic (no sticking/energy loss) collisions?
–
Chris WhiteFeb 13 '13 at 20:59

Well to be more precise, it's about developing a curling-simulation. So the position of the pucks (circles) is represented by their central point, both integers corresponding to pixel units. The direction is an integer angle, I decided to choose 0° as the perfectly vertical axis to the bottom. For the moment they're only equal-mass but I consider to add pucks with different weights later.
–
RobFeb 13 '13 at 21:04

You definitely want to store the position as floats rather than integers and then round it to ints just before you render it. If you don't do this, you will see some strange artefacts when the speed is close to one pixel per frame, and if it's less than one pixel per frame the object will suddenly stop moving, because the speed will be rounded down to zero every frame. There's also no reason not to make the direction a float as well.
–
NathanielFeb 14 '13 at 1:28

1 Answer
1

In the ideal case where the collision is instantaneous and there is only a single point of contact, the forces experienced by each object can only be along the line that connects the centers and passes through the contact point. Actually, the "force" will be infinite, but it will impart a finite impulse (i.e. change in momentum) during the infinitesimal interval of time during which the collision occurs. There can be no component of impulse orthogonal to this, because that would amount to a "force" tangential to the circle. With any finite coefficient of friction, you cannot affect a circle by pushing tangent to it at just a point.

This constraint, together with conservation of momentum in two directions and conservation of energy, is enough to determine the motion of both circles given any initial conditions (which needs 4 scalars to be defined fully).

If the target circle is sitting still before the collision, its direction of motion afterward is easy enough to find: It is exactly along the line connecting the two circles' centers at the moment of contact. (Make sure you go the right way along this line - only one of the directions is sensible.) The new direction of the circle that was originally moving will simply be given by the direction of the vector sum of its old momentum and the momentum imparted to it in the collision. If you want numbers, say the moving circle makes contact when its center is at $(x_1, y_1)$, and the other center is at $(x_2, y_2)$. Then the angle at which 2 moves away from the collision is
$$ \theta = \frac{180^\circ}{\pi} \tan^{-1}\left(\frac{y_2-y_1}{x_2-x_1}\right). $$
By the way, it might be easier to just use $x$ and $y$ components of velocity, rather than speeds and angles.

Of course, if you want to take this to the next level of realism, you may need to account for the following effects:

Kinetic energy is lost (perhaps by a certain percentage) with each collision.

The collision could result in torques, transferring angular momentum.

Spinning objects may curve while sliding. This is a complicated effect though, and you probably have to model it with a kinetic coefficient of friction that varies with velocity.

Finally, for numerical accuracy, I suggest keeping all numbers as floats in the calculations and only rounding to the nearest integers when rendering.

Thank you a lot for this very full answer. I'm going to work on this a lot to get things right. Concerning my numerical accuracy, I forgot to mention it but of course I was already calculating my numbers as floats and rounding them in the end. Thanks again!
–
RobFeb 14 '13 at 9:26

@tekknolagi In that case I suggest transforming into a frame such that one is sitting still, doing the calculation, and then transforming back. The first transformation subtracts one of the objects' velocities (vectorially) from both, while the second transformation simply adds this same quantity back to both resulting velocities.
–
Chris WhiteFeb 27 '13 at 2:20