diff --git a/Cargo.toml b/Cargo.toml index ad08ba7..d21c913 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,11 +23,14 @@ arbitrary = { version = "1.0.0", optional = true } proptest = { version = "1.0.0", optional = true } speedy = { version = "0.8.3", optional = true, default-features = false } bytemuck = { version = "1.12.2", optional = true, default-features = false } +geo = { version = "0.24", optional = true } +robust = { version = "0.2", optional = true } [dev-dependencies] serde_test = "1.0" [features] -default = ["std"] -std = ["num-traits/std"] -randtest = ["rand/std", "rand/std_rng"] +default = ["std"] +geo-interop = ["geo", "robust"] +std = ["num-traits/std"] +randtest = ["rand/std", "rand/std_rng"] diff --git a/src/lib.rs b/src/lib.rs index b34de94..ce3077e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -974,7 +974,7 @@ impl Ord for NotNan { } } -#[allow(clippy::derive_hash_xor_eq)] +#[allow(clippy::derived_hash_with_manual_eq)] impl Hash for NotNan { #[inline] fn hash(&self, state: &mut H) { @@ -2249,3 +2249,57 @@ mod impl_bytemuck { assert!(try_cast::>(pi).is_ok()); } } + +#[cfg(feature = "geo")] +mod impl_geo { + use super::{Float, NotNan, OrderedFloat}; + use geo::kernels::{HasKernel, Kernel, RobustKernel}; + use geo::CoordNum; + use num_traits::NumCast; + use robust::{orient2d, Coord}; + + impl HasKernel for OrderedFloat { + type Ker = RobustKernel; + } + + impl HasKernel for NotNan { + type Ker = NotNanRobustKernel; + } + + #[derive(Default, Debug)] + pub struct NotNanRobustKernel; + + impl Kernel> for NotNanRobustKernel + where + T: Float + NumCast + CoordNum, + { + fn orient2d( + p: geo::Coord>, + q: geo::Coord>, + r: geo::Coord>, + ) -> geo::Orientation { + let orientation = orient2d( + Coord { + x: ::from(p.x).unwrap(), + y: ::from(p.y).unwrap(), + }, + Coord { + x: ::from(q.x).unwrap(), + y: ::from(q.y).unwrap(), + }, + Coord { + x: ::from(r.x).unwrap(), + y: ::from(r.y).unwrap(), + }, + ); + + if orientation > 0.0 { + geo::Orientation::CounterClockwise + } else if orientation < 0.0 { + geo::Orientation::Clockwise + } else { + geo::Orientation::Collinear + } + } + } +}