Tips on using the applet:
If it at first doesn't work, try a shift-reload. To make the block spin, click on the applet, and hit one of the keys that are listed. To see some cool physics at work, press and hold one axis, and then press and hold another axis, so it goes into a real fit. Then you can watch as it stabilizes itself to be rotating around a single, happy, axis.
Note (4/13): My old physics teacher tells me that in the absence of torque this effect shouldn't occur. The axis of rotation should change over time, but it shouldn't tend towards the angular momentum. We are nailing down the reason why this is happening…
Note (4/14): It turns out that the damping effect is coming from my 1-st order Euler integration technique, which is highly inaccurate, especially given the fact that we are only running at about 30fps or so. It is interesting that the errors incurred in this calculation give rise to an almost identical effect as a damping medium such as air.
What's going on:
It can be very difficult to programmatically reproduce realistic free rotation of a rigid body onscreen. Just taking a look at the free rotation of a rectangular prism (a book with a rubber band around it) can really be intimidating. I have searched for a long time for a good way of doing this, and the answer finally came to me: Angular Momentum. Of all the things that are conserved, the least represented in lower-devision physics is angular momentum. Because it is necessarily conserved except in the case of applied torque, you can represent any constant rotational motion simply by having a vector representaton of the angular momentum. This provides a springboard for a host of complex behavior, because no matter what, given a rigid body, angular momentum is conserved. The axis about which an object rotates is not necessarily constant, in fact, it requires extreme symmetry to have an object exhibit this property. The traditional notion that angular momentum = rotational inertia * angular velocity is an extreme simplification, unless you consider the rotational inertia to be a 3×3 matrix. If you do this, given a stored angular momentum, you can invert the matrix, multiply the angular momentum (vector) by it, and you get the angular velocity (vector). This won't be the same at every time step, so you'll have to re-calculate it every time. However, this extra step gives a solid physics foundation for your rotation calculations, gives you an easy way to apply torques and forces to your object, and gives you an easily calculated rotation axis. Storing the inertia tensor (3×3 matrix) in inverted form means that at every frame you just have to perform a single matrix calculation every frame to get the angular velocity of the object.