When my housemate told me of his scheme for constructing a physics simulation, I did the only decent thing I could. I stole his idea. I turned to my copy of Serway and Beichner (a ~1600 page physics book that I keep under my pillow for just such emergencies) and sat down to work out how to get 2D circles to bounce off each other in the expected manner. Not that anyone has actually seen two-dimensional circles bouncing off each other in everyday life, what with the universe being three-dimensional and everything, but somehow we still have a conception of what it would be like if it were possible.
This took a surprising amount of math (much of which was admittedly due to a series of mistakes). Collisions must preserve overall momentum and energy, and the direction of acceleration must be determined by the angle of collision. And it’s nice if you can remember the quadratic formula, and work out which of the two answers it gives you is the right one in this circumstance.
Eventually I got it working, using a combination of C++, KDevelop, CMake, SDL and OpenGL, all of which I was using for the first time in years, or in some cases ever. My housemate valiantly tried to suggest the use of autopointers, but I was all learned out at that point. So, having triumphed in two dimensions where others have merely succeeded years or decades ago in three dimensions, I now have a little black window containing 20 or so blue circles of various sizes (and virtual masses) bouncing around and hitting each other.
The algorithm assumes for the moment that a given circle can collide with at most one other circle in every discrete time unit. When multiple simultaneous collisions occur, at least two circles become entwined – partially overlapping. They constantly “collide”, in each and every time unit, each time alternating direction with respect to each other but never gaining sufficient velocity to escape. They each just vibrate back and forth. The net effect is that they become a combined object, which exhibits angular momentum. The two balls spin around each other, with the “heavier” one making less pronounced motions than the “lighter” one. And I haven’t even tried to model angular momentum yet.
The next step will be allowing for multiple collisions with the same object in the same time unit, which should theoretically stop this from happening. But I might just have to preserve the current version.