Rotation and scaling in 3D
In 3D a linear transformation is a 3×3 matrix: each new coordinate is a fixed combination of x, y and z. Rotations about the origin and scalings along the axes are both linear, so the page transforms the corners of the shape by matrix multiplication and redraws the edges between them. Unlike 2D, there are three axes to rotate about, and rotations about different axes do not commute.
The page's convention and matrices
With Row Major (the default, used here) the point is a row vector on the left, p′ = p · M. With Column Major it is a column vector on the right, p′ = MT · p, and every matrix is transposed. These are the matrices the page uses (row form):
About z (turns +x toward +y): About y (turns +z toward +x): About x (turns +y toward +z):
Rz = [ cos θz sin θz 0 ] Ry = [ cos θy 0 -sin θy ] Rx = [ 1 0 0 ]
[ -sin θz cos θz 0 ] [ 0 1 0 ] [ 0 cos θx sin θx ]
[ 0 0 1 ] [ sin θy 0 cos θy ] [ 0 -sin θx cos θx ]
Scale: S = [ sx 0 0 ]
[ 0 sy 0 ]
[ 0 0 sz ]
Rotate button (row vectors): M = Rz . Ry . Rx -> z first, then y, then x
Rotate button (column vectors): M^T = Rx^T . Ry^T . Rz^T (same rotation, read right to left)
Scale button: M = S
The page multiplies Ry · Rx first and then Rz · (Ry · Rx); associativity means that is the same as (Rz · Ry) · Rx. Every vertex is then multiplied by the single combined matrix. Rotate and Scale are separate buttons, and each press acts on the shape as it is now, so a sequence of presses is a composition in the order you press them.
A sign to watch: all three matrices follow the right-hand rule (thumb along the positive axis, fingers curl in the positive direction). The axes go round in the cyclic order x → y → z → x, so a positive turn about z takes +x toward +y, about x takes +y toward +z, and about y takes +z toward +x, which means +x goes toward −z. That is why the minus sign in Ry sits in the top row, while in Rz and Rx it is in the lower row. With Y Angle 90, (1, 0, 0) · Ry(90°) = (0, 0, −1), and on the page the cube's corner (100, 100, 100) goes to (100, 100, −100). Some books and libraries flip the sign for one axis or use left-handed axes, so check which convention yours uses.
The drawing uses a simple oblique projection: the screen shows x to the right and z up, and y goes into the screen at 30° at half length (screen right = x + 0.433y, screen up = z + 0.25y).
Worked example
Rotate the point (1, 2, 3) with Z Angle 90, Y Angle 0, X Angle 90, then scale by (2, 1, 0.5). With cos 90° = 0, sin 90° = 1, and Ry(0) = I:
Rz(90) = [ 0 1 0 ] Rx(90) = [ 1 0 0 ]
[ -1 0 0 ] [ 0 0 1 ]
[ 0 0 1 ] [ 0 -1 0 ]
z first: [1 2 3] . Rz = [ 1·0 + 2·(-1) + 3·0, 1·1 + 2·0 + 3·0, 3 ] = [ -2 1 3 ]
then x: [-2 1 3] . Rx = [ -2, 1·0 + 3·(-1), 1·1 + 3·0 ] = [ -2 -3 1 ]
One matrix: M = Rz . Ry . Rx = [ 0 0 1 ] [1 2 3] . M = [ 2·(-1), 3·(-1), 1·1 ] = [ -2 -3 1 ]
[ -1 0 0 ]
[ 0 -1 0 ]
Other order (x first, then z):
[1 2 3] . Rx = [ 1, 2·0 + 3·(-1), 2·1 + 3·0 ] = [ 1 -3 2 ]
[1 -3 2] . Rz = [ 1·0 + (-3)·(-1), 1·1 + (-3)·0, 2 ] = [ 3 1 2 ]
Scale the first result by (2, 1, 0.5):
[-2 -3 1] . S = [ -2·2, -3·1, 1·0.5 ] = [ -4 -3 0.5 ]
The two rotation orders give (−2, −3, 1) and (3, 1, 2): the same two quarter turns, a different result. On the page, the cube's corner (100, 100, 100) goes to (−100, −100, 100) with Z Angle 90 and X Angle 90.
Why it works
[1 0 0] · M, [0 1 0] · M and [0 0 1] · M are the three rows of M, and any point is x, y, z times those unit vectors. So the rows of the matrix are where the x, y and z axes go (the columns, in the column convention). In the combined matrix above, the x axis goes to (0, 0, 1), the y axis to (−1, 0, 0) and the z axis to (0, −1, 0). For a rotation the three rows are perpendicular unit vectors, so R · RT = I: the inverse of a rotation is its transpose, and (Rz · Ry · Rx)−1 = RxT · RyT · RzT, the steps undone in reverse order. Its determinant is 1. A scale has determinant sx·sy·sz, the factor by which volumes change.
Three angles about fixed axes (Euler angles) can describe any orientation, but they have a weak spot called gimbal lock. With the page's order, when Y Angle is 90° the first and last rotations turn about the same line, so only the sum Z + X matters: (Z, Y, X) = (30, 90, 0), (0, 90, 30) and (20, 90, 10) all give the same matrix, and one degree of freedom is lost.
Cost and practical notes
A 3×3 matrix times a vector is 9 multiplications; a 3×3 product is 27. Combining the three rotations first costs 54 multiplications once, then 9 per vertex, instead of 27 per vertex. That hardly matters for the 8 corners of a cube but matters a lot for a million-vertex model. Real pipelines use 4×4 matrices with homogeneous coordinates (x, y, z, 1) so translation and perspective fit in the same product, and a GPU applies one combined model-view-projection matrix to every vertex. Animation systems often store orientations as quaternions, which avoid gimbal lock and interpolate smoothly, and convert them to a matrix for drawing.
Common mistakes
- Order of rotations. There are many Euler conventions (XYZ, ZYX, ZXZ, ...). "Rotate 90 about z and 90 about x" is ambiguous until you say which comes first.
- Row vs column convention. Row vectors: first transformation on the left. Column vectors: first on the right, and every matrix transposed. Copying a matrix between conventions without transposing gives the inverse rotation.
- Sign conventions, especially for Ry: its minus sign is in the other corner from Rz and Rx (see above), and copying their pattern turns about y the wrong way.
- Degrees vs radians. The page takes degrees;
Math.coswants radians (θ × π / 180). - Rotating about the origin, not the object's centre. These shapes are centred at the origin. For an object centred at c: translate by −c, rotate, translate by +c.
- Non-uniform scale distorts normals. Scale by (2, 1, 1): a surface direction (1, −1, 0) becomes (2, −1, 0), but the normal (1, 1, 0) becomes (2, 1, 0), and (2, −1, 0)·(2, 1, 0) = 3 ≠ 0. Normals must use the inverse transpose, here diag(0.5, 1, 1), giving (0.5, 1, 0), which is perpendicular again. Lighting code that forgets this shades stretched objects wrongly.
- Drift. Repeated rotations with rounded numbers slowly stop being orthogonal; rebuild the matrix from stored angles or re-orthonormalise it.
Where it is used
3D modelling tools and game engines (object rotation and scale in every editor), flight and vehicle simulation (yaw, pitch and roll are Euler angles), VR and phone orientation sensors, robot arm joints, and CSS 3D transforms (rotateX(), rotateY(), rotateZ(), scale3d()), which multiply matrices exactly like this with column vectors.