math_utils/geometry/intersect/integer.rs
1//! Intersection of Aabbs over Integers.
2//!
3//! Note that unlike Aabbs over Scalars, Aabbs over Integers are *closed* (they
4//! include their boundaries).
5
6use crate::*;
7use crate::geometry::primitive::integer::*;
8
9/// Discrete intersection test of 1D axis-aligned bounding boxes (intervals).
10///
11/// Shared boundary points will return intersection:
12///
13/// ```
14/// # use math_utils::geometry::integer::*;
15/// # use math_utils::geometry::intersect::integer::*;
16/// let a = Interval::from_points ( 0, 1);
17/// let b = Interval::from_points (-1, 0);
18/// assert!(discrete_interval (&a, &b));
19/// ```
20#[inline]
21pub fn discrete_interval <I : Integer> (a : &Interval <I>, b : &Interval <I>)
22 -> bool
23{
24 let (min_a, max_a) = (a.min(), a.max());
25 let (min_b, max_b) = (b.min(), b.max());
26 // intersection if intervals overlap
27 max_a >= min_b && min_a <= max_b
28}
29
30/// Continuous intersection test of 1D axis-aligned bounding boxes (intervals).
31///
32/// Shared boundary points will return intersection:
33///
34/// ```
35/// # use math_utils::geometry::integer::*;
36/// # use math_utils::geometry::intersect::integer::*;
37/// let a = Interval::from_points ( 0, 1);
38/// let b = Interval::from_points (-1, 0);
39/// assert_eq!(
40/// continuous_interval (&a, &b).unwrap(),
41/// Interval::from_points (0, 0));
42/// ```
43#[inline]
44pub fn continuous_interval <I> (a : &Interval <I>, b : &Interval <I>)
45 -> Option <Interval <I>>
46where
47 I : Integer + std::fmt::Debug
48{
49 if discrete_interval (a, b) {
50 Some (Interval::with_minmax (
51 Ord::max (a.min(), b.min()),
52 Ord::min (a.max(), b.max())
53 ))
54 } else {
55 None
56 }
57}
58
59/// Discrete intersection test of 2D axis-aligned bounding boxes.
60///
61/// Shared boundary points will return intersection:
62///
63/// ```
64/// # use math_utils::geometry::integer::*;
65/// # use math_utils::geometry::intersect::integer::*;
66/// let a = Aabb2::from_points ([ 0, 0].into(), [1, 1].into());
67/// let b = Aabb2::from_points ([-1, 0].into(), [0, 1].into());
68/// assert!(discrete_aabb2_aabb2 (&a, &b));
69/// ```
70#[inline]
71pub fn discrete_aabb2_aabb2 <I : Integer> (a : &Aabb2 <I>, b : &Aabb2 <I>)
72 -> bool
73{
74 let (min_a, max_a) = (a.min(), a.max());
75 let (min_b, max_b) = (b.min(), b.max());
76 // intersection if overlap exists on both axes
77 max_a.0.x >= min_b.0.x && min_a.0.x <= max_b.0.x &&
78 max_a.0.y >= min_b.0.y && min_a.0.y <= max_b.0.y
79}
80
81/// Continuous intersection test of 2D axis-aligned bounding boxes.
82///
83/// Shared boundary points will return intersection:
84///
85/// ```
86/// # use math_utils::geometry::integer::*;
87/// # use math_utils::geometry::intersect::integer::*;
88/// let a = Aabb2::from_points ([ 0, 0].into(), [1, 1].into());
89/// let b = Aabb2::from_points ([-1, 0].into(), [0, 1].into());
90/// assert_eq!(
91/// continuous_aabb2_aabb2 (&a, &b).unwrap(),
92/// Aabb2::from_points ([0,0].into(), [0, 1].into()));
93/// ```
94#[inline]
95pub fn continuous_aabb2_aabb2 <I> (a : &Aabb2 <I>, b : &Aabb2 <I>)
96 -> Option <Aabb2 <I>>
97where
98 I : Integer + std::fmt::Debug
99{
100 if discrete_aabb2_aabb2 (a, b) {
101 Some (Aabb2::with_minmax (
102 point2_max (a.min(), b.min()),
103 point2_min (a.max(), b.max())
104 ))
105 } else {
106 None
107 }
108}
109
110/// Discrete intersection test of 3D axis-aligned bounding boxes.
111///
112/// Shared boundary points will return intersection:
113///
114/// ```
115/// # use math_utils::geometry::integer::*;
116/// # use math_utils::geometry::intersect::integer::*;
117/// let a = Aabb3::from_points ([ 0, 0, 0].into(), [1, 1, 1].into());
118/// let b = Aabb3::from_points ([-1, 0, 0].into(), [0, 1, 1].into());
119/// assert!(discrete_aabb3_aabb3 (&a, &b));
120/// ```
121#[inline]
122pub fn discrete_aabb3_aabb3 <I : Integer> (a : &Aabb3 <I>, b : &Aabb3 <I>)
123 -> bool
124{
125 let (min_a, max_a) = (a.min(), a.max());
126 let (min_b, max_b) = (b.min(), b.max());
127 // intersection if overlap exists on all three axes
128 max_a.0.x >= min_b.0.x && min_a.0.x <= max_b.0.x &&
129 max_a.0.y >= min_b.0.y && min_a.0.y <= max_b.0.y &&
130 max_a.0.z >= min_b.0.z && min_a.0.z <= max_b.0.z
131}
132
133/// Continuous intersection test of 3D axis-aligned bounding boxes.
134///
135/// Shared boundary points will return intersection:
136///
137/// ```
138/// # use math_utils::geometry::integer::*;
139/// # use math_utils::geometry::intersect::integer::*;
140/// let a = Aabb3::from_points ([ 0, 0, 0].into(), [1, 1, 1].into());
141/// let b = Aabb3::from_points ([-1, 0, 0].into(), [0, 1, 1].into());
142/// assert_eq!(
143/// continuous_aabb3_aabb3 (&a, &b).unwrap(),
144/// Aabb3::from_points ([0, 0, 0].into(), [0, 1, 1].into()));
145/// ```
146#[inline]
147pub fn continuous_aabb3_aabb3 <I> (a : &Aabb3 <I>, b : &Aabb3 <I>)
148 -> Option <Aabb3 <I>>
149where
150 I : Integer + std::fmt::Debug
151{
152 if discrete_aabb3_aabb3 (a, b) {
153 Some (Aabb3::with_minmax (
154 point3_max (a.min(), b.min()),
155 point3_min (a.max(), b.max())
156 ))
157 } else {
158 None
159 }
160}
161