17.20 Geometry Libraries and Practical Patterns

Most real-world geometry software is not built from a single algorithm.

17.20 Geometry Libraries and Practical Patterns

Problem

Most real-world geometry software is not built from a single algorithm.

A mapping system may use:

point-in-polygon
spatial indexes
polygon clipping
bounding boxes
coordinate transforms

A CAD application may use:

line intersections
half-plane constraints
mesh generation
topological validation

A game engine may use:

collision detection
broad-phase indexing
ray casting
convex hulls

The challenge is not merely implementing individual algorithms. The challenge is combining them into reliable geometric systems.

Solution

Treat geometric algorithms as reusable building blocks.

Throughout this chapter, a small number of primitives have appeared repeatedly:

orientation
cross product
dot product
distance comparison
bounding-box tests
line intersection

Many advanced algorithms differ primarily in how they combine these primitives.

A practical geometry library should emphasize:

robust predicates
clear data structures
consistent coordinate semantics
reusable components

rather than isolated algorithms.

Core Geometric Types

Most libraries begin with a small set of geometric types.

from dataclasses import dataclass

@dataclass(frozen=True)
class Point:
    x: float
    y: float

Vector operations:

@dataclass(frozen=True)
class Vector:
    x: float
    y: float

Rectangles:

@dataclass(frozen=True)
class Rectangle:
    left: float
    bottom: float
    right: float
    top: float

Segments:

@dataclass(frozen=True)
class Segment:
    start: Point
    end: Point

Polygons:

@dataclass
class Polygon:
    vertices: list[Point]

Keep the primitives simple.

Complexity belongs in algorithms, not data containers.

Centralizing Predicates

Avoid scattering orientation logic throughout the codebase.

Instead:

def orientation(a, b, c):
    return (
        (b.x - a.x) * (c.y - a.y)
        -
        (b.y - a.y) * (c.x - a.x)
    )

Then reuse it everywhere:

convex hull
segment intersection
point-in-polygon
rotating calipers
half-plane intersection

A bug fixed in one place automatically improves every dependent algorithm.

Bounding Boxes First

Many expensive geometric operations can be preceded by a cheap bounding-box test.

For segments:

def segment_box(segment):
    return Rectangle(
        min(segment.start.x, segment.end.x),
        min(segment.start.y, segment.end.y),
        max(segment.start.x, segment.end.x),
        max(segment.start.y, segment.end.y)
    )

Before computing a precise intersection:

if not boxes_intersect(
    segment_box(a),
    segment_box(b)
):
    return False

This pattern appears constantly in practical geometry software.

Layered Query Architecture

A common architecture:

spatial index
    ↓
bounding-box filter
    ↓
exact predicate

Example:

R-tree
    ↓
candidate polygons
    ↓
point-in-polygon

Or:

spatial hash
    ↓
candidate objects
    ↓
exact collision test

This separation improves performance without compromising correctness.

Convex vs General Geometry

Many algorithms become dramatically simpler on convex inputs.

For example:

Problem General Polygon Convex Polygon
Point containment O(n) O(log n) possible
Diameter Complex Rotating calipers
Intersection More difficult Simpler
Optimization Harder Easier

Whenever possible:

general geometry
        ↓
convex decomposition
        ↓
convex algorithms

This strategy appears in physics engines and optimization systems.

Immutable Geometry Objects

Geometry objects often benefit from immutability.

@dataclass(frozen=True)
class Point:
    x: float
    y: float

Advantages:

thread safety
easier debugging
predictable behavior
hashability

Mutable structures are usually reserved for performance-critical code.

Separating Predicates and Constructions

Consider segment intersection.

Predicate:

segments_intersect(a, b)

Construction:

segment_intersection_point(a, b)

Do not combine them unnecessarily.

Many algorithms need only:

yes/no

answers.

Computing intersection coordinates every time wastes work and increases numerical exposure.

A useful design:

if segments_intersect(a, b):
    point = segment_intersection_point(a, b)

The expensive operation happens only when necessary.

Coordinate Systems

Many geometry bugs arise from mixed coordinate systems.

Examples:

screen coordinates
world coordinates
tile coordinates
geographic coordinates

A geometry library should clearly define:

units
origin
axis directions
projection assumptions

For example:

screen:
y increases downward

mathematics:
y increases upward

Mixing the two silently can invert orientation tests.

Geometry Pipelines

Practical applications often follow a geometric pipeline.

Example:

raw points
    ↓
deduplicate
    ↓
convex hull
    ↓
diameter

Or:

polygons
    ↓
spatial index
    ↓
candidate selection
    ↓
exact intersection

Or:

GPS coordinates
    ↓
projection
    ↓
spatial query
    ↓
visualization

Thinking in pipelines simplifies system design.

Testing Geometric Software

Geometry requires more than ordinary unit tests.

Include:

duplicate points
collinear points
large coordinates
small coordinates
touching boundaries
overlapping objects
empty inputs
single-point inputs
degenerate polygons

Randomized testing is especially useful.

Example:

for _ in range(10000):
    points = random_points()

    assert (
        convex_hull(points)
        ==
        reference_convex_hull(points)
    )

Comparing against a slower reference implementation often reveals subtle bugs.

Using Existing Libraries

For production systems, consider established geometry libraries rather than implementing everything from scratch.

Examples include:

  • entity["software","CGAL","Computational Geometry Algorithms Library"]
  • entity["software","GEOS","Geometry Engine Open Source"]
  • entity["software","JTS Topology Suite","Java geometry library"]
  • entity["software","Shapely","Python geometry library"]
  • entity["software","Boost.Geometry","C++ geometry library"]

These libraries provide:

robust predicates
polygon operations
spatial indexes
topological validation
coordinate transforms

and have received extensive real-world testing.

Common Design Patterns

Several patterns appear repeatedly.

Broad Phase Then Narrow Phase

spatial index
    ↓
candidate set
    ↓
exact geometry

Filter Then Refine

bounding box
    ↓
precise test

Convex Reduction

general shape
    ↓
convex pieces
    ↓
simpler algorithms

Coordinate Compression

large coordinates
    ↓
compressed coordinates
    ↓
efficient data structure

Exact Predicate, Approximate Construction

robust decision
    ↓
approximate coordinate output

This pattern often yields the best balance between correctness and performance.

Complexity Awareness

Geometry libraries should expose algorithmic expectations.

Examples:

Operation Complexity
Orientation O(1)
Segment intersection O(1)
Convex hull O(n log n)
Closest pair O(n log n)
KD-tree query O(log n) average
Point-in-polygon O(n)
Polygon area O(n)

Making these costs visible helps users select the appropriate algorithm.

Common Pitfalls

Reimplementing Everything

Many geometric operations are surprisingly subtle.

Mixing Integer and Floating Arithmetic

Conversions should be explicit.

Ignoring Degenerate Inputs

Real-world data is rarely ideal.

Coupling Algorithms Too Tightly

Reusable predicates and utilities reduce duplication.

Assuming Visual Correctness

Rendered output may appear correct while topology is invalid.

Discussion

Practical computational geometry is less about individual algorithms and more about composition. Convex hulls rely on orientation tests. Sweep-line algorithms rely on interval structures. Spatial indexes rely on bounding boxes. Voronoi diagrams connect naturally to Delaunay triangulations. The same small collection of predicates and representations appears repeatedly.

A well-designed geometry library reflects this structure. It provides reliable primitives, keeps geometric decisions centralized, separates filtering from exact computation, and treats robustness as a first-class concern. With those foundations in place, even sophisticated geometric systems become manageable.