Geometric algorithms for ternary spaces — points, distances (Manhattan, Lee, Hamming), Voronoi diagrams, convex hulls, and area/volume on the {0, 1, 2} grid.
The ternary grid — where each coordinate takes one of three values — is the natural geometry for ternary computing. With only 9 points in 2D and 27 in 3D, you can enumerate and reason about the entire space exhaustively. This crate provides geometric primitives that respect the discrete, cyclic nature of ternary coordinates, including Lee distance (cyclic distance on ℤ/3ℤ) which has no analog in standard Euclidean geometry.
- TernaryPoint — A point in {0, 1, 2}³ with 2D and 3D variants
- Manhattan Distance — Standard L1 distance between ternary points
- Lee Distance — Cyclic distance on ℤ/3ℤ (wraps around: distance 0→2 is 1, not 2)
- Hamming Distance — Count of differing coordinates
- Voronoi Diagrams — Nearest-seed partitioning with Manhattan or Lee distance
- Convex Hull — Gift-wrapping algorithm for 2D ternary point sets
- Polygon Area — Shoelace formula for 2D ternary polygons
# Cargo.toml
[dependencies]
ternary-geometry = "0.1"use ternary_geometry::*;
// Create points
let a = TernaryPoint::new_2d(0, 0);
let b = TernaryPoint::new_2d(2, 2);
let c = TernaryPoint::new(0, 1, 2);
// Distance metrics
println!("Manhattan: {}", manhattan_distance(&a, &b)); // 4
println!("Lee: {}", lee_distance(&a, &b)); // 2 (wraps)
println!("Hamming: {}", hamming_distance(&a, &b)); // 2
// All points in the grid
let all_2d = TernaryPoint::all_2d(); // 9 points
let all_3d = TernaryPoint::all_3d(); // 27 points
println!("2D grid: {} points", all_2d.len());
println!("3D grid: {} points", all_3d.len());
// Voronoi diagrams
let seeds = vec![TernaryPoint::new_2d(0, 0), TernaryPoint::new_2d(2, 2)];
let regions = voronoi_manhattan_2d(&seeds);
for (point, seed_idx) in ®ions {
println!("{:?} → seed {}", point.coords, seed_idx);
}
// Convex hull
let pts = vec![
TernaryPoint::new_2d(0, 0),
TernaryPoint::new_2d(2, 0),
TernaryPoint::new_2d(2, 2),
TernaryPoint::new_2d(0, 2),
TernaryPoint::new_2d(1, 1), // interior
];
let hull = convex_hull_2d(&pts);
println!("Hull indices: {:?}", hull);
// Polygon area (shoelace formula)
let area = polygon_area_2d(&pts[..4].to_vec());
println!("Square area: {}", area); // 4.0
// Bounding box and centroid
let bbox = bounding_box_2d(&pts);
let (cx, cy) = centroid_2d(&pts);
println!("BBox: {:?}", bbox);
println!("Centroid: ({}, {})", cx, cy);
// Line operations
let line = TernaryLine::new(a, b);
println!("Midpoint: {:?}", line.midpoint().coords);
println!("On segment: {}", point_on_segment(&TernaryPoint::new_2d(1, 1), &line));| Type / Function | Description |
|---|---|
TernaryPoint |
Point in {0,1,2}³ with all_2d(), all_3d() |
TernaryLine |
Line segment with midpoint, manhattan_length, lee_length |
manhattan_distance / lee_distance / hamming_distance |
Distance metrics |
voronoi_manhattan_2d/3d / voronoi_lee_3d |
Voronoi partitioning |
convex_hull_2d |
Gift-wrapping hull computation |
polygon_area_2d |
Shoelace formula area |
bounding_box_2d / points_in_bbox |
Bounding box utilities |
centroid_2d |
Mean coordinate |
point_on_segment |
Point-line containment test |
ternary_grid_volume / ternary_grid_area |
Constants (27 and 9) |
Lee Distance treats each coordinate as a cyclic value in ℤ/3ℤ. The distance between 0 and 2 is min(2, 3−2) = 1, reflecting that 2 "wraps around" to be close to 0. This is the natural metric for ternary arithmetic.
Voronoi Diagrams enumerate all grid points and assign each to its nearest seed. With only 9 (2D) or 27 (3D) points, brute-force is efficient and exact. Supports both Manhattan and Lee distance metrics.
Convex Hull uses gift wrapping (Jarvis march), choosing the most counterclockwise point at each step. Ties are broken by distance. Interior points are naturally excluded.
Polygon Area applies the shoelace formula: Area = ½|Σ(xᵢyᵢ₊₁ − xᵢ₊₁yᵢ)|.
- Ternary code analysis — Compute distance distributions between codewords in ternary error-correcting codes using Lee distance
- Game board geometry — Model small discrete game boards where positions are ternary coordinates
- Territory partitioning — Assign ternary grid cells to nearest facilities using Voronoi diagrams
- Pattern recognition — Measure similarity between ternary patterns with appropriate distance metrics
-
Coordinate space is {0, 1, 2}, not {-1, 0, +1}: Unlike most ternary crates in this ecosystem that use the balanced ternary {-1, 0, +1} representation, this crate uses non-negative coordinates {0, 1, 2}. Converting between this crate's
TernaryPointand the balanced ternary used by other crates requires a manual offset (x - 1). -
Grid exhaustively enumerated — only 9 (2D) or 27 (3D) points: All algorithms (Voronoi, convex hull) enumerate the full grid, which means they cannot generalize to larger ternary spaces or different coordinate ranges. The crate is fundamentally limited to exactly 3 values per dimension.
-
convex_hull_2d()uses gift wrapping on at most 9 points: The gift-wrapping algorithm runs on the 9-point 2D grid. For this tiny domain, any hull algorithm is instant, but the implementation doesn't exploit the known structure of the ternary grid (e.g., the hull is always a subset of the 8 boundary points). -
polygon_area_2d()uses shoelace formula with integer coordinates: Since all coordinates are in {0, 1, 2}, polygon areas are always multiples of 0.5. The function returns anf64but the result is always0.0,0.5,1.0,1.5, etc. — the floating-point precision is unnecessary. -
TernaryLine::midpoint()rounds down: The midpoint of(0, 0)and(1, 2)is computed as(0, 1)rather than(0.5, 1.5)because coordinates are integers. This silently loses the true midpoint for most line segments. -
Voronoi ties go to the first seed: When a grid point is equidistant from multiple seeds, it is assigned to the seed with the lowest index. The tie-breaking rule is deterministic but arbitrary — it can produce unintuitive region boundaries.
-
No 3D convex hull or 3D volume computation: The crate provides 2D convex hull and 2D polygon area but no 3D equivalents.
ternary_grid_volume()returns the constant 27 andternary_grid_area()returns 9 — they are not computed from input.
Part of the SuperInstance ternary computing crate family:
ternary-compression-v2— Multi-algorithm ternary compressionternary-hash— Hashing and fingerprinting for ternary dataternary-pca— Principal component analysis on ternary valuesternary-ga— Genetic algorithms with ternary genomesternary-matrix— Compact ternary matrix operationsternary-reservoir— Echo state networks with ternary nodesternary-evolution-advanced— Advanced evolutionary optimizationternary-causality— Causal inference for ternary systemsternary-consensus— Distributed consensus for ternary agents
MIT
- ternary-topology — related
- ternary-graph — related
- ternary-projection — related
- ternary-pca — related
- ternary-tensor — related