BasicCompGeometry.jl

A comprehensive library for basic computational geometry in Julia.

BasicCompGeometry.jl provides efficient, high-dimensional primitives and algorithms for computational geometry, leveraging Julia's multiple dispatch and the StaticArrays.jl ecosystem.

A core concept in the library is the AbsPntSeq, which is treated as a sequence of points. This can represent a simple point set, a polygonal chain, or a classical closed polygon. AbsPolygon is provided as an alias for backward compatibility.

Features

  • Multi-Dimensional Primitives: Support for Points, Segments, Lines, Point Sequences (PntSeq), and Axis-Aligned Bounding Boxes (BBox) in any dimension.
  • Zero-Copy Matrix Integration: Use MatPntSeq to treat columns of a matrix as points without copying memory.
  • Multiple Coordinate Types: Works seamlessly with Float64, Int64, and other numeric types.
  • Geometric Predicates: Fast checks for turns (left/right) and containment.
  • Curve Algorithms: Hausdorff distance-based simplification and uniform resampling.
  • Spatial Decomposition: Efficient Bounding Box Trees (BBT) and Well-Separated Pairs Decompositions (WSPD).
  • 2D Transformations: Efficient translation and rotation for planar geometry.

Algorithms

The library implements a variety of classic and modern geometric algorithms:

  • Convex Hull: 2D (Monotone Chain) and 3D (Gift-wrapping).
  • Diameter: Exact $O(n^2)$ and $(1+\epsilon)$-approximation via WSPD.
  • Spatial Decomposition: WSPD and Bounding Box Tree (BBT) construction.
  • Curve Processing: Hausdorff distance-based simplification and uniform resampling.
  • Metric Space Algorithms: Greedy permutation (incremental furthest-point sampling).
  • Advanced Optimization: Longest Convex Subset calculation.
  • Geometric Predicates: Fast turn_sign, is_left_turn, is_right_turn, and is_collinear checks.

Data Structures

BasicCompGeometry provides highly optimized, type-safe data structures:

  • Geometric Primitives: Point{D, T}, Segment{D, T}, Line{D, T}, and BBox{D, T}.
  • Point Sequences: PntSeq{D, T} and the matrix-backed MatPntSeq{D, T}.
  • Tree Structures: Hierarchical BBT.Tree and BBT.Node.
  • Metric Spaces: AbsFMS interface and PointsSpace wrappers.
  • Utilities: VArray for efficient permutation and original index tracking.

Metric Spaces

The library provides a robust framework for working with Finite Metric Spaces (FMS), allowing algorithms to operate on abstract indices while the underlying representation handles the distance calculations.

The AbsFMS Interface

All metric spaces subtype AbsFMS. They represent a set of $n$ points identified by indices $1 \dots n$. The core interface requires:

  • size(space): Number of points.
  • dist(space, i, j): Distance between points at indices $i$ and $j$.

Provided Metric Space Types

  • PointsSpace{T}: A simple wrapper around a Vector of any objects that support the dist(p1, p2) function.
  • MPointsSpace{T}: A matrix-backed space where each column is treated as a point in $\mathbb{R}^d$. It uses optimized Euclidean distance calculations.
  • AbsPntSeq: Any point sequence (like PntSeq or MatPntSeq) automatically implements the AbsFMS interface.
  • PermutMetric: A powerful decorator that creates a "view" of an existing metric space under a specific permutation or subset of indices.
  • SpherePMetric: A specialized space where the distance between two points $i$ and $j$ is the angle they form at a fixed base point $b$.

Metric Space Algorithms

  • Greedy Permutation: Generates a furthest-point ordering of the metric space.
    • greedy_permutation_naive: Standard $O(n^2)$ implementation of Gonzalez's algorithm.
    • greedy_permutation_vanity: A variation that breaks distance ties using a secondary "vanity" score.

Quick Start

using BasicCompGeometry

# Create points
p1 = point(0.0, 0.0)
p2 = point(3.0, 4.0)

# Calculate distance
d = dist(p1, p2) # 5.0

# Work with segments
seg = Segment(p1, p2)
len = geom_length(seg)

# Bounding boxes
bb = BBox(p1, p2)
is_inside(point(1.0, 1.0), bb) # true

# Point Sequences (Polygons)
ps = PntSeq([p1, p2, point(0.0, 4.0)])
cardin(ps) # 3

API Reference

Points

BasicCompGeometry.PointType
Point{D, T}

Type alias for SVector{D, T} from StaticArrays. Provides a concise way to work with fixed-size coordinate vectors. It inherits all efficient operations from StaticArrays.

source
BasicCompGeometry.pointFunction
point(args...)

Construct a Point (SVector) from a list of coordinates or a single collection. Example: point(1.0, 2.0) or point([1, 2, 3]).

source
BasicCompGeometry.distFunction
dist(P::PointsSpace, i::Int, j::Int)

Returns the distance between the i-th and j-th point in the vector.

source
dist(P::MPointsSpace, i::Int, j::Int)

Euclidean distance between column i and column j.

source
dist(p, q)

Calculate the Euclidean distance between two points p and q.

source
dist(seg, point)

Return the minimum Euclidean distance between the segment seg and a query point qr. This calculates the distance to the nearest point on the segment.

source
dist(seg1, seg2)

Return the minimum Euclidean distance between two segments a and b in D dimensions. This uses an optimization approach to find the closest points on both segments.

source
dist(P::AbsPntSeq, i::Int, j::Int)

Distance between vertex i and vertex j of the point sequence. Part of the AbsFMS interface.

source
dist(bb1, bb2)

Return the minimum Euclidean distance between two bounding boxes. Returns 0 if the boxes intersect.

source
BasicCompGeometry.dist_sqFunction
dist_sq(p, q)

Calculate the square of the Euclidean distance between two points p and q. This is more efficient than dist(p, q) if only relative distances are needed.

source

Segments & Lines

BasicCompGeometry.LineType
Line{D, T}

Infinite line in D dimensions defined by a point p and a direction vector u. The line is parametrised as p + u * t for all real t. u represents the orientation and does not need to be normalized.

source
BasicCompGeometry.geom_lengthFunction
geom_length(seg)

Return the Euclidean length of the segment.

source
geom_length(pnt_seq)

Calculate the total Euclidean length of the polygonal curve (sum of edge lengths).

source
BasicCompGeometry.atFunction
at(seg, t)

Return the point on the segment at parameter t. t=0 returns the start point p, and t=1 returns the end point q. The function uses a convex combination of the endpoints.

source
at(pnt_seq, t)

Return a point on the polygonal curve at the normalized parameter t in [0, 1]. t=0 is the first vertex, t=1 is the last vertex. The parameterization is based on arc-length (linear interpolation along edges).

source
BasicCompGeometry.nn_pointFunction
nn_point(p, q, qr)

Return the nearest point on the segment defined by endpoints p and q to the query point qr.

source
nn_point(seg, qr)

Return the nearest point on segment seg to query point qr.

source
BasicCompGeometry.dist_segment_segmentFunction
dist_segment_segment(a_p, a_q, b_p, b_q)

Calculate the minimum distance between two segments defined by [a_p, a_q] and [b_p, b_q]. For non-parallel segments, it solves for the parameters s, t that minimize the distance. If segments are parallel, it falls back to point-segment distance calculations.

source
BasicCompGeometry.bisection_pointFunction
bisection_point(seg, p, q)

Determine if the segment seg intersects the bisector plane of points p and q. Return (intersects::Bool, t::Float64, point::Point). t is the parameter on the segment where intersection occurs.

source

Point Sequences

BasicCompGeometry.AbsPntSeqType
AbsPntSeq{D, T}

Abstract supertype for all representations of a sequence of points (polygonal chain or polygon) in D dimensions with coordinate type T. Subtypes must implement the AbsFMS interface (dist and size) and provide access to vertices.

source
BasicCompGeometry.PntSeqType
PntSeq{D, T}

A wrapper around Vector{Point{D, T}} representing a sequence of points, a polygonal curve, or a classical polygon in D dimensions. The points are stored sequentially in the pnts field.

PntSeq is a subtype of AbsPntSeq{D, T}, meaning it can be treated as a finite metric space where its vertices are the points and the distance is Euclidean.

source
BasicCompGeometry.MatPntSeqType
MatPntSeq{D, T, M, V}

A representation of a sequence of points backed by an AbstractMatrix{T} of size D x N. It provides a zero-copy view of the matrix columns as Point{D, T} objects.

source
BasicCompGeometry.prefix_lengthsFunction
prefix_lengths(pnt_seq)

Return a vector containing the cumulative arc-length distances at each vertex of the point sequence. The first element is always 0.0, and the last is the total geometric length.

source
BasicCompGeometry.simplifyFunction
simplify(P, r)

Perform distance-based simplification of the point sequence P. Vertices are skipped if they are within distance r of the last kept vertex. Returns (simplified_pnt_seq, kept_indices).

source

Bounding Boxes

BasicCompGeometry.BBoxType
BBox{D, T}

Axis parallel bounding box in D dimensions. The fields mini and maxi store the lower and upper bounds of the box for each dimension.

source
BasicCompGeometry.widthFunction
width(bb, dim=1)

Return the extent of the bounding box in the specified dimension dim. Defaults to the first dimension (width in 2D).

source
BasicCompGeometry.heightFunction
height(bb, dim=2)

Return the extent of the bounding box in the specified dimension dim. Defaults to the second dimension (height in 2D).

source
BasicCompGeometry.max_distFunction
max_dist(bb1, bb2)

Return the maximum possible Euclidean distance between any point in bb1 and any point in bb2. This is the distance between the two most distant corners of the boxes.

source
BasicCompGeometry.expand!Function
expand!(bb, factor)

Rescale the bounding box bb in-place by factor around its center. factor=2 doubles the side lengths.

source
BasicCompGeometry.expand_add!Function
expand_add!(bb, delta)

Padding operation: adds delta to each side of the box in-place. Each dimension's length increases by 2 * delta.

source

Transformations (2D)

BasicCompGeometry.translationFunction
translation(a, b)

Return a 3x3 homogeneous translation matrix for 2D coordinates. Translates by a along the X-axis and b along the Y-axis.

source
translation(p::Point{2})

Return a 3x3 translation matrix using the coordinates of 2D point p.

source
BasicCompGeometry.rotationFunction
rotation(x)

Return a 3x3 homogeneous rotation matrix for 2D coordinates. Rotates counter-clockwise by angle x (in radians).

source

Algorithms

BasicCompGeometry.hausdorff_simplifyFunction
hausdorff_simplify(P, w)

Simplify the pntseq P using a greedy approach based on the Hausdorff distance. The resulting pntseq vertices are a subset of the original vertices. For every segment [v_i, v_{i+1}] in the simplification, the Hausdorff distance to the original subcurve it replaces is at most w. Returns (simplified_pnt_seq, vertex_indices).

source
BasicCompGeometry.hausdorff_dist_subsegFunction
hausdorff_dist_subseg(P, rng)

Calculate the Hausdorff distance between the sub-point sequence P[rng] and the single segment connecting its first and last vertices. This is used as an error measure for curve simplification.

source
BasicCompGeometry.distance_inftyFunction
distance_infty(P, Q)

Calculate the maximum (L_∞) distance between corresponding vertices of two point sequences. Requires length(P) == length(Q). Useful for assessing the quality of point-to-point matching.

source
BasicCompGeometry.centroidFunction
centroid(P)

Calculate the centroid (arithmetic mean) of a collection of points P. Works with point sequences or vectors of points.

source
BasicCompGeometry.match_priceFunction
match_price(p_a, p_b, q_a, q_b)

Calculate a cost metric for matching the segment [p_a, p_b] to the segment [q_a, q_b]. The price is defined as the product of the sum of the lengths of the two edges and the average distance between their corresponding endpoints.

source