Rotating Offsets with Matter.Vector.rotate

In Matter.js, positioning an element relative to a rotating rigid body requires translating local coordinates into world coordinates. The Matter.Vector.rotate utility facilitates this by applying a 2D rotation matrix to an offset vector using the body’s current angle. When this rotated offset is added to the body’s world position, it yields the exact world coordinate of any point anchored to the body, regardless of how the body moves or turns.

Understanding Relative Offsets

When working with physics simulations, rigid bodies possess a center of mass defined by body.position and an orientation defined by body.angle (measured in radians).

A relative offset is a fixed coordinate pair (x, y) representing distance from the body's center in its untranslated, unrotated state (local space). For example, a weapon mounted on the nose of a vehicle might have an offset of { x: 40, y: 0 }. If the vehicle remains upright at an angle of 0, the weapon's world position is simply body.position.x + 40. However, as the vehicle rotates, this fixed point must orbit the center point to maintain its relative attachment position.

How Matter.Vector.rotate Works

The Matter.Vector.rotate function takes two arguments:

  1. vector: The vector to rotate, representing { x, y }.
  2. angle: The angle of rotation in radians.

Mathematically, it calculates the new coordinates using standard Euclidean 2D rotation formulas:

\[x' = x \cdot \cos(\theta) - y \cdot \sin(\theta)\] \[y' = x \cdot \sin(\theta) + y \cdot \cos(\theta)\]

When you pass the local offset and body.angle into Matter.Vector.rotate, it reorients the offset vector along the directional heading of the body while preserving its magnitude (distance from the center).

Implementation Pattern

To compute a dynamic point in world space relative to a rotating body:

  1. Define the static offset: Establish the local offset vector relative to (0, 0).
  2. Rotate the offset: Pass the local offset and body.angle into Matter.Vector.rotate.
  3. Translate to world space: Add the rotated offset to body.position using Matter.Vector.add.
// Step 1: Define local offset (e.g., 50 units forward, 10 units up)
const localOffset = { x: 50, y: -10 };

// Step 2: Rotate the offset by the body's current orientation
const rotatedOffset = Matter.Vector.rotate(localOffset, body.angle);

// Step 3: Combine with the body's center position in the world
const worldPoint = Matter.Vector.add(body.position, rotatedOffset);

Practical Use Cases