use super::{Intersects, has_disjoint_bboxes};
use crate::*;
impl<T> Intersects<Coord<T>> for Triangle<T>
where
T: GeoNum,
{
fn intersects(&self, rhs: &Coord<T>) -> bool {
let mut orientations = self
.to_lines()
.map(|l| T::Ker::orient2d(l.start, l.end, *rhs));
orientations.sort();
!orientations
.windows(2)
.any(|win| win[0] != win[1] && win[1] != Orientation::Collinear)
}
}
symmetric_intersects_impl!(Triangle<T>, LineString<T>);
symmetric_intersects_impl!(Triangle<T>, MultiLineString<T>);
symmetric_intersects_impl!(Triangle<T>, Line<T>);
symmetric_intersects_impl!(Triangle<T>, Point<T>);
symmetric_intersects_impl!(Triangle<T>, MultiPoint<T>);
impl<T> Intersects<Polygon<T>> for Triangle<T>
where
T: GeoNum,
{
fn intersects(&self, rhs: &Polygon<T>) -> bool {
if has_disjoint_bboxes(self, rhs) {
return false;
}
rhs.coords_iter().take(1).any(|p| self.intersects(&p))
|| self.v1().intersects(rhs)
|| rhs.lines_iter().any(|rhs_line| {
self.lines_iter()
.any(|self_line| self_line.intersects(&rhs_line))
})
}
}
symmetric_intersects_impl!(Triangle<T>, MultiPolygon<T>);
symmetric_intersects_impl!(Triangle<T>, Rect<T>);
impl<T> Intersects<Triangle<T>> for Triangle<T>
where
T: GeoNum,
{
fn intersects(&self, rhs: &Triangle<T>) -> bool {
self.to_polygon().intersects(&rhs.to_polygon())
}
}
#[cfg(test)]
mod test_polygon {
use super::*;
#[test]
fn test_disjoint() {
let triangle = Triangle::from([(0., 0.), (10., 0.), (10., 10.)]);
let polygon: Polygon<f64> = Rect::new((11, 11), (12, 12)).to_polygon().convert();
assert!(!triangle.intersects(&polygon));
}
#[test]
fn test_partial() {
let triangle = Triangle::from([(0., 0.), (10., 0.), (10., 10.)]);
let polygon: Polygon<f64> = Rect::new((9, 9), (12, 12)).to_polygon().convert();
assert!(triangle.intersects(&polygon));
}
#[test]
fn test_triangle_inside_polygon() {
let triangle = Triangle::from([(1., 1.), (2., 1.), (2., 2.)]);
let polygon: Polygon<f64> = Rect::new((0, 0), (10, 10)).to_polygon().convert();
assert!(triangle.intersects(&polygon));
}
#[test]
fn test_polygon_inside_triangle() {
let triangle = Triangle::from([(0., 0.), (10., 0.), (10., 10.)]);
let polygon: Polygon<f64> = Rect::new((1, 1), (2, 2)).to_polygon().convert();
assert!(triangle.intersects(&polygon));
}
#[test]
fn test_rect_inside_polygon_hole() {
let bound: Rect<f64> = Rect::new((0, 0), (10, 10)).convert();
let hole = Rect::new((1, 1), (9, 9)).convert();
let triangle = Triangle::from([(4., 4.), (4., 6.), (6., 6.)]);
let polygon = Polygon::new(
bound.exterior_coords_iter().collect(),
vec![hole.exterior_coords_iter().collect()],
);
assert!(!triangle.intersects(&polygon));
}
#[test]
fn test_triangle_equals_polygon_hole() {
let bound: Rect<f64> = Rect::new((0, 0), (10, 10)).convert();
let triangle = Triangle::from([(4., 4.), (4., 6.), (6., 6.)]);
let polygon = Polygon::new(
bound.exterior_coords_iter().collect(),
vec![triangle.exterior_coords_iter().collect()],
);
assert!(triangle.intersects(&polygon));
}
}