Physics of Angular Motion

Okay now’s where things start to get a little twisty… Get it? Twisty? The previous post handles the relatively simple case of motion in a straight line. Now we want to turn (eh? Turn?) our attention to rotations. Simply put, while Linear Motion deals with motion in a straight line, Angular Motion deals with how things spin. The good news is that every formula for rotations has a direct analogue in linear space. The bad news is that it still manages to be confusing. This may have to do with the blatant overuse of Greek symbols. Thankfully for you, I have no idea how to type Greek.

So my goal will be to build up a bunch of equations of Angular Motion by referring directly back to their Linear equivalents. I’m gonna start with the easy ones. First, there’s the Angular version of Position… It’s just Rotation. No surprise here, in Linear space we talk about standing at a specific position, in Angular space we talk about which direction we’re facing. Oh, but I’m not gonna let you get off that easily, I’m gonna throw in Quaternions to make it horrible:

Unit_quaternion rotation;

Okay yeah, so the Quaternion makes it mathematically hard, but the concept is simple enough. Are you facing North, South, etc? The reason we’re forced into using a Unit_quaternion is that we will need to take any arbitrary rotation, apply a force, and get some new rotation. If you remember from the Rotations post, this kind of manipulation of a rotation is exactly the problems that Quaternions solve.

So that solves position, but how about velocity? Well in Angular space we simply call this “Angular Velocity” and it just means how fast are you spinning? In Math docs you’ll see this represented with the Greek symbol little omega. In my code it’s called:

Vector angular_velocity;

Why do I use a Vector and not a Quaternion? This is a great question. I’ve actually been on a bit of quest to try and see how I might use a Quaternion directly, but so far I have not been successful. The math of applying a Quaternion angular velocity to an existing rotation is great, but all of the physics of is just easier to reason about using plain old Vectors. So for now, our angular velocity is a Vector. It works exactly like an Axis and Angle previously described.

So is there an angular version of acceleration? Absolutely, but much like with Linear Acceleration, I don’t really use it so much, aside from as a trick to convert Force to Velocity.

Okay so now for the hard ones. Believe it or not, the first hard one is the Angular equivalent of humble mass, it’s called “moment of inertia.” Why does this need to be hard? Well you may have noticed that when something’s mass is evenly distributed it tends to spin smoothly, think car tire or hula-hoop. But something that weighs a lot more on one end spins very unevenly, think hula-hoop with a five pound weight attached to one side. The Physics of it is that things rotate around the center of mass, the balance point. If the thing has an odd shape, or is made of light stuff on one side, and heavy stuff on the other, it will not spin around it’s physical center. I don’t want to get hung up on the details of this one, the Internet is filled with the math for how this works, for this discussion it’s important to know that things with an uneven mass distribution will spin differently then things with an even mass distribution, even if they both have the same total mass. A Moment of Inertia does the job of storing both an object’s mass, and the distribution of that mass.

And this brings us to the big one, Force, or as we call it in Angular space, Torque. When I was in high school, torque was the hardest part of Physics for the class to understand. I’m not entirely sure why this topic was so complicated for us, but we spent weeks trying to wrap our heads around it. It turns out that torque is really just Force… but it has an extra component, which is where on the object the force is applied. Just like in moment of inertia the distribution of mass is important. Similarly, where the Force is applied is an important part of the Torque. To put this in more concrete terms, imagine a bicycle wheel. If you push the tire it’s pretty simple to get it spinning, but you have to push very fast to make the wheel spin fast. But if you push right next to the hub it’s harder to get it spinning, but you don’t have to push very fast to make the wheel spin fast. It’s the same amount of Torque required to get the wheel spinning to a given angular velocity, but depending on where you push it can feel easier or harder.

You can start to build an equation for Torque by just converting the Linear equation for Force into the Angular one. Let’s start by reminding ourselves what Linear Force looks like:

// Newton's Second Law says:
F = m * a;

So the rotation equivalent should be something like:

Torque = (angular mass) * (angular acceleration);

Well as stated above, the angular versions of mass and acceleration are moment of inertia and angular acceleration. So the formula is simply:

Torque = moment_of_inertia * angular_acceleration;

If  you’ll remember from my last post, we don’t actually use acceleration, we replace it with the change in velocity in order to find a formula for how velocity changes given an applied force. Let’s do the same thing with torque:

// T = torque
// moi = moment of inertia
// ra = rotational acceleration
// rv = rotational velocity
// t = elapsed time
T = moi * ra;               // Newton's second law (sort of)
ra = (rv1 - rv0)/t;         // Rotational Acceleration
T = moi * (rv1 - rv0)/t;    // Newton's second, replace ra
T*t = moi*rv1 - moi*rv0;
T*t + moi*rv0 = moi*rv1;    // rv1 is what we want
(T*t + moi*rv0)/moi = rv1;
(T*t)/moi + rv0 = rv1;      // Eureka! We have rv1

There, that wasn’t so hard… but wait, there’s more. It turns out that moment_of_inertia can’t be represented by a simple scalar. Nope, not a Vector either. How about a Quaternion? Nope, sorry. The moment of inertia is something called a “tensor.” What’s a tensor? Damned if I know, but I do know it’s represented by a matrix. As you may recall, I hate matrices and have made it my life’s work to never use one in a Physics Engine. So what to do? Well if you don’t know by now, it’s time I let you in on a sad truth, Physics Engines are cheaters. Physics Engines for games are blatant, unrepentant cheaters. In the thick of a video game you just don’t need perfect Physics. When you blow up a pile of stacked boxes with some kind of ultra-blaster frag bazooka, you’re not gonna notice if the resulting shrapnel isn’t spinning off around the correct center of mass. So while it turns out that the correct moment of inertia for an object has to do with its shape and mass distribution, the moment of inertia of a uniform sphere is pretty simple, it’s just:

moment_of_inertia_of_uniform_sphere = 2/5 * radius * (mass * mass);

Check it out, it all fits into a simple scalar. Thank goodness for cheating. So the above function for finding the new angular velocity manages to hold up just fine with our cheating simplified moment of inertia.

Now unfortunately when we go to look at the code there’s a bit of a snag. Remember that I’ve been storing angular velocity as a Vector because it makes the physics easier to reason about. And I’ve been storing the rotation as a Quaternion because it makes rotations smoother. Unfortunately the conversion from one representation to another is a bit of a mystery to me. Luckily for us there are Mathematicians who can show us the way. When you look online you’ll find that most people do something like this:

rotation = rotation + t/2 * angular_velocity * rotation

You won’t find a lot of sites explaining why this works, but this link does have an explanation. Unfortunately I’m not able to fully understand it, so let’s just hope the author never takes down that link.

And there we go, that brings us to the end of Rotational Physics. The code for this is all sitting right next to the code for Linear Physics, here are some links:

 << Linear Motion Contents GJK part 1 >>

Physics of Linear Motion

Now that we have a grounding in the basic Math of a Physics Engine, it’s time we shift our attention to actual Physics. Thankfully, basic Physics is something we’ve all probably had in high school, so this information should be pretty straight forward. Maybe it will help knock off some rust, maybe it will help focus your attention on the specific parts we need for a Physics Engine, or maybe it will introduce you to some of the quirks of Physics in 3D (which I never did in high school). I’m going to split up Linear Motion and Angular Motion into two posts. The Linear part should be a lot simpler, so let’s get started.

Linear Motion is the physics of moving in straight lines. At the base of it all are these humble concepts:

Point position; // where you are
float m; // mass
float t; // time

No surprises here. The position is a 3D point, which may be a bit different from what you saw in high school, but by now should be easy to grasp. Let’s move it up a notch

Vector distance = pos1 - pos0;
Vector velocity = distance/t;

Here’s a nice chance to point out how Vectors are not the same as Points. Recall that subtracting a Point from a Point yields a Vector, in this case a distance. Dividing that by the scalar time will result in velocity. And with Velocity we can move up to the big guy, acceleration:

Vector v0; // the starting velocity
Vector v1; // the final velocity
Vector acceleration = (v1-v0) / t;

In English, acceleration is the change in velocity divided by time. Or to say it in car analogy: The Tesla Model S does 0 to 60 in 2.28 seconds. To make it painfully obvious, 60 is v1 and 0 is v0, and t is 2.28 seconds.

Consider the basics of what we want to do during a Physics update loop. We will have some kind of object, and it will have a force applied to it (eg. gravity on a falling object, thrust on a rocket ship, brakes on a car, etc), and some amount of time has elapsed since our last trip through the Physics loop. Our goal really comes down to figuring out how far to move the object. Everything else is kind of unimportant, we just want to move the object so users will see it move across the screen. So here’s our list of known things:

Point position;
float mass;
float time;
Vector velocity;
Vector force;

From that we want to figure out how far to move the object, a Point representing the new position would be useful. Notice that force is one of the things we have. When I was in high school I learned exactly one way to convert force to anything useful, it was through Newton’s Second Law, the famous F = ma. We actually could use that if we had to. We could find the acceleration, and then use that to solve for the new velocity, and then use that to solve for the new distance. But wouldn’t it be nicer to just get the new velocity directly from the force? Here’s the math (in pseudo code):

F = m * a;            // Newton's Second law
a = (v1 - v0)/t;      // Acceleration (see above)
F = m * (v1 - v0)/t;  // Newton's second, replace a with dv/t
F*t = m*v1 - m*v0;
F*t + m*v0 = m*v1;    // v1 is what we want
(F*t + m*v0)/m = v1;
(F*t)/m + v0 = v1;    // Eureka! We have v1

So here’s the story thus far: we have an object with a known mass, velocity, and applied force. Some amount of time elapses. We enter our Physics loop and combine all of these things to get a brand new velocity. That’s great, but remember that what we want is a new position for our object. How do we take this new velocity and elapsed time and find the position?

V = d / t;            // classic velocity formula (see above)
d = (p1 - p0);        // distance is new position minus old (see above)
V = (p1 - p0) / t;    // replace d with p1 and p0
V * t = p1 - p0;      // p1 is what we want 
V * t + p0 = p1;      // Eureka! We have p1

So yeah, no great magic to all of this. Every time through the Physics loop we take our known velocity, mass, position, force and elapsed time and use those to figure out a new velocity and position. We then update the position on screen, and save these for our next time through the Physics loop.

In my Engine I store the physical properties (velocity, force, mass, etc) in something called a Physics_object. The class which manages all of the Physics_objects and causes them to smash into one another is the Arena:

 << Coordinate Systems Contents Angular Motion >>