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