What it does
Every shape is an object such as { kind: 'circle', x, y, r } or { kind: 'sector', x, y, r, start, end }, so shapes
can be stored in level data, sent over a network or built on the fly. Some are areas, with an inside: circles, rings,
sectors, ellipses, rectangles, triangles, polygons and closed splines. Others are curves, with a length but no inside:
points, lines, arcs, quadratic and cubic beziers, open splines and paths of segments laid end to end. Spirals and waves
are curves too.
The same functions work on every kind. pointAt finds the point a fraction of the way along an outline or curve, and
points and pointsByStep space points evenly by length, for enemies in formation round a ring or coins along an arc.
randomPoint gives a uniformly random point inside an area, for spawning. contains, closestPoint,
lineIntersections and overlaps answer AI and gameplay questions: is the player in the guard's sight cone, where does
a laser hit the wall, does this blast radius touch that crate. translate, rotate and scale return new shapes, and
length, area, bounds and centroid measure them.
It also handles trails. findLoop notices when a trail of points has just crossed itself and returns the loop it
closed, and encircled and encircledAll say which targets are inside that loop: a lasso, encircling enemies, or
closing off territory.
Features
- Sixteen shape kinds — from points and lines through sectors, polygons and beziers to Catmull-Rom splines, spirals, waves and paths of mixed segments.
- Points along — at a fraction of the way, evenly by count, or a fixed distance apart, with closed shapes wrapping.
- Random inside — uniform points inside any area, or on a curve, from a random generator you pass in.
- Containment — point-in-shape for every area, including the band of a ring and the slice of a sector.
- Crossings and overlaps — where a segment crosses an outline, in order along it, and whether two areas share any point.
- Transforms — move, rotate and scale about a point; a rotated rectangle becomes a polygon and an unevenly scaled circle an ellipse.
- Constant-speed curves —
bakesamples a curve by arc length, so something moving along a bezier keeps a steady speed. - Loops and lassos —
findLoop,encircledandencircledAllfor trails that close round targets.
Good for
- Particle zones — effects born inside a triangle or along a bezier and killed on entering a polygon.
- Movement along curves — enemies swooping on beziers, platforms on arcs, formations round a ring.
- AI sight checks — a guard's cone as a sector and a quick
containstest. - Spawning — random points inside an arena, a zone or a polygonal room.
- Shooting and lasers — where a ray first crosses a wall or a shield.
- Lasso and encircle games in the style of the arcade game Quantum, where a closed trail captures what it surrounds.
Make it yours
There is nothing to configure: shapes are data you build however your game likes, and every function is a pure function
of them. The pack is composed for game.geometry, and its functions are also exported for code and packs that import
them directly. Two quite different uses: a shooter that lays out an enemy wave as twelve points round a ring and
moves each one along a cubic baked for constant speed; and a stealth game that never draws a shape at all, keeping a
sector per guard and testing contains against the player each frame.
A quick look
A guard's sight cone, and a point along a curve:
const cone = { kind: 'sector', x: guard.x, y: guard.y, r: 200, start: guard.facing - 30, end: guard.facing + 30 };
if (game.geometry.contains(cone, player.x, player.y)) alert();
const p = game.geometry.pointAt({ kind: 'cubic', x1: 0, y1: 0, c1x: 50, c1y: -80, c2x: 150, c2y: -80, x2: 200, y2: 0 }, t);
Works with
particles-2d— its emit zones and death zones are these shapes.path— walkers that move along these shapes and curves.collisionandphysics-2d— for contacts and responses rather than a yes or no overlap.visibility-2d— for real line of sight round walls in a continuous world.
Good to know
- Curves are sampled for length, bounds and closest point (64 points or more) and for intersections (48 points); lines, circles and polygons are exact.
overlapsanswers yes or no and gives no contact; usephysics-2dorcollisionfor that.- Polygons are assumed simple (not self-intersecting), and angles are in degrees, 0 to the right and 90 down.
- It is 2D only.






