Files
OneCAD-Simulation/crates/mesh/src/predicates/ring.rs
T
4667655e08 mesh: exact predicates (Shewchuk adaptive, symbolic perturbation, indirect LPI/TPI) (#8)
* mesh: exact predicates (Shewchuk adaptive orient/incircle/insphere), symbolic perturbation, indirect LPI/TPI predicates

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* mesh: predicate benchmark (filter hit rate, CAD-degenerate inputs); record the predicate decision

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* mesh: simplify predicates (destructuring over fallbacks, shared-minor exact insphere, cheaper expansion product)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

---------

Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:04:56 -04:00

47 lines
1.7 KiB
Rust

//! Predicate formulas written once over exact or certified number types.
//!
//! A [`Ring`] is a number type with `+`, `-`, `*`; a [`Signed`] one can report a sign it is sure
//! of. The formulas below are instantiated with [`super::expansion::Expansion`] (the exact stage
//! of the explicit predicates), [`super::interval::Interval`] (the dynamic filter of the indirect
//! predicates) and [`super::dyadic::Dyadic`] (their exact stage). Writing each polynomial once
//! and letting the compiler monomorphize it plays the role of the code generators of Lévy's PCK
//! (2016) and Attene (2020, §6): one source formula, several arithmetic models.
use std::ops::{Add, Mul, Sub};
use super::Sign;
pub(crate) trait Ring: Clone + Add<Output = Self> + Sub<Output = Self> + Mul<Output = Self> {
/// The exact value of a double.
fn from_f64(x: f64) -> Self;
}
pub(crate) trait Signed {
/// The sign, when the representation is sure of it (always, for exact types).
fn sign(&self) -> Option<Sign>;
}
/// `a * d - b * c`.
#[inline]
pub(crate) fn det2<T: Ring>(a: &T, b: &T, c: &T, d: &T) -> T {
a.clone() * d.clone() - b.clone() * c.clone()
}
/// The determinant of the three rows, expanded along the last column.
#[inline]
pub(crate) fn det3<T: Ring>(rows: &[[T; 3]; 3]) -> T {
let [[a0, a1, a2], [b0, b1, b2], [c0, c1, c2]] = rows;
a2.clone() * det2(b0, b1, c0, c1) - b2.clone() * det2(a0, a1, c0, c1) + c2.clone() * det2(a0, a1, b0, b1)
}
/// `x² + y²` and `x² + y² + z²`.
#[inline]
pub(crate) fn sq2<T: Ring>(x: &T, y: &T) -> T {
x.clone() * x.clone() + y.clone() * y.clone()
}
#[inline]
pub(crate) fn sq3<T: Ring>(x: &T, y: &T, z: &T) -> T {
sq2(x, y) + z.clone() * z.clone()
}