In this one I want to introduce a specific kind of force: collisions! This is not a "fundamental force", it's actually a combination of lots of complicated interactions, some of which we might talk about later in this series. But despite that, it's an important kind of interaction, and it's one that illustrates very nicely a couple of important ideas that I want to introduce early.
So what is the collision force? The goal here should be to come up with an expression that we can just plug into our simulation loop and press "go." Now I want this expression I present to be physically motivated, but I don't care about perfect accuracy. This series is about concepts.
So what I did is I went on youtube and found a couple slow-motion videos of tennis balls bouncing and colliding with one another. I tracked their positions over a number of video frames, and then backsolved to get an idea of what shape the force should take. And this is what I arrived at. Plugging into the simulation loop gets us this. When the two balls far away and not touching, there's no force felt by either. When they're close together, they feel a repulsive force. As they get pressed closer together, the force they feel gets larger in magnitude.
collision_force(this, other) { distance = (this position) - (other position) cutoff_distance = (this radius) + (other radius) norm_dist = distance / cutoff_distance if (abs(distance) <= cutoff_distance) { force = 0.125 * (abs(norm_dist)^-5 - 1) * (norm_dist / abs(norm_dist)) } else { force = 0 } }
The way this works is that each object, when at the stage when it's time to calculate its force, plugs its *own* position into "this position" and the other object's position into "other position". So for the right ball, it's the right position minus the left. For the left ball, it's left minus right. So what this means is that for the right ball, this quantity is going to be positive, and that positive number will cascade through the expression and result in a positive force. For the left ball, this quantity will be negative, and cascade into an overall negative force.
It first computes a normalized distance, where 0 means "occupying the exact same spot", -1 and 1 mean "just barely touching", and numbers outside of the [-1, 1] range means not touching. It then computes to compute a force value between 0 and infinity for the appropriate distance, and then multiplies by +1 or -1 depending on if the force is coming from the left or right.
For our purposes, the "position" of one of the balls that you see on the screen is denoted by the little crosshairs, which is supposed to represent the object's "center". During the collision you see the balls squash and stretch, but this is just a visual effect.
Changelog:
© by Daniel Taylor