Rotate Around
To rotate a first-person camera, we need a means of rotating about a non-standard axis, like the diagonal \(\begin{bmatrix}0.707&0.707&0\end{bmatrix}\). The good news is that a rotation around an arbitrary axis can be decomposed into this sequence of rotations around the standard axes:
- Rotate around the x-axis so that the axis of rotation lies in the xz-plane.
- Rotate around the y-axis so that the axis of rotation aligns with the z-axis.
- Rotate around the z-axis by the desired angle.
- Unrotate around the y-axis.
- Unrotate around the x-axis.
The bad news is that the math of this sequence gets rather involved. You have to figure out the angles for steps 1 and 2 using dot products. And then you've got five rotation matrices to multiply together. In pseudocode, the algorithm looks something like this:
function rotateAroundAxis(axis, degrees)
angle1 = degrees needed to rotate axis in xz-plane
angle2 = degrees needed to rotate axis into z-axis
return Matrix4.rotateX(-angle1) *
Matrix4.rotateY(-angle2) *
Matrix4.rotateZ(degrees) *
Matrix4.rotateY(angle2) *
Matrix4.rotateX(angle1)
function rotateAroundAxis(axis, degrees) angle1 = degrees needed to rotate axis in xz-plane angle2 = degrees needed to rotate axis into z-axis return Matrix4.rotateX(-angle1) * Matrix4.rotateY(-angle2) * Matrix4.rotateZ(degrees) * Matrix4.rotateY(angle2) * Matrix4.rotateX(angle1)
You can figure out the math later if you want. In the meantime, your graphics forebears have worked out a compact form of this matrix and shared it with you. Suppose you wish to rotate \(a\) radians around arbitrary and axis \(\mathbf{v}\). The compact matrix is built out of the components of \(\mathbf{v}\) and these variables derived from \(a\):
The rotation matrix has this form:
A rotateAround
method that builds this matrix is a great addition to your Matrix4
class. Have it accept parameters for the axis and degrees. Assume the axis is normalized, which is a prerequisite for this method to work properly.