Recently, I have been studying a number of matrix libraries used for WebGL to better understand the math that goes into the various transforms performed on matrices. Currently, I am trying to better understand the math used for rotational transforms.
Specifically, I already understand the transforms used for rotating around the three axes as well as how to generate these matrices (shown below).
However, I don't get the equations used to rotate around an arbitrary axis that isn't the x-, y- or z-axis.
I'm currently reading through WebGL Programming Guide, and in the provided library, they use the following JS to rotate around an arbitrary axis (where e
is the array that contains the 4x4 matrix):
len = Math.sqrt(x*x + y*y + z*z);
if (len !== 1) {
rlen = 1 / len;
x *= rlen;
y *= rlen;
z *= rlen;
}
nc = 1 - c;
xy = x * y;
yz = y * z;
zx = z * x;
xs = x * s;
ys = y * s;
zs = z * s;
e[ 0] = x*x*nc + c;
e[ 1] = xy *nc + zs;
e[ 2] = zx *nc - ys;
e[ 3] = 0;
e[ 4] = xy *nc - zs;
e[ 5] = y*y*nc + c;
e[ 6] = yz *nc + xs;
e[ 7] = 0;
e[ 8] = zx *nc + ys;
e[ 9] = yz *nc - xs;
e[10] = z*z*nc + c;
e[11] = 0;
e[12] = 0;
e[13] = 0;
e[14] = 0;
e[15] = 1;
From what I can tell, the first part of the code is used to normalize the 3D vector, but other than that, I honestly cannot make any sense of it.
For example, what do nc
, xy
, yz
, zx
, xs
, ys
and zs
mean? Also, as an example, how did they come up with the formula x*x*nc + c
to calculate e[0]
?
As per a related SO post, I did find a reference to the following matrix for rotating about an arbitrary axis:
This seems to be related to (if not the same as) what the JS code above is doing.
How is this matrix generated? I've thought a lot about how to rotate around an arbitrary axis, but the only thing I could come up with was to break the 3D vector extending from the origin into its x, y and z components, and then perform three different rotations, which seems pretty inefficient.
Having one matrix to do all of that for you seems best, but I really want to understand that matrix and how it's generated.
Lastly, while I'm not sure, it seems like the matrix above does not account for a translation of the axis away from the origin. Could that be easily handled by simply using a 4x4 matrix instead with Tx, Ty and Tz values in the appropriate locations?
Thank you.