nsys-math-utils 0.1.0

Math types and traits
Documentation
//! Intersection of Aabbs over Integers.
//!
//! Note that unlike Aabbs over Scalars, Aabbs over Integers are *closed* (they
//! include their boundaries).

use crate::*;
use crate::geometry::primitive::integer::*;

/// Discrete intersection test of 1D axis-aligned bounding boxes (intervals).
///
/// Shared boundary points will return intersection:
///
/// ```
/// # use math_utils::geometry::integer::*;
/// # use math_utils::geometry::intersect::integer::*;
/// let a = Interval::from_points ( 0, 1);
/// let b = Interval::from_points (-1, 0);
/// assert!(discrete_interval (&a, &b));
/// ```
#[inline]
pub fn discrete_interval <I : Integer> (a : &Interval <I>, b : &Interval <I>)
  -> bool
{
  let (min_a, max_a) = (a.min(), a.max());
  let (min_b, max_b) = (b.min(), b.max());
  // intersection if intervals overlap
  max_a >= min_b && min_a <= max_b
}

/// Continuous intersection test of 1D axis-aligned bounding boxes (intervals).
///
/// Shared boundary points will return intersection:
///
/// ```
/// # use math_utils::geometry::integer::*;
/// # use math_utils::geometry::intersect::integer::*;
/// let a = Interval::from_points ( 0, 1);
/// let b = Interval::from_points (-1, 0);
/// assert_eq!(
///   continuous_interval (&a, &b).unwrap(),
///   Interval::from_points (0, 0));
/// ```
#[inline]
pub fn continuous_interval <I> (a : &Interval <I>, b : &Interval <I>)
  -> Option <Interval <I>>
where
  I : Integer + std::fmt::Debug
{
  if discrete_interval (a, b) {
    Some (Interval::with_minmax (
      Ord::max (a.min(), b.min()),
      Ord::min (a.max(), b.max())
    ))
  } else {
    None
  }
}

/// Discrete intersection test of 2D axis-aligned bounding boxes.
///
/// Shared boundary points will return intersection:
///
/// ```
/// # use math_utils::geometry::integer::*;
/// # use math_utils::geometry::intersect::integer::*;
/// let a = Aabb2::from_points ([ 0, 0].into(), [1, 1].into());
/// let b = Aabb2::from_points ([-1, 0].into(), [0, 1].into());
/// assert!(discrete_aabb2_aabb2 (&a, &b));
/// ```
#[inline]
pub fn discrete_aabb2_aabb2 <I : Integer> (a : &Aabb2 <I>, b : &Aabb2 <I>)
  -> bool
{
  let (min_a, max_a) = (a.min(), a.max());
  let (min_b, max_b) = (b.min(), b.max());
  // intersection if overlap exists on both axes
  max_a.0.x >= min_b.0.x && min_a.0.x <= max_b.0.x &&
  max_a.0.y >= min_b.0.y && min_a.0.y <= max_b.0.y
}

/// Continuous intersection test of 2D axis-aligned bounding boxes.
///
/// Shared boundary points will return intersection:
///
/// ```
/// # use math_utils::geometry::integer::*;
/// # use math_utils::geometry::intersect::integer::*;
/// let a = Aabb2::from_points ([ 0, 0].into(), [1, 1].into());
/// let b = Aabb2::from_points ([-1, 0].into(), [0, 1].into());
/// assert_eq!(
///   continuous_aabb2_aabb2 (&a, &b).unwrap(),
///   Aabb2::from_points ([0,0].into(), [0, 1].into()));
/// ```
#[inline]
pub fn continuous_aabb2_aabb2 <I> (a : &Aabb2 <I>, b : &Aabb2 <I>)
  -> Option <Aabb2 <I>>
where
  I : Integer + std::fmt::Debug
{
  if discrete_aabb2_aabb2 (a, b) {
    Some (Aabb2::with_minmax (
      point2_max (a.min(), b.min()),
      point2_min (a.max(), b.max())
    ))
  } else {
    None
  }
}

/// Discrete intersection test of 3D axis-aligned bounding boxes.
///
/// Shared boundary points will return intersection:
///
/// ```
/// # use math_utils::geometry::integer::*;
/// # use math_utils::geometry::intersect::integer::*;
/// let a = Aabb3::from_points ([ 0, 0,  0].into(), [1, 1, 1].into());
/// let b = Aabb3::from_points ([-1, 0,  0].into(), [0, 1, 1].into());
/// assert!(discrete_aabb3_aabb3 (&a, &b));
/// ```
#[inline]
pub fn discrete_aabb3_aabb3 <I : Integer> (a : &Aabb3 <I>, b : &Aabb3 <I>)
  -> bool
{
  let (min_a, max_a) = (a.min(), a.max());
  let (min_b, max_b) = (b.min(), b.max());
  // intersection if overlap exists on all three axes
  max_a.0.x >= min_b.0.x && min_a.0.x <= max_b.0.x &&
  max_a.0.y >= min_b.0.y && min_a.0.y <= max_b.0.y &&
  max_a.0.z >= min_b.0.z && min_a.0.z <= max_b.0.z
}

/// Continuous intersection test of 3D axis-aligned bounding boxes.
///
/// Shared boundary points will return intersection:
///
/// ```
/// # use math_utils::geometry::integer::*;
/// # use math_utils::geometry::intersect::integer::*;
/// let a = Aabb3::from_points ([ 0, 0,  0].into(), [1, 1, 1].into());
/// let b = Aabb3::from_points ([-1, 0,  0].into(), [0, 1, 1].into());
/// assert_eq!(
///   continuous_aabb3_aabb3 (&a, &b).unwrap(),
///   Aabb3::from_points ([0, 0, 0].into(), [0, 1, 1].into()));
/// ```
#[inline]
pub fn continuous_aabb3_aabb3 <I> (a : &Aabb3 <I>, b : &Aabb3 <I>)
  -> Option <Aabb3 <I>>
where
  I : Integer + std::fmt::Debug
{
  if discrete_aabb3_aabb3 (a, b) {
    Some (Aabb3::with_minmax (
      point3_max (a.min(), b.min()),
      point3_min (a.max(), b.max())
    ))
  } else {
    None
  }
}