Chapter 15: Hierarchical Transformations
The first thing to understand is that the order of transformations makes a big difference.
A good example of this comes from applying a rotation and translation to an object.
Our rotation transformations rotate an object around the origin. But sometimes, we may want to rotate an object around a different point.
For a given vertex , rotation matrix and translation matrix .
This describes first a rotation about the origin, then we translate to a position described by . So the object will be rotated, but it will be at the position specified by .
This describes a translation followed by a rotation around the new origin. Now it’s like the object is off in space and orbiting the origin.
See the visual example below!
Let’s say we want to build a robot arm like below:
We have a red upper arm, green lower arm, and blue hand.
For the red upper arm, the transform is simple. We defined a Rotation 1 and rotate by this:
For the green lower arm, we want the block to follow the rotation of the upper arm, but also be able to rotate around the elbow. We define a Rotation 2 which is the elbow rotation. We also need to account for the fact that the green block is moved along the x-axis (it doesn’t occupy the same space as the red block, it’s at the end of the red block).
So we want to first rotate around the elbow, then move out to the end of the upper arm. Finally we need to rotate along with the upper arm rotation.
We’ll do a similar process for the blue hand. We add a Rotation 3 which is the rotation of the wrist. We also need to translate out to the end of the green lower arm.
Note that how we chain these transformations together is necessary to make all the rotations work. We also don’t have to account for the length of the red upper arm when translating the blue hand. That is already accounted for in our chain.
Hierarchic Transforms Slides
Rectangle Transform: “A” Example
rotate(-rot); push(); translate(-75, 0); rotate(radians(60)); scale(3, 0.25); // red rectangle fill(204, 101, 101, 127); stroke(127, 63, 63); rect(-50, -50, 100, 100); pop(); push(); translate(75, 0); rotate(radians(-60)); scale(3, 0.25); // green rectangle fill(101, 204, 101, 127); stroke(63, 127, 63); rect(-50, -50, 100, 100); pop(); push(); translate(0, -20); scale(1.25, 0.25); // blue rectangle fill(101, 101, 204, 127); stroke(63, 63, 127); rect(-50, -50, 100, 100); pop();
Note that the standard order to apply the usual three transforms (translation, rotation, and scale) to an object is:
You definitely want to apply scale before translation - otherwise, the scale will increase or decrease the translation amount.
If the scale is uniform (same value for x, y, and z) then it and rotation can be in either order. But, applying a non-uniform scale after rotation will cause a weird effect (it will turn rectangles into trapezoids).