cga

2D conformal geometric algebra for the plane: points, lines, circles, and dipoles, plus the segments, polygons, and polylines composed from them, and the versors (Motor, Flector) that move them — immutable Kotlin types joined by infix operators (join, meet, dot, on, intersects, distanceTo, angleTo, collide, escape, gap, coerceOut, coerceIn, coerceOn), the containment operator in/!in, the orientation flip -, and the transform action *.

The algebra is conformal GA over the null basis e1..e4 (e1, e2 Euclidean; e3 projective; e4 the point at infinity). Components are stored exact at full Double precision; equality and predicates round at the SCALE quantum — store exact, round only for identity.

Every shape class is open and carries a copy rebuild hook, and the shape-preserving operations (*, -, coerceOut, coerceIn, coerceOn, canonical) are generic over the receiver's type: a subclass that overrides its shape's copy comes back from every such operation as itself.

Packages

Link copied to clipboard
common
Link copied to clipboard
common
Link copied to clipboard
common

The constraint tier: operations that solve for the motion satisfying a geometric relation and return the shape already moved. The dual verbs coerceOut and coerceIn keep a polygon out of — respectively inside — an oriented solid region, in the standard library's coerce posture: an already-valid receiver comes back untouched, a violating one minimally moved — generic over the receiver's type, so a Polygon subclass comes back as its own class. coerceOn, the equality constraint beside them, rests a polygon against the region: where the two inequality verbs accept every pose that does not violate, coerceOn accepts exactly the touching ones — resolved through collide when the subject overlaps the region and through gap when it lies apart.

Link copied to clipboard
common
Link copied to clipboard
common

The algebra tier: infix operators over the shapes, returning geometry or Double raw at full precision (the segment-bounded meets return null on a miss) — scalar multiplication (*), the inner-product family (dot), join (join, the wedge ∧), meet (meet, the antiwedge ∨), and the two interior products: contraction (contract, the bulk contraction a ∨ b^★) and expansion (expand, the weight expansion a ∧ b^☆).

Link copied to clipboard
common

The projection tier: composite operations built from the products. Projection (project, b ∨ (a ∧ b^☆)) carries a shape onto a higher-grade target; antiprojection (antiproject, b ∧ (a ∨ b^☆)) carries one onto a lower-grade target. Both divide by the target's self-pairing b ∘ b, so the receiver's weight and orientation carry through — an imaginary target (negative self-pairing) negates every component, and a target whose self-pairing vanishes (a line at infinity, a zero-radius circle, coincident endpoints) floods the division instead of throwing. The one bounded target, a Segment, is reached through its carrier's projection and clamped to the segment — no self-pairing of its own.

Link copied to clipboard
common

The query tier, split by answer kind: predicates carries the Boolean queries, rounded at the SCALE quantum; measures carries the scalar measurements — raw Euclidean distances and angles; the data queries at this level — penetration and gap — answer with geometry-flavored data — offending edge, depth, normal, the shortest segment — whose values stay raw behind rounded existence gates.

common

The measure tier: scalar Euclidean measurements answered raw — distances as non-negative Doubles, angles as signed Angles.

common

The decision tier: predicates answering Boolean where the operator tier answers geometry — incidence (on), containment (contains, spelled in/!in), and region overlap (intersects). Every answer is rounded at the SCALE quantum.

Link copied to clipboard
common
common
common
Link copied to clipboard
common

The transform tier: the versors that move shapes — Motor (rotations and translations, built by the T and R factories) and Flector (reflections and glide reflections, built by F and G) — applied with shape * versor and composed with versor * versor. The per-shape actions live in the primitives and composites subpackages; a receiver typed only as Shape moves through the same spelling — the Shape * Versor dispatch delegates to the per-shape actions, preserving the receiver's class.

common

The action tier for the composites: shape * versor moves a segment by its endpoints and a polyline or polygon vertex-by-vertex, with the same * Motor / * Flector / * Versor trio per shape. Results carry full raw Double precision, and each form is generic over the receiver's type — the moved geometry returns through the shape's copy hook, so a subclass overriding it comes back as its own class.

common

The action tier for the primitives: shape * versor applies a versor's motion to each of the five primitives and returns the same primitive type — a * Motor form, a * Flector form, and a * Versor dispatch per shape. Results carry full raw Double precision, and each form is generic over the receiver's type — the moved geometry returns through the shape's copy hook, so a subclass overriding it comes back as its own class. A motor's rigid motion preserves orientation; a flector's mirror motion reverses it, and the oriented types — Line, Dipole, Circle — record the reversal in their own components. Imaginary and at-infinity operands transform faithfully — first-class data, never an error — and no action on a primitive throws.