hyperlimit provides hyperreal-first exact geometry predicates that report both
the classified result and how the result was decided.
It implements 2D/3D orientation, in-circle, in-sphere, line classification, and
plane classification over hyperreal::Real. The resolver uses Real structural
facts, exact structural term-sign filters, exact arithmetic, and bounded
hyperreal sign refinement. Primitive f32 and f64 are not predicate Real
values; they should only appear at rendering, IO, and interop boundaries.
hyperrealsupplies exact/symbolic Real facts and bounded sign refinement throughhyperreal::Real.hyperlatticeuses the samehyperreal::Realtype for vector and matrix code and shares Real structural facts withhyperlimit.hyperlimitowns predicate policy, escalation order, and result provenance.
hyperlimit does not own Real expression internals or linear algebra types.
hyperlimit is the exact decision layer. It owns reusable geometric predicate
traits, outcomes, policies, escalation stages, and small classifiers whose
semantics are shared by higher crates. It does not own Real representation,
vector/matrix storage, curve booleans, triangulation topology, solver models, or
domain-specific geometry.
Predicate dispatch may use facts carried by lower layers, but decisions must remain exact. Current shortcuts use exact structural zero/sign facts, exact arithmetic, and bounded hyperreal refinement. Future fast paths should accept metadata such as integer-grid scale, dyadic denominator class, symbolic Real class, sparse-zero masks, affine-transform kind, coordinate bounds expressed as exact structural certificates, and source normalization facts. Those facts should select faster determinant expansions or skip known-zero terms before generic expression construction; they must not reintroduce primitive-float predicate filters.
hyperlimit should keep reusable predicates here and leave object ownership
above it: segment/ring storage in hypercurve or hypertri, DCEL state in
hypertri, and active-set policy in hypersolve.
Version 0.2.0 is an early, documented predicate crate with a small public API.
It is not a mesh, polygon, BSP, CSG, or intersection library.
Implemented:
Point2andPoint3withRealcoordinatesRealZeroKnowledge,Point2DisplacementFacts,Segment2Facts,Triangle2Facts,TriangleEdge2, andAabb2Factsfor predicate-facing structural dispatch metadatacompare_reals,compare_point2_lexicographicpoint2_equal,compare_point2_distance_squaredclassify_real_closed_interval,real_in_closed_interval,classify_closed_interval_intersection,closed_intervals_intersectclassify_point_aabb2,point_in_aabb2,classify_aabb2_intersection,aabb2s_intersectorient2d,orient3dincircle2d,insphere3dclassify_point_lineclassify_point_segment,point_on_segment,classify_segment_intersection,PreparedSegment2, and cached-Segment2Factsvariantsclassify_point_triangle,PreparedTriangle2, and cached-Triangle2Factsvariantsring_area_sign,classify_point_ring_even_odd,point_in_ring_even_oddPlane3,classify_point_plane,classify_point_oriented_plane- batch APIs, with optional Rayon parallel variants
PredicateOutcome<T>with certainty and deciding stagePredicatePolicyfor exact/refined predicate behavior- Real structural-fact helpers and bounded sign refinement
[dependencies]
hyperlimit = "0.2.0"From sibling checkouts:
[dependencies]
hyperlimit = { path = "../hyperlimit" }use hyperlimit::{Point2, Sign, orient2d};
use hyperreal::Real;
let a = Point2::new(Real::from(0), Real::from(0));
let b = Point2::new(Real::from(1), Real::from(0));
let c = Point2::new(Real::from(0), Real::from(1));
let outcome = orient2d(&a, &b, &c);
assert_eq!(outcome.value(), Some(Sign::Positive));Line-side classification maps orientation signs into geometry names:
use hyperlimit::{LineSide, Point2, classify_point_line};
use hyperreal::Real;
let from = Point2::new(Real::from(0), Real::from(0));
let to = Point2::new(Real::from(1), Real::from(0));
let point = Point2::new(Real::from(0), Real::from(1));
assert_eq!(
classify_point_line(&from, &to, &point).value(),
Some(LineSide::Left)
);Plane classification works with explicit plane equations:
use hyperlimit::{Plane3, PlaneSide, Point3, classify_point_plane};
use hyperreal::Real;
let plane = Plane3::new(
Point3::new(Real::from(0), Real::from(0), Real::from(1)),
Real::from(-2),
);
let point = Point3::new(Real::from(0), Real::from(0), Real::from(3));
assert_eq!(
classify_point_plane(&point, &plane).value(),
Some(PlaneSide::Above)
);Predicates return PredicateOutcome<T>:
use hyperlimit::{Point2, PredicateOutcome, orient2d};
use hyperreal::Real;
let a = Point2::new(Real::from(0), Real::from(0));
let b = Point2::new(Real::from(1), Real::from(0));
let c = Point2::new(Real::from(0), Real::from(1));
match orient2d(&a, &b, &c) {
PredicateOutcome::Decided { value, certainty, stage } => {
println!("{value:?} from {certainty:?} at {stage:?}");
}
PredicateOutcome::Unknown { needed, stage } => {
println!("unknown at {stage:?}; needs {needed:?}");
}
}Certainty values:
ExactFiltered
Stages:
StructuralFilterExactRefinedUndecided
The shared sign resolver attempts:
- Real structural sign
- determinant term filters from exact structural zero/sign facts
- exact Real or exact predicate hooks
- bounded Real sign refinement
Unknown
Use policy-specific functions when the default strict behavior is not desired:
use hyperlimit::{Point2, PredicatePolicy, orient::orient2d_with_policy};
use hyperreal::Real;
let a = Point2::new(Real::from(0), Real::from(0));
let b = Point2::new(Real::from(1), Real::from(1));
let c = Point2::new(Real::from(2), Real::from(2));
let policy = PredicatePolicy {
allow_refinement: false,
..PredicatePolicy::STRICT
};
let outcome = orient2d_with_policy(&a, &b, &c, policy);
println!("{outcome:?}");Predicate coordinates are hyperreal::Real. The predicate layer reads:
- known sign
- exact zero/nonzero status
- exact rational state
- bounded sign refinement
Higher crates should preserve these facts alongside geometric objects when they can reuse them across many predicates.
| Feature | Purpose |
|---|---|
std |
Default feature. No special public API is attached to it currently. |
parallel |
Enables batch predicate variants under the same Real API. |
dispatch-trace |
Records predicate dispatch provenance during benchmarks. |
real: Real fact mapping and borrowed Real arithmetic helpersgeometry::facts: point-displacement, segment, and AABB extent structural facts for exact fast-path selectionpredicate: outcome, certainty, policy, and sign typesresolve: shared internal sign-resolution pipelinepredicates::aabb: exact stateless 2D axis-aligned box classifierspredicates::distance: exact squared-distance comparison predicatespredicates::interval: exact Real interval containment and intersection classifierspredicates::order: exact Real and point ordering predicatesorient: points and orientation/circle/sphere predicatespredicates::segment: exact point-on-segment and segment-intersection classifierspredicates::ring: exact signed-area/winding sign and even-odd point-ring helpersplane: explicit and oriented plane classificationclassify: line and plane side enumsbatch: sequential and optional parallel batch APIserror: crate-local error/result types
Common public types and functions are re-exported from the crate root.
Bentley, Jon Louis, and Thomas A. Ottmann. "Algorithms for Reporting and Counting Geometric Intersections." IEEE Transactions on Computers, vol. C-28, no. 9, 1979, pp. 643-647.
de Berg, Mark, Otfried Cheong, Marc van Kreveld, and Mark Overmars. Computational Geometry: Algorithms and Applications. 3rd ed., Springer, 2008.
Hormann, Kai, and Alexander Agathos. "The Point in Polygon Problem for Arbitrary Polygons." Computational Geometry, vol. 20, no. 3, 2001, pp. 131-144.
Shewchuk, Jonathan Richard. "Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates." Discrete & Computational Geometry, vol. 18, no. 3, 1997, pp. 305-363.
Yap, Chee K. "Towards Exact Geometric Computation." Computational Geometry, vol. 7, nos. 1-2, 1997, pp. 3-23.
Run checks:
cargo test
cargo test --no-default-features
cargo test --all-featuresRun the broad feature set:
cargo test --features parallelRun benchmarks:
cargo bench --bench predicatesThe generated benchmark summary is in benchmarks.md.
Run dispatch tracing separately:
cargo bench --bench predicates --features dispatch-trace -- --write-dispatch-trace-mdThe generated trace summary is in dispatch_trace.md.
MIT OR Apache-2.0.
