Step 1 of 5 · Reading · ~3 min
Read
Game Loop
Transforms & Math
Every object in a scene has a position, a rotation and a scale, and most are attached to a parent: a sword to a hand, a hand to an arm. After this lesson your program will keep a tree of such objects and answer where any point of any object ends up in the world, even after a parent moves.
Why a 3x3 matrix
Rotating a 2D point is a 2x2 matrix multiply. Translating is an addition, and an addition is not a multiplication, so a 2x2 cannot hold all three operations. The fix is homogeneous coordinates: write the point as (x, y, 1) and use a 3x3 matrix whose last row is always (0, 0, 1). Then translate, rotate and scale are all one kind of object, and combining transforms is matrix multiplication.
Because the last row never changes, engines store only six numbers (a, b, c, d, e, f):
| a c e | | x | x' = a*x + c*y + e
| b d f | * | y | y' = b*x + d*y + f
| 0 0 1 | | 1 |
The columns are where the x axis, the y axis and the origin of the object's space land.
The local matrix: scale, then rotate, then translate
A node stores translation (tx, ty), rotation deg and scale (sx, sy). Its local transform scales the point about the origin first, rotates that about the origin, and moves the result last. Written as a product that is T x R x S, applied right to left. With theta the rotation in radians:
a = sx*cos(theta) c = -sy*sin(theta) e = tx
b = sx*sin(theta) d = sy*cos(theta) f = ty
Try node T(5,5) R(90) S(2,1) on the point (1,0): scale gives (2,0), rotate 90 degrees gives (0,2), translate gives (5,7). Doing the steps in another order gives a different point, which is the classic source of "my object orbits instead of spinning".
The hierarchy
A child's matrix is relative to its parent. To find where it is in the world, multiply down the chain from the root:
world(child) = world(parent) x local(child)
The parent goes on the left because the child's local transform is applied first and the parent's second. Take a parent at (10,0), rotated 90 degrees, scaled 2, with a child 3 units along its local x axis. The parent's matrix is (0, 2, -2, 0, 10, 0) and the child's local origin is (3,0), so the child lands at (03 + -20 + 10, 23 + 00 + 0) = (10, 6): the 3 became 6 through the scale and turned up through the rotation.
Real engines cache the world matrix on each node and mark descendants dirty when a parent changes. Whatever you cache, moving a parent must move its children.
Traps
- Shear. A rotated child under a non-uniform parent scale is not a rotation plus a scale any more; its matrix has a skew. That is why many engines forbid non-uniform scale on parents.
- Handedness. Maths puts y up, most screens put y down, so a positive angle that turns counter-clockwise on paper looks clockwise on screen. Pick one convention and keep it.
- Degrees and radians. Authoring tools use degrees,
sinandcosuse radians.
Common mistakes
- Multiplying in the wrong order (local x parent, or scale after rotate).
- Caching the world matrix when a node is defined and never refreshing it after
MOVEorROTATE. - Passing degrees to
sin/cos. - Printing
-0.0000. A tiny negative number rounds to negative zero; print it as0.0000.
Your exercise
Build the hierarchy described in the exercise. The starter parses the commands and prints results; you write the three matrix functions. The most likely mistake is the multiplication order.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…