geometry_algorithm/
disjoint.rs1use geometry_coords::CoordinateScalar;
10use geometry_strategy::{CartesianIntersects, IntersectsStrategy};
11use geometry_trait::{Box as BoxTrait, Geometry, Point as PointTrait};
12
13#[inline]
18#[must_use]
19pub fn disjoint<A, B>(a: &A, b: &B) -> bool
20where
21 CartesianIntersects: IntersectsStrategy<A, B>,
22{
23 !CartesianIntersects.intersects(a, b)
24}
25
26#[inline]
54#[must_use]
55pub fn disjoint_box_box<A, B, T>(a: &A, b: &B) -> bool
56where
57 A: BoxTrait,
58 B: BoxTrait,
59 <A as Geometry>::Point: PointTrait<Scalar = T>,
60 <B as Geometry>::Point: PointTrait<Scalar = T>,
61 T: CoordinateScalar,
62{
63 let a_min_x = a.get_indexed::<0, 0>();
65 let a_min_y = a.get_indexed::<0, 1>();
66 let a_max_x = a.get_indexed::<1, 0>();
67 let a_max_y = a.get_indexed::<1, 1>();
68 let b_min_x = b.get_indexed::<0, 0>();
69 let b_min_y = b.get_indexed::<0, 1>();
70 let b_max_x = b.get_indexed::<1, 0>();
71 let b_max_y = b.get_indexed::<1, 1>();
72
73 a_max_x < b_min_x || b_max_x < a_min_x || a_max_y < b_min_y || b_max_y < a_min_y
74}
75
76#[cfg(test)]
77mod tests {
78 use super::disjoint;
79 use crate::intersects::intersects;
80 use geometry_cs::Cartesian;
81 use geometry_model::{Linestring, Point2D, linestring};
82
83 type P = Point2D<f64, Cartesian>;
84 type LS = Linestring<P>;
85
86 #[test]
87 fn disjoint_matches_negated_intersects() {
88 let a: LS = linestring![(0.0, 0.0), (2.0, 0.0)];
89 let b: LS = linestring![(10.0, 10.0), (11.0, 11.0)];
90 assert!(disjoint(&a, &b));
91 assert!(!intersects(&a, &b));
92 }
93
94 #[test]
95 fn disjoint_false_when_intersecting() {
96 let a: LS = linestring![(0.0, 0.0), (2.0, 0.0)];
97 let b: LS = linestring![(1.0, -1.0), (1.0, 1.0)];
98 assert!(!disjoint(&a, &b));
99 assert!(intersects(&a, &b));
100 }
101
102 #[test]
103 fn box_box_fast_path() {
104 use crate::disjoint::disjoint_box_box;
105 use geometry_model::Box;
106
107 let a = Box::from_corners(P::new(0.0, 0.0), P::new(2.0, 2.0));
108 let right = Box::from_corners(P::new(5.0, 0.0), P::new(6.0, 2.0));
110 assert!(disjoint_box_box(&a, &right));
111 let above = Box::from_corners(P::new(0.0, 5.0), P::new(2.0, 6.0));
113 assert!(disjoint_box_box(&a, &above));
114 let over = Box::from_corners(P::new(1.0, 1.0), P::new(3.0, 3.0));
116 assert!(!disjoint_box_box(&a, &over));
117 let touch = Box::from_corners(P::new(2.0, 0.0), P::new(4.0, 2.0));
119 assert!(!disjoint_box_box(&a, &touch));
120 }
121}