Scale Vertices Around a Point in Matter.js

This article explains how to scale geometric vertices relative to a specific origin point in Matter.js using the Matter.Vertices.scale method. You will learn the function signature, how the custom origin parameter modifies vertex positions directly in-place, and how to apply this technique through a concise, practical code example.

The Matter.Vertices.scale Method

In Matter.js, the Vertices module contains utility functions for creating and manipulating sets of polygonal points. The Matter.Vertices.scale function allows you to scale an array of vertices non-uniformly along both axes relative to a given coordinate point.

The method signature is:

Matter.Vertices.scale(vertices, scaleX, scaleY, point)

If the point argument is omitted, Matter.js defaults to using the geometric center calculated by Matter.Vertices.centre(vertices). To scale around an arbitrary anchor—such as a corner, a pivot joint, or the world origin (0, 0)—you must pass that coordinate as the fourth argument.

How Scaling Around an Origin Works

When a point is provided, the algorithm calculates the distance delta between each vertex and the origin point, scales that delta vector by scaleX and scaleY, and adds the result back to the origin coordinates:

\[\text{vertex.x} = \text{point.x} + (\text{vertex.x} - \text{point.x}) \times \text{scaleX}\] \[\text{vertex.y} = \text{point.y} + (\text{vertex.y} - \text{point.y}) \times \text{scaleY}\]

Because the function modifies the original vertex objects in place, any reference to those vertices will reflect the transformation immediately.

Code Example: Scaling Around a Custom Point

Below is an implementation demonstrating how to define a set of vertices and scale them around a specific pivot point:

// Define a triangle
const vertices = [
    { x: 100, y: 100 },
    { x: 200, y: 100 },
    { x: 150, y: 200 }
];

// Define the custom origin point (e.g., the top-left vertex)
const originPoint = { x: 100, y: 100 };

// Scale the vertices by 2x horizontally and 1.5x vertically around originPoint
Matter.Vertices.scale(vertices, 2, 1.5, originPoint);

console.log(vertices);
// Resulting vertices:
// [{ x: 100, y: 100 }, { x: 300, y: 100 }, { x: 200, y: 250 }]

Applying Scaled Vertices to a Matter.js Body

If you are modifying vertices intended for an active physics body (Matter.Body), updating vertices directly with Matter.Vertices.scale does not automatically update the body's internal properties, such as mass, inertia, or bounding boxes.

To safely apply the transformed vertices to a body, use Matter.Body.setVertices:

const body = Matter.Bodies.fromVertices(200, 200, vertices);

// Define origin to scale around (e.g., world coordinate or local body position)
const pivot = { x: body.position.x, y: body.position.y };

// Scale vertices in-place
Matter.Vertices.scale(body.vertices, 1.5, 1.5, pivot);

// Recompute mass, inertia, and bounds based on the modified vertices
Matter.Body.setVertices(body, body.vertices);