Matrix
geometry/matrix.ts:58A 2D affine transform — the engine's representation of a fully-resolved
world transform. Where a WorldObject stores its transform as a
human-friendly decomposed triple (position, rotation, scale), a Matrix
is the composed form those three collapse into, and it is the only form
that survives an object hierarchy intact.
Why a matrix, and not just position/rotation/scale
As long as everything is flat, "position + rotation + scale" is a perfect
description of where a thing is. The moment you nest one object under
another, that stops being true: a child's world transform is its parent's
world transform composed with its own local one, and once a rotation meets
a non-uniform scale somewhere up that chain, the result contains
shear — a skew that no single (rotation, scale) pair can represent. A
matrix represents it exactly. This is why WorldObject.worldMatrix
is a Matrix and not three numbers, and why graphics push the matrix
straight to the renderer rather than a decomposed transform.
Representation
The transform is stored as the six significant entries of a 3×3 affine
matrix, in the same a, b, c, d, tx, ty layout the underlying renderer
(PIXI) uses, so handing one to the renderer is a field-for-field copy:
| a c tx | x' = a·x + c·y + tx
| b d ty | y' = b·x + d·y + ty
| 0 0 1 |a/b/c/d are the linear part (rotation + scale + shear); tx/ty
are the translation. The default-constructed matrix is the identity.
Mutation style
Like Point, the in-place operations (Matrix.append,
Matrix.invert) mutate this matrix and return this for chaining,
while Matrix.clone and Matrix.apply never mutate. Compose a
fresh matrix with the static Matrix.compose; tear one back apart
with Matrix.decompose.
Example
// The world transform of a child = parent's world × child's local.
const world = parent.worldMatrix.append(
Matrix.compose(child.position, child.rotation, child.scale),
);
// Project the child's local origin into world space.
const worldOrigin = world.apply({ x: 0, y: 0 });Constructors
Properties
Methods
append(other: Matrix): this Post-multiplies this matrix by other in place — this = this × other
— and returns this. "Post-multiply" means other is applied to a
point first: this.append(other).apply(p) equals
this.apply(other.apply(p)).
This is the operation that walks an object hierarchy: starting from a parent's world matrix and appending a child's local matrix yields the child's world matrix.
Parameters
-
otherMatrix
Returns
this This matrix, for chaining.
apply(point: PointPrimitive): Point Transforms a point by this matrix, returning the result as a fresh
Point (this matrix and the input are left untouched). Equivalent
to (a·x + c·y + tx, b·x + d·y + ty).
Parameters
-
pointPointPrimitive
clone(): Matrix Returns an independent copy of this matrix. Use before a mutating operation (Matrix.append, Matrix.invert) when the original must be preserved.
Returns
Matrix decompose(): DecomposedTransform Recovers an approximate translate/rotate/scale triple from this matrix — the lossy inverse of Matrix.compose. Round-trips exactly for any matrix built from a TRS chain with non-negative scale; a matrix carrying shear (rotation composed with non-uniform scale, as can happen deep in an object hierarchy) is approximated, because shear has no TRS representation.
Translation is read directly from tx/ty; the x-scale and y-scale are
the lengths of the two basis vectors; rotation is the angle of the first
basis vector. See DecomposedTransform for the per-field contract.
invert(): this Inverts this matrix in place and returns this, so that applying the
result undoes the original transform. Used when reparenting an object
"in place": the new local transform is the new parent's inverse world
matrix appended with the object's current world matrix.
A matrix with a zero determinant (one that collapses space — e.g. a
zero scale on an axis) has no inverse; rather than producing
Infinity/NaN entries, this resets the matrix to the identity. The
collapse is already information-losing, so identity is the least
surprising degenerate result.
Returns
this This matrix, for chaining.
compose(position: PointPrimitive, rotation: number, scale: PointPrimitive): Matrix Composes a translate → rotate → scale chain into a single matrix, in that application order: a point is first scaled, then rotated, then translated. This is the exact transform a WorldObject applies to map a point from its own local space into its parent's space, so it is the building block WorldObject.worldMatrix is assembled from.
Parameters
-
positionPointPrimitive -
rotationnumber -
scalePointPrimitive