geo/algorithm/contains/triangle.rs
1use super::{Contains, impl_contains_from_relate, impl_contains_geometry_for};
2use crate::geometry::*;
3use crate::{GeoFloat, GeoNum, Orientation, kernels::Kernel};
4
5// ┌──────────────────────────────┐
6// │ Implementations for Triangle │
7// └──────────────────────────────┘
8
9impl<T> Contains<Coord<T>> for Triangle<T>
10where
11 T: GeoNum,
12{
13 fn contains(&self, coord: &Coord<T>) -> bool {
14 // leverageing robust predicates
15 self.to_lines()
16 .map(|l| T::Ker::orient2d(l.start, l.end, *coord))
17 .windows(2)
18 .all(|win| win[0] == win[1] && win[0] != Orientation::Collinear)
19
20 // // neglecting robust prdicates, hence faster
21 // let p0x = self.0.x.to_f64().unwrap();
22 // let p0y = self.0.y.to_f64().unwrap();
23 // let p1x = self.1.x.to_f64().unwrap();
24 // let p1y = self.1.y.to_f64().unwrap();
25 // let p2x = self.2.x.to_f64().unwrap();
26 // let p2y = self.2.y.to_f64().unwrap();
27
28 // let px = coord.x.to_f64().unwrap();
29 // let py = coord.y.to_f64().unwrap();
30
31 // let a = 0.5 * (-p1y * p2x + p0y * (-p1x + p2x) + p0x * (p1y - p2y) + p1x * p2y);
32
33 // let sign = a.signum();
34
35 // let s = (p0y * p2x - p0x * p2y + (p2y - p0y) * px + (p0x - p2x) * py) * sign;
36 // let t = (p0x * p1y - p0y * p1x + (p0y - p1y) * px + (p1x - p0x) * py) * sign;
37
38 // s > 0. && t > 0. && (s + t) < 2. * a * sign
39 }
40}
41
42impl<T> Contains<Point<T>> for Triangle<T>
43where
44 T: GeoNum,
45{
46 fn contains(&self, point: &Point<T>) -> bool {
47 self.contains(&point.0)
48 }
49}
50
51impl_contains_from_relate!(Triangle<T>, [Line<T>, LineString<T>, Polygon<T>, MultiPoint<T>, MultiLineString<T>, MultiPolygon<T>, GeometryCollection<T>, Rect<T>, Triangle<T>]);
52impl_contains_geometry_for!(Triangle<T>);