geo/algorithm/kernels/
robust.rs

1use super::{CoordNum, Kernel, Orientation};
2use crate::Coord;
3
4use num_traits::{Float, NumCast};
5
6/// Robust kernel that uses [fast robust
7/// predicates](//www.cs.cmu.edu/~quake/robust.html) to
8/// provide robust floating point predicates. Should only be
9/// used with types that can _always_ be casted to `f64`
10/// _without loss in precision_.
11#[derive(Default, Debug)]
12pub struct RobustKernel;
13
14impl<T> Kernel<T> for RobustKernel
15where
16    T: CoordNum + Float,
17{
18    fn orient2d(p: Coord<T>, q: Coord<T>, r: Coord<T>) -> Orientation {
19        use robust::{orient2d, Coord};
20
21        let orientation = orient2d(
22            Coord {
23                x: <f64 as NumCast>::from(p.x).unwrap(),
24                y: <f64 as NumCast>::from(p.y).unwrap(),
25            },
26            Coord {
27                x: <f64 as NumCast>::from(q.x).unwrap(),
28                y: <f64 as NumCast>::from(q.y).unwrap(),
29            },
30            Coord {
31                x: <f64 as NumCast>::from(r.x).unwrap(),
32                y: <f64 as NumCast>::from(r.y).unwrap(),
33            },
34        );
35
36        if orientation < 0. {
37            Orientation::Clockwise
38        } else if orientation > 0. {
39            Orientation::CounterClockwise
40        } else {
41            Orientation::Collinear
42        }
43    }
44}