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)vertices: An array ofVectorobjects ([{ x, y }, ...]) defining the polygon.scaleX: The multiplication factor along the horizontal axis.scaleY: The multiplication factor along the vertical axis.point(optional): The originVector({ x, y }) around which the scaling takes place.
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);