Apollonius is a lightweight, high-performance N-dimensional geometry library for Rust. It provides the mathematical and structural foundations for physics engines, collision detection systems, and spatial simulations using const generics.
Logical flow and relationships between modules. Algebra is the base; primitives build on it and share the SpatialRelation / Bounded / IntersectionResult API; space and utils support transforms and float handling.
flowchart TB
subgraph ROOT["apollonius"]
direction TB
subgraph ALGEBRA["algebra (foundation)"]
direction TB
POINTS["points.rs<br/>Point, Point2D, Point3D<br/>MetricSquared, EuclideanMetric"]
VECTORS["vectors.rs<br/>Vector, Vector2D, Vector3D<br/>VectorMetricSquared, EuclideanVector"]
MATRIX["matrix.rs<br/>Matrix<T,N,Tag> (General, Isometry, Affine)<br/>MatrixTag, IsAffine, IsIsometry"]
ANGLE["angle.rs<br/>Angle<br/>radians, degrees, sin, cos, tan"]
POINTS --> VECTORS
VECTORS --> MATRIX
end
subgraph PRIMITIVES["primitives (shapes + API)"]
direction TB
TRAITS["mod.rs<br/>SpatialRelation (closest_point, distance, contains)<br/>Bounded (aabb)<br/>IntersectionResult enum"]
LINE["line.rs<br/>Line (origin + direction)"]
SEG["segment.rs<br/>Segment (start + end)"]
AABB["aabb.rs<br/>AABB (min, max)"]
SPHERE["hypersphere.rs<br/>Hypersphere / Circle / Sphere"]
PLANE["hyperplane.rs<br/>Hyperplane (origin + normal)"]
TRI["triangle.rs<br/>Triangle (a, b, c)"]
TRAITS --> LINE
TRAITS --> SEG
TRAITS --> SPHERE
TRAITS --> PLANE
TRAITS --> TRI
TRAITS --> AABB
end
subgraph SPACE["space"]
LINEAR["Matrix × Point/Vector<br/>linear_ops: × Line, Segment, Hypersphere, Hyperplane, Triangle"]
AFFINE["AffineTransform (linear + translation)"]
LINEAR --> AFFINE
end
UTILS["utils.rs<br/>FloatSign, classify_to_zero"]
end
ALGEBRA -->|"Point, Vector"| PRIMITIVES
ALGEBRA -->|"Matrix, Vector"| SPACE
UTILS -->|"tolerance"| PRIMITIVES
UTILS -->|"tolerance"| ALGEBRA
subgraph FLOW["Typical usage flow"]
direction LR
F1["1. Build geometry<br/>(Point, Vector, Line, …)"]
F2["2. SpatialRelation / Bounded<br/>(closest_point, aabb, …)"]
F3["3. Intersection methods<br/>(intersect_*, IntersectionResult)"]
F1 --> F2 --> F3
end
- Algebra: All types use
T: Float(num_traits). Points and vectors are the coordinate types; Matrix (with type tagsGeneral,Isometry,Affineand traitsMatrixTag,IsAffine,IsIsometry) and Angle extend the toolbox. - Primitives: Each shape implements
SpatialRelation(and oftenBounded). Intersections between them returnIntersectionResult<T, N>(None, Tangent, Secant, Collinear, Single, HalfSpacePenetration). - Space: AffineTransform (linear part + translation); linear_ops:
Matrix × Point/VectorandMatrix/AffineTransform× Line, Segment, Hypersphere, Hyperplane, Triangle. Isometry tag required for hypersphere (radius preserved). - Utils:
classify_to_zeroandFloatSignfor robust float comparisons in primitives and algebra.
- N-Dimensional Support: Type-safe coordinates and vectors for 2D, 3D, and higher-dimensional spaces using Rust's
const generics. - Efficient Primitives:
- Hyperspheres: (Circles, Spheres, N-Spheres) with plane intersection and submerged volume ratio.
- Lines & Segments: Infinite lines and finite segments with parametric evaluation, projection, and full intersection APIs.
- Hyperplanes: Half-space queries, signed distance, and intersection with lines, segments, and hyperspheres.
- Triangles: N-dimensional triangles with centroid, area (Lagrange identity), and AABB.
- Broad-Phase Foundations: Native support for AABB (Axis-Aligned Bounding Boxes) with optimized overlap theorems.
- Unified Intersection Engine: A single
IntersectionResulttype covering:- None, Tangent(point), Secant(p1, p2), Collinear, Single(point) for point-like contacts.
- HalfSpacePenetration(depth) for hypersphere–hyperplane penetration.
- Point-to-Point Intersections: Line∩Line, Line∩Segment, Line∩Hypersphere, Line∩Hyperplane; Segment∩Segment, Segment∩Hypersphere, Segment∩Hyperplane, Segment∩Line; Hyperplane∩Line, Hyperplane∩Segment, Hyperplane∩Hypersphere; Hypersphere∩Line, Hypersphere∩Segment, Hypersphere∩Hyperplane.
- Numerical Stability: Robust floating-point classification via
classify_to_zeroandFloatSignto handle accumulation errors. - Type-safe matrices: Tags
General,Isometry,Affineand traitsMatrixTag,IsAffine,IsIsometryso you can restrict functions to specific matrix kinds (e.g. only isometries acting on hyperspheres). - Prelude and re-exports: All main types and traits are re-exported at the crate root. Use
use apollonius::prelude::*for one-shot imports (points, vectors, matrices, primitives, metric traits).
- Language: Rust (Stable)
- Math Traits:
num-traitsfor generic support overf32andf64. - Core Philosophy: Minimal dependencies; core logic is independent of rendering or external physics frameworks.
Add this to your Cargo.toml:
[dependencies]
apollonius = "0.1"Optional serde for serialization:
apollonius = { version = "0.1", features = ["serde"] }Importing: Use the crate root or the prelude. All core types and traits are re-exported:
// Explicit imports from the crate root
use apollonius::{Point, Vector, Matrix, General, Isometry, Affine, Line, Hypersphere};
// Or bring in the most used items in one go (includes metric traits for distances/magnitudes)
use apollonius::prelude::*;use apollonius::{Point, Vector, Line, Hypersphere, IntersectionResult};
let line = Line::new(Point::new([-5.0, 0.0]), Vector::new([1.0, 0.0]));
let sphere = Hypersphere::new(Point::new([0.0, 0.0]), 2.0);
match line.intersect_hypersphere(&sphere) {
IntersectionResult::Secant(p1, p2) => println!("Intersects at {:?} and {:?}", p1, p2),
IntersectionResult::Tangent(p) => println!("Grazing contact at {:?}", p),
_ => println!("No intersection"),
}Matrices are type-tagged: General (any N×N), Isometry (rotations; preserve distances), Affine (used in affine context). You can multiply them by points, vectors, and by primitives (Line, Segment, Hypersphere, Hyperplane, Triangle). AffineTransform = linear part + translation.
use apollonius::{General, Matrix, Point, Vector};
// Identity leaves point and vector unchanged
let id = Matrix::<f64, 2, General>::identity();
let p = Point::new([3.0, 4.0]);
let v = Vector::new([1.0, 0.0]);
assert_eq!(id * p, p);
assert_eq!(id * v, v);
// General 2×2 matrix: row-major construction
let m = Matrix::<_, 2, General>::new([[1.0, 2.0], [3.0, 4.0]]);
let out = m * Vector::new([1.0, 1.0]);
assert_eq!(out.coords_ref(), &[3.0, 7.0]);use apollonius::{Angle, Isometry, Matrix, Point, Vector};
use std::f64::consts::FRAC_PI_2;
// Rotate 90° counterclockwise in the plane
let rot = Matrix::<f64, 2, Isometry>::rotation_2d(Angle::<f64>::from_radians(FRAC_PI_2));
let v = Vector::new([1.0, 0.0]);
let rotated = rot * v;
// (1, 0) → (0, 1)
assert!((rotated.coords_ref()[0] - 0.0).abs() < 1e-10);
assert!((rotated.coords_ref()[1] - 1.0).abs() < 1e-10);use apollonius::{AffineTransform, Angle, Isometry, Line, Matrix, Point, Vector};
let linear = Matrix::<f64, 2, Isometry>::rotation_2d(Angle::<f64>::from_radians(std::f64::consts::FRAC_PI_2));
let translation = Vector::new([10.0, 0.0]);
let tr = AffineTransform::new(linear, translation);
let line = Line::new(Point::new([0.0, 0.0]), Vector::new([1.0, 0.0]));
let transformed = tr * line;
// Origin and direction are transformed; direction is re-normalized
println!("New origin: {:?}", transformed.origin());Only isometric matrices (and affine transforms with isometric linear part) can act on hyperspheres, so the radius is preserved:
use apollonius::{Angle, Hypersphere, Isometry, Matrix, Point};
let rot = Matrix::<f64, 2, Isometry>::rotation_2d(Angle::<f64>::from_radians(1.0));
let circle = Hypersphere::new(Point::new([1.0, 0.0]), 5.0);
let rotated_circle = rot * circle;
assert_eq!(rotated_circle.radius(), 5.0); // unchanged
// Center is rotated: rot * circle.center()Use the traits MatrixTag, IsAffine, or IsIsometry to restrict generic functions. The type system ensures only isometries act on hyperspheres (radius is preserved):
use apollonius::{Hypersphere, IsIsometry, Matrix};
/// Only matrices with tag implementing IsIsometry (e.g. Isometry) are accepted.
fn rotate_sphere<const N: usize, Tag>(rot: Matrix<f64, N, Tag>, sphere: Hypersphere<f64, N>) -> Hypersphere<f64, N>
where
Tag: IsIsometry,
{
rot * sphere
}use apollonius::{Point, Vector, Hypersphere, Hyperplane, IntersectionResult};
let sphere = Hypersphere::new(Point::new([0.0, 0.0, 5.0]), 5.0);
let plane = Hyperplane::new(Point::new([0.0, 0.0, 0.0]), Vector::new([0.0, 0.0, 1.0]));
match sphere.intersect_hyperplane(&plane) {
IntersectionResult::Tangent(p) => println!("Sphere touches plane at {:?}", p),
IntersectionResult::HalfSpacePenetration(depth) => println!("Penetration depth: {}", depth),
IntersectionResult::None => println!("No contact"),
_ => {}
}use apollonius::prelude::*;
let seg = Segment::new(Point::new([0.0, 0.0]), Point::new([2.0, 0.0]));
let aabb = seg.aabb();
assert_eq!(aabb.min_ref(), &[0.0, 0.0]);
assert_eq!(aabb.max_ref(), &[2.0, 0.0]);
let query = Point::new([1.0, 3.0]);
let closest = seg.closest_point(&query);
assert_eq!(closest.coords_ref(), &[1.0, 0.0]); // foot on segment
let dist_sq = seg.distance_to_point_squared(&query);
assert!((dist_sq - 9.0).abs() < 1e-10);- N-dimensional Point & Vector algebra.
- Core primitives (Hypersphere, Line, Segment, Hyperplane, AABB, Triangle).
- AABB broad-phase overlap.
- Point-result intersections: Line/Segment with Line, Segment, Hypersphere, Hyperplane; Hyperplane with Line, Segment, Hypersphere; Hypersphere with Line, Segment, Hyperplane.
- Hypersphere–Hyperplane: tangent contact, half-space penetration,
submerged_ratio. - Documentation and doc tests.
- v0.1.0: Type-tagged matrices (General, Isometry, Affine), AffineTransform, linear_ops (Matrix/AffineTransform × Point, Vector, Line, Segment, Hypersphere, Hyperplane, Triangle). Prelude and crate-root re-exports.
- GJK (Gilbert–Johnson–Keerthi) for narrow-phase.
- Oriented Bounding Boxes (OBB).
- Spatial partitioning (BVH / quadtree).
This project is licensed under the MIT License.
Developed with 🦀 by Mauricio Klainbard