Chamfering Polygon Corners in Matter.js
In Matter.js, rigid bodies defined by custom polygon vertices often
have sharp, jagged corners that can snag on other objects or create
unnatural collision behaviors. The Matter.Vertices.chamfer
method provides a built-in algorithmic solution to this problem by
slicing and rounding sharp vertex points into smooth bevels or curved
arcs. This article explains how the chamfering algorithm functions
internally, how its parameters manipulate polygon geometry, how to
implement it in your code, and the performance trade-offs associated
with increasing vertex counts for collision detection.
How the Chamfer Algorithm Works
At its core, chamfering is the process of cutting away a sharp edge or corner to create a symmetrical sloping or rounded edge. In standard 2D vector geometry, a polygon vertex is formed where two linear segments meet at a distinct angle.
When you pass a set of vertices into
Matter.Vertices.chamfer, the function executes the
following sequence for each corner:
- Edge Vector Analysis: The algorithm inspects the target vertex along with its immediate preceding and succeeding neighbor vertices, determining the interior angle formed by the two connecting edges.
- Tangent Point Calculation: Based on a specified
radius, the function moves inward along both incident edges away from the corner, marking the points where the curve or bevel must begin and end. - Arc Interpolation: Instead of leaving a flat bevel (a simple cut), the function calculates a series of intermediate points along an arc that connects the two tangent points, smoothly approximating a rounded corner.
- Vertex Replacement: The original sharp vertex is removed from the array and replaced with the newly generated sequence of arc points.
Parameters of
Matter.Vertices.chamfer
The method typically accepts the vertex array and a chamfer configuration object (or a direct radius value). The primary parameters governing this transformation include:
radius: Defines the distance from the original vertex to the start of the chamfer along adjacent edges. This can be specified as a single uniform number for all corners, or as an array of individual numbers to round specific corners differently (or leave some sharp by assigning a radius of0).quality: Controls the resolution of the rounding. Aqualityof1or less results in a flat bevel (a single diagonal cut replacing the corner). Higher values insert more intermediate vertices along the arc, creating a visibly smoother curve.qualityMinandqualityMax: Thresholds used by Matter.js to dynamically clamp the number of generated points based on the sharpness of the angle, preventing overly dense vertex clusters on obtuse corners.
Implementation Example
To apply chamfering to a custom polygon body, the chamfer method is
typically called on the vertex set prior to passing it to
Matter.Bodies.fromVertices:
// Define a triangle with sharp corners
const coords = [
{ x: 0, y: 0 },
{ x: 100, y: 0 },
{ x: 50, y: 100 }
];
// Create Matter.js vertex objects
let vertices = Matter.Vertices.fromPath("0 0 100 0 50 100");
// Apply chamfering
Matter.Vertices.chamfer(vertices, [10, 10, 15], 1, 2, 8);
// Create the rigid body with rounded corners
const roundedBody = Matter.Bodies.fromVertices(200, 200, [vertices]);
Matter.Composite.add(engine.world, roundedBody);You can also pass chamfer configurations directly inside the body
options when using standard helper factories like
Matter.Bodies.polygon or
Matter.Bodies.rectangle:
const box = Matter.Bodies.rectangle(100, 100, 80, 80, {
chamfer: { radius: 10 }
});Physical and Computational Considerations
While chamfered corners significantly improve simulation aesthetics and prevent bodies from catching on seams, they have direct physical implications:
- Collision Normal Multiplication: Matter.js utilizes the Separating Axis Theorem (SAT) for convex collision detection. Because SAT projects shapes along the perpendicular axes (normals) of every edge, replacing one corner vertex with an arc of five vertices creates five new edges and five new axes to compute during every collision check.
- Convexity and Decomposition: If a chamfer radius is
set too large relative to the length of an adjacent edge, the generated
arc can overlap neighboring chamfers or invert the edge. This can turn a
convex shape concave, requiring the shape to be decomposed into multiple
sub-bodies via the
poly-decomplibrary, which further increases computational overhead.