| Crates.io | apfp |
| lib.rs | apfp |
| version | 0.1.1 |
| created_at | 2026-01-02 15:53:52.758199+00 |
| updated_at | 2026-01-04 02:49:42.434304+00 |
| description | Adaptive precision floating-point arithmetic for robust geometric predicates |
| homepage | |
| repository | https://github.com/lemmih/apfp |
| max_upload_size | |
| id | 2018821 |
| size | 263,641 |
Robust geometric predicates using adaptive precision arithmetic. The library provides exact sign computation for arithmetic expressions, automatically escalating precision only when needed.
orient2d, incircle, cmp_dist that handle near-degenerate cases correctlyapfp_signum! macro computes exact signs for arbitrary arithmetic expressions[dependencies]
apfp = "0.1"
use apfp::geometry::f64::{Coord, orient2d, cmp_dist, Orientation};
use std::cmp::Ordering;
let a = Coord::new(0.0, 0.0);
let b = Coord::new(1.0, 0.0);
let c = Coord::new(0.5, 1e-16);
// Orientation test: is c left of, right of, or on line ab?
match orient2d(&a, &b, &c) {
Orientation::CounterClockwise => println!("Counter-clockwise"),
Orientation::Clockwise => println!("Clockwise"),
Orientation::CoLinear => println!("Collinear"),
}
// Distance comparison: is p closer to origin than q?
let origin = Coord::new(0.0, 0.0);
let p = Coord::new(1.0, 0.0);
let q = Coord::new(0.0, 1.0);
match cmp_dist(&origin, &p, &q) {
Ordering::Less => println!("p is closer"),
Ordering::Greater => println!("q is closer"),
Ordering::Equal => println!("equidistant"),
}
Use apfp_signum! to compute the exact sign of any arithmetic expression:
use apfp::{apfp_signum, square};
// Compute sign of a determinant
let a = 1.0_f64;
let b = 2.0_f64;
let c = 3.0_f64;
let d = 4.0_f64;
let sign = apfp_signum!(a * d - b * c);
assert_eq!(sign, -1); // 1*4 - 2*3 = -2 < 0
// Use square() for squared terms (more efficient than x * x)
let x = 3.0_f64;
let y = 4.0_f64;
let z = 5.0_f64;
let sign = apfp_signum!(square(x) + square(y) - square(z));
assert_eq!(sign, 0); // 9 + 16 - 25 = 0
The macro supports +, -, *, and square() operations on f64 values.
The library implements Shewchuk's adaptive precision arithmetic:
Most calls complete in the fast path. The adaptive approach provides both correctness and performance.
On random inputs, orient2d performs within 1.1x of the geometry-predicates crate (which uses the same underlying algorithm). The macro-based approach allows the compiler to inline and optimize the entire computation.
This project is released under The Unlicense.