Skip to main content

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}