geo/algorithm/intersects/
rect.rs

1use super::{value_in_range, Intersects};
2use crate::*;
3
4impl<T> Intersects<Coord<T>> for Rect<T>
5where
6    T: CoordNum,
7{
8    fn intersects(&self, rhs: &Coord<T>) -> bool {
9        // Funnily, we don't use point_in_rect, as we know
10        // self.min <= self.max.
11        let bound_1 = self.min();
12        let bound_2 = self.max();
13        value_in_range(rhs.x, bound_1.x, bound_2.x) && value_in_range(rhs.y, bound_1.y, bound_2.y)
14    }
15}
16symmetric_intersects_impl!(Coord<T>, Rect<T>);
17symmetric_intersects_impl!(Rect<T>, Point<T>);
18symmetric_intersects_impl!(Rect<T>, MultiPoint<T>);
19
20impl<T> Intersects<Rect<T>> for Rect<T>
21where
22    T: CoordNum,
23{
24    fn intersects(&self, other: &Rect<T>) -> bool {
25        if self.max().x < other.min().x {
26            return false;
27        }
28
29        if self.max().y < other.min().y {
30            return false;
31        }
32
33        if self.min().x > other.max().x {
34            return false;
35        }
36
37        if self.min().y > other.max().y {
38            return false;
39        }
40
41        true
42    }
43}
44
45// Same logic as Polygon<T>: Intersects<Line<T>>, but avoid
46// an allocation.
47impl<T> Intersects<Line<T>> for Rect<T>
48where
49    T: GeoNum,
50{
51    fn intersects(&self, rhs: &Line<T>) -> bool {
52        let lt = self.min();
53        let rb = self.max();
54        let lb = Coord::from((lt.x, rb.y));
55        let rt = Coord::from((rb.x, lt.y));
56        // If either rhs.{start,end} lies inside Rect, then true
57        self.intersects(&rhs.start)
58            || self.intersects(&rhs.end)
59            || Line::new(lt, rt).intersects(rhs)
60            || Line::new(rt, rb).intersects(rhs)
61            || Line::new(lb, rb).intersects(rhs)
62            || Line::new(lt, lb).intersects(rhs)
63    }
64}
65symmetric_intersects_impl!(Line<T>, Rect<T>);