The pack
geometry
function geometry(): Pack<{ geometry: GeometryApi }>
The geometry pack: shapes and curves as data with the maths on them — points along, random inside, contains, bounds, transforms, intersections. Headless, no columns, no passes. Particle zones, paths and AI read it.
Helpers
encircled
function encircled(path: ReadonlyArray<Vec2>, p: Vec2): boolean
Is the point inside the loop the trail has just closed? False while the trail has closed none.
encircledAll
function encircledAll<T extends Vec2>(path: ReadonlyArray<Vec2>, targets: ReadonlyArray<T>): T[]
Every target inside the loop the trail has just closed; none while it has closed none.
findLoop
function findLoop(path: ReadonlyArray<Vec2>): Vec2[] | null
The loop a trail has just closed, or null: when the trail's newest segment crosses an earlier one, the polygon from the crossing round the trail and back to it. Draw a lasso, encircle enemies (Quantum), close off territory.
points
function points(s: Shape, n: number, seamless = true): Vec2[]
n points along the outline or curve, evenly by length; seamless (default true) leaves out the closing duplicate on a closed shape.
scale
function scale(s: Shape, sx: number, sy = sx, ox = 0, oy = 0): Shape
Scale a shape about (ox, oy): a new shape. A circle scaled unevenly becomes an ellipse.
Functions
area
function area(s: Shape): number
The enclosed area; 0 for curves and lines. A polygon's is unsigned.
bake
function bake(s: Shape, samples = 128): { points: Float32Array; length: number; closed: boolean }
Bake a shape by ARC LENGTH: samples points (default 128, at least 2) spaced evenly along it, as a flat
[x, y, …] Float32Array, with its length and whether it is closed (an area's outline). bakedAt on the result
moves at constant speed, which pointAt on a bezier or spiral does not.
bakedAt
function bakedAt(b: { points: Float32Array; closed: boolean }, t: number, out: Vec2 = { x: 0, y: 0 }): Vec2
The point at t (0..1 by length) on a baked curve.
bounds
function bounds(s: Shape): Box
The axis-aligned bounding box. Curves are sampled.
centroid
function centroid(s: Shape): Vec2
The centroid: area-weighted for areas, the midpoint of the bounds for curves.
closestPoint
function closestPoint(s: Shape, x: number, y: number): Vec2
The closest point on the shape's outline (or curve) to (x, y); sampled for curves, exact for lines, circles and polygons.
contains
function contains(s: Shape, x: number, y: number): boolean
Does the shape contain the point? Curves, lines and points never do; a ring is the band between inner and r.
isCurve
function isCurve(s: Shape): boolean
Is the shape a curve or outline only (no inside)? Points, lines, arcs, beziers, open splines, spirals, waves, paths.
length
function length(s: Shape): number
The outline's length (perimeter), or the curve's length. Curves are measured by 64 samples.
lineIntersections
function lineIntersections(ax: number, ay: number, bx: number, by: number, s: Shape): Vec2[]
Where segment (ax, ay)→(bx, by) crosses the shape's outline, as points along the segment in order; empty when it does not. Lines, circles, rings and polygons exact; other shapes via 48 points on their outline. An area's outline is closed; an open curve (an arc, a bezier, an open spline, a spiral, a wave) is walked from one end to the other, never across the gap between its ends. A path is tested segment by segment, and a point is crossed only when the segment passes through it.
overlaps
function overlaps(a: Shape, b: Shape): boolean
Do two area shapes overlap (share any interior or touch)? Exact for circle/circle, circle/rect, rect/rect; everything else via polygons (separating axes for convex, edge tests plus containment otherwise). Curves never overlap.
pointAt
function pointAt(s: Shape, t: number, out: Vec2 = { x: 0, y: 0 }): Vec2
The point at t (0..1) along the shape's outline, or along the curve. Closed shapes wrap; a rect starts at its top-left and goes clockwise; a circle starts at its right (0°).
pointsByStep
function pointsByStep(s: Shape, step: number): Vec2[]
Points along the outline or curve spaced step units apart (by length).
randomPoint
function randomPoint(s: Shape, rng: Rng, out: Vec2 = { x: 0, y: 0 }): Vec2
A uniformly random point INSIDE an area shape, or ON a curve, line or point. Rejection-samples polygons against their bounds.
rotate
function rotate(s: Shape, deg: number, ox = 0, oy = 0): Shape
Rotate a shape about (ox, oy) by deg degrees: a new shape. Circles, rings and ellipses move but keep their axes; a rect becomes a polygon.
toPolygon
function toPolygon(s: Shape, samples = 32): Extract<Shape, { kind: 'polygon' }>
The outline as a polygon (curves and round shapes sampled with samples points).
translate
function translate(s: Shape, dx: number, dy: number): Shape
Move a shape by (dx, dy): a new shape.
Constants
geometryApi
const geometryApi: GeometryApi
The geometry API object, for packs that import rather than compose.
SHAPE_KINDS
const SHAPE_KINDS: ReadonlyArray<ShapeKind>
Every shape kind.
Types
Box
interface Box
An axis-aligned box.
x: number— Left.y: number— Top.w: number— Width.h: number— Height.
GeometryApi
interface GeometryApi
game.geometry: every function of this module by name, plus the shape kinds.
pointAt: typeof pointAt— The point at t along the outline or curve.length: typeof length— Outline or curve length.area: typeof area— Enclosed area.points: typeof points— n points along the outline, evenly by length.pointsByStep: typeof pointsByStep— Points spacedstepapart.contains: typeof contains— Point-in-shape.randomPoint: typeof randomPoint— A random point inside (or on a curve).bounds: typeof bounds— Bounding box.centroid: typeof centroid— Centroid.closestPoint: typeof closestPoint— Closest outline point.translate: typeof translate— Move.rotate: typeof rotate— Rotate, degrees, about a point.scale: typeof scale— Scale about a point.toPolygon: typeof toPolygon— The outline as a polygon.lineIntersections: typeof lineIntersections— Segment–outline crossings.overlaps: typeof overlaps— Two areas overlap.isCurve: typeof isCurve— Is it a curve (no inside)?bake: typeof bake— Bake by arc length.bakedAt: typeof bakedAt— A point on a baked curve.findLoop: typeof findLoop— The loop a self-crossing trail has just closed.encircled: typeof encircled— Is a point inside the loop the trail just closed?encircledAll: typeof encircledAll— Every target inside the loop the trail just closed.readonly kinds: ReadonlyArray<ShapeKind>— Every shape kind.
Shape
type Shape = | { kind: 'point'; x: number; y: number } | { kind: 'line'; x1: number; y1: number; x2: number; y2: number } | { kind: 'circle'; x: number; y: number; r: number } | { kind: 'ring'; x: number; y: number; r: number; inner: number } | { kind: 'arc'; x: number; y: number; r: number; start: number; end: number } | { kind: 'sector'; x: number; y: number; r: number; start: number; end: number } | { kind: 'ellipse'; x: number; y: number; rx: number; ry: number } | { kind: 'rect'; x: number; y: number; w: number; h: number } | { kind: 'triangle'; x1: number; y1: number; x2: number; y2: number; x3: number; y3: number } | { kind: 'polygon'; points: ReadonlyArray<number> } | { kind: 'quadratic'; x1: number; y1: number; cx: number; cy: number; x2: number; y2: number } | { kind: 'cubic'; x1: number; y1: number; c1x: number; c1y: number; c2x: number; c2y: number; x2: number; y2: number } | { kind: 'spline'; points: ReadonlyArray<number>; closed?: boolean } | { kind: 'spiral'; x: number; y: number; r1: number; r2: number; turns: number; start?: number } | { kind: 'wave'; x1: number; y1: number; x2: number; y2: number; amplitude: number; cycles: number; shape?: 'sine' | 'zigzag' | 'square' } | { kind: 'path'; segments: ReadonlyArray<Shape> }
A shape or curve, by kind. Angles in degrees (0 right, 90 down), positions in world units. points lists are flat [x, y, x, y…]. spiral winds from radius r1 to r2 over turns from angle start; wave runs from (x1, y1) to (x2, y2) with cycles oscillations of amplitude across it.
ShapeKind
type ShapeKind = Shape['kind']
A shape's kind name.
Vec2
interface Vec2
A point.
x: number— x.y: number— y.


