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 include
4//! 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 I : Integer + std::fmt::Debug {
47 if discrete_interval (a, b) {
48 Some (
49 Interval::with_minmax (Ord::max (a.min(), b.min()), Ord::min (a.max(), b.max())))
50 } else {
51 None
52 }
53}
54
55/// Discrete intersection test of 2D axis-aligned bounding boxes.
56///
57/// Shared boundary points will return intersection:
58///
59/// ```
60/// # use math_utils::geometry::integer::*;
61/// # use math_utils::geometry::intersect::integer::*;
62/// let a = Aabb2::from_points ([ 0, 0].into(), [1, 1].into());
63/// let b = Aabb2::from_points ([-1, 0].into(), [0, 1].into());
64/// assert!(discrete_aabb2_aabb2 (&a, &b));
65/// ```
66#[inline]
67pub fn discrete_aabb2_aabb2 <I : Integer> (a : &Aabb2 <I>, b : &Aabb2 <I>) -> bool {
68 let (min_a, max_a) = (a.min(), a.max());
69 let (min_b, max_b) = (b.min(), b.max());
70 // intersection if overlap exists on both axes
71 max_a.0.x >= min_b.0.x && min_a.0.x <= max_b.0.x &&
72 max_a.0.y >= min_b.0.y && min_a.0.y <= max_b.0.y
73}
74
75/// Continuous intersection test of 2D axis-aligned bounding boxes.
76///
77/// Shared boundary points will return intersection:
78///
79/// ```
80/// # use math_utils::geometry::integer::*;
81/// # use math_utils::geometry::intersect::integer::*;
82/// let a = Aabb2::from_points ([ 0, 0].into(), [1, 1].into());
83/// let b = Aabb2::from_points ([-1, 0].into(), [0, 1].into());
84/// assert_eq!(
85/// continuous_aabb2_aabb2 (&a, &b).unwrap(),
86/// Aabb2::from_points ([0,0].into(), [0, 1].into()));
87/// ```
88#[inline]
89pub fn continuous_aabb2_aabb2 <I> (a : &Aabb2 <I>, b : &Aabb2 <I>)
90 -> Option <Aabb2 <I>>
91where I : Integer + std::fmt::Debug {
92 if discrete_aabb2_aabb2 (a, b) {
93 Some (
94 Aabb2::with_minmax (point2_max (a.min(), b.min()), point2_min (a.max(), b.max())))
95 } else {
96 None
97 }
98}
99
100/// Discrete intersection test of 3D axis-aligned bounding boxes.
101///
102/// Shared boundary points will return intersection:
103///
104/// ```
105/// # use math_utils::geometry::integer::*;
106/// # use math_utils::geometry::intersect::integer::*;
107/// let a = Aabb3::from_points ([ 0, 0, 0].into(), [1, 1, 1].into());
108/// let b = Aabb3::from_points ([-1, 0, 0].into(), [0, 1, 1].into());
109/// assert!(discrete_aabb3_aabb3 (&a, &b));
110/// ```
111#[inline]
112pub fn discrete_aabb3_aabb3 <I : Integer> (a : &Aabb3 <I>, b : &Aabb3 <I>)
113 -> bool
114{
115 let (min_a, max_a) = (a.min(), a.max());
116 let (min_b, max_b) = (b.min(), b.max());
117 // intersection if overlap exists on all three axes
118 max_a.0.x >= min_b.0.x && min_a.0.x <= max_b.0.x &&
119 max_a.0.y >= min_b.0.y && min_a.0.y <= max_b.0.y &&
120 max_a.0.z >= min_b.0.z && min_a.0.z <= max_b.0.z
121}
122
123/// Continuous intersection test of 3D axis-aligned bounding boxes.
124///
125/// Shared boundary points will return intersection:
126///
127/// ```
128/// # use math_utils::geometry::integer::*;
129/// # use math_utils::geometry::intersect::integer::*;
130/// let a = Aabb3::from_points ([ 0, 0, 0].into(), [1, 1, 1].into());
131/// let b = Aabb3::from_points ([-1, 0, 0].into(), [0, 1, 1].into());
132/// assert_eq!(
133/// continuous_aabb3_aabb3 (&a, &b).unwrap(),
134/// Aabb3::from_points ([0, 0, 0].into(), [0, 1, 1].into()));
135/// ```
136#[inline]
137pub fn continuous_aabb3_aabb3 <I> (a : &Aabb3 <I>, b : &Aabb3 <I>)
138 -> Option <Aabb3 <I>>
139where I : Integer + std::fmt::Debug {
140 if discrete_aabb3_aabb3 (a, b) {
141 Some (
142 Aabb3::with_minmax (point3_max (a.min(), b.min()), point3_min (a.max(), b.max())))
143 } else {
144 None
145 }
146}