#[cfg(feature = "derive_serdes")]
use serde::{Deserialize, Serialize};
use crate::*;
use crate::geometry::intersect;
#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Interval <I> {
min : I,
max : I
}
#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Aabb2 <I> {
min : Point2 <I>,
max : Point2 <I>
}
#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Aabb3 <I> {
min : Point3 <I>,
max : Point3 <I>
}
pub fn point2_min <I : Integer> (a : &Point2 <I>, b : &Point2 <I>) -> Point2 <I> {
[ Ord::min (a.0.x, b.0.x),
Ord::min (a.0.y, b.0.y)
].into()
}
pub fn point2_max <I : Integer> (a : &Point2 <I>, b : &Point2 <I>) -> Point2 <I> {
[ Ord::max (a.0.x, b.0.x),
Ord::max (a.0.y, b.0.y)
].into()
}
pub fn point2_min_value <I : Integer> () -> Point2 <I> {
[ I::min_value(), I::min_value() ].into()
}
pub fn point2_max_value <I : Integer> () -> Point2 <I> {
[ I::max_value(), I::max_value() ].into()
}
pub fn point3_min <I : Integer> (a : &Point3 <I>, b : &Point3 <I>) -> Point3 <I> {
[ Ord::min (a.0.x, b.0.x),
Ord::min (a.0.y, b.0.y),
Ord::min (a.0.z, b.0.z)
].into()
}
pub fn point3_max <I : Integer> (a : &Point3 <I>, b : &Point3 <I>) -> Point3 <I> {
[ Ord::max (a.0.x, b.0.x),
Ord::max (a.0.y, b.0.y),
Ord::max (a.0.z, b.0.z)
].into()
}
pub fn point3_min_value <I : Integer> () -> Point3 <I> {
[ I::min_value(), I::min_value(), I::min_value() ].into()
}
pub fn point3_max_value <I : Integer> () -> Point3 <I> {
[ I::max_value(), I::max_value(), I::max_value() ].into()
}
impl <I : Integer> Interval <I> {
#[inline]
pub fn with_minmax (min : I, max : I) -> Self where I : std::fmt::Debug {
debug_assert_eq!(min, Ord::min (min, max));
debug_assert_eq!(max, Ord::max (min, max));
Interval { min, max }
}
#[inline]
pub fn from_points (a : I, b : I) -> Self {
let min = Ord::min (a, b);
let max = Ord::max (a, b);
Interval { min, max }
}
#[inline]
pub fn containing (points : &[I]) -> Self where I : std::fmt::Debug {
debug_assert!(!points.is_empty());
let mut min = I::max_value();
let mut max = I::min_value();
for point in points {
if *point < min {
min = *point;
}
if *point > max {
max = *point;
}
}
Interval::with_minmax (min, max)
}
#[inline]
pub fn union (a : &Interval <I>, b : &Interval <I>) -> Self where I : std::fmt::Debug {
Interval::with_minmax (
Ord::min (a.min(), b.min()),
Ord::max (a.max(), b.max())
)
}
#[inline]
pub const fn min (&self) -> I {
self.min
}
#[inline]
pub const fn max (&self) -> I {
self.max
}
#[inline]
pub fn width (&self) -> I {
self.max - self.min
}
#[inline]
pub fn contains (&self, point : I) -> bool {
self.min <= point && point <= self.max
}
pub fn clamp (&self, point : I) -> I {
Ord::max (Ord::min (self.max, point), self.min)
}
#[inline]
pub fn rand_point <R> (&self, rng : &mut R) -> I where
I : rand::distr::uniform::SampleUniform,
R : rand::Rng
{
rng.random_range (self.min..self.max + I::one())
}
#[inline]
pub fn intersects (&self, other : &Interval <I>) -> bool {
intersect::integer::discrete_interval (self, other)
}
}
impl <I : Integer> Aabb2 <I> {
#[inline]
pub fn with_minmax (min : Point2 <I>, max : Point2 <I>) -> Self where
I : std::fmt::Debug
{
debug_assert_eq!(min, point2_min (&min, &max));
debug_assert_eq!(max, point2_max (&min, &max));
Aabb2 { min, max }
}
#[inline]
pub fn from_points (a : Point2 <I>, b : Point2 <I>) -> Self {
let min = point2_min (&a, &b);
let max = point2_max (&a, &b);
Aabb2 { min, max }
}
#[inline]
pub fn containing (points : &[Point2 <I>]) -> Self where I : std::fmt::Debug {
debug_assert!(!points.is_empty());
let mut min = point2_max_value();
let mut max = point2_min_value();
for point in points {
min = point2_min (&min, point);
max = point2_max (&max, point);
}
Aabb2::with_minmax (min, max)
}
#[inline]
pub fn union (a : &Aabb2 <I>, b : &Aabb2 <I>) -> Self where I : std::fmt::Debug {
Aabb2::with_minmax (point2_min (a.min(), b.min()), point2_max (a.max(), b.max()))
}
#[inline]
pub const fn min (&self) -> &Point2 <I> {
&self.min
}
#[inline]
pub const fn max (&self) -> &Point2 <I> {
&self.max
}
#[inline]
pub fn width (&self) -> I {
self.max.0.x - self.min.0.x
}
#[inline]
pub fn height (&self) -> I {
self.max.0.y - self.min.0.y
}
#[inline]
pub fn contains (&self, point : &Point2 <I>) -> bool {
self.min.0.x <= point.0.x && point.0.x <= self.max.0.x &&
self.min.0.y <= point.0.y && point.0.y <= self.max.0.y
}
pub fn clamp (&self, point : &Point2 <I>) -> Point2 <I> {
[ Ord::max (Ord::min (self.max.0.x, point.0.x), self.min.0.x),
Ord::max (Ord::min (self.max.0.y, point.0.y), self.min.0.y),
].into()
}
#[inline]
pub fn rand_point <R> (&self, rng : &mut R) -> Point2 <I> where
I : rand::distr::uniform::SampleUniform,
R : rand::Rng
{
[ rng.random_range (self.min.0.x..self.max.0.x+I::one()),
rng.random_range (self.min.0.y..self.max.0.y+I::one())
].into()
}
#[inline]
pub fn intersects (&self, other : &Aabb2 <I>) -> bool {
intersect::integer::discrete_aabb2_aabb2 (self, other)
}
}
impl <I : Integer> Aabb3 <I> {
#[inline]
pub fn with_minmax (min : Point3 <I>, max : Point3 <I>) -> Self where
I : std::fmt::Debug
{
debug_assert_eq!(min, point3_min (&min, &max));
debug_assert_eq!(max, point3_max (&min, &max));
Aabb3 { min, max }
}
#[inline]
pub fn from_points (a : Point3 <I>, b : Point3 <I>) -> Self {
let min = point3_min (&a, &b);
let max = point3_max (&a, &b);
Aabb3 { min, max }
}
#[inline]
pub fn containing (points : &[Point3 <I>]) -> Self where I : std::fmt::Debug {
debug_assert!(!points.is_empty());
let mut min = point3_max_value();
let mut max = point3_min_value();
for point in points {
min = point3_min (&min, point);
max = point3_max (&max, point);
}
Aabb3::with_minmax (min, max)
}
#[inline]
pub fn union (a : &Aabb3 <I>, b : &Aabb3 <I>) -> Self where I : std::fmt::Debug {
Aabb3::with_minmax (point3_min (a.min(), b.min()), point3_max (a.max(), b.max()))
}
#[inline]
pub const fn min (&self) -> &Point3 <I> {
&self.min
}
#[inline]
pub const fn max (&self) -> &Point3 <I> {
&self.max
}
#[inline]
pub fn width (&self) -> I {
self.max.0.x - self.min.0.x
}
#[inline]
pub fn height (&self) -> I {
self.max.0.y - self.min.0.y
}
#[inline]
pub fn depth (&self) -> I {
self.max.0.z - self.min.0.z
}
#[inline]
pub fn contains (&self, point : &Point3 <I>) -> bool {
self.min.0.x <= point.0.x && point.0.x <= self.max.0.x &&
self.min.0.y <= point.0.y && point.0.y <= self.max.0.y &&
self.min.0.z <= point.0.z && point.0.z <= self.max.0.z
}
pub fn clamp (&self, point : &Point3 <I>) -> Point3 <I> {
[ Ord::max (Ord::min (self.max.0.x, point.0.x), self.min.0.x),
Ord::max (Ord::min (self.max.0.y, point.0.y), self.min.0.y),
Ord::max (Ord::min (self.max.0.z, point.0.z), self.min.0.z)
].into()
}
#[inline]
pub fn rand_point <R> (&self, rng : &mut R) -> Point3 <I> where
I : rand::distr::uniform::SampleUniform,
R : rand::Rng
{
[ rng.random_range (self.min.0.x..self.max.0.x+I::one()),
rng.random_range (self.min.0.y..self.max.0.y+I::one()),
rng.random_range (self.min.0.z..self.max.0.z+I::one())
].into()
}
#[inline]
pub fn intersects (&self, other : &Aabb3 <I>) -> bool {
intersect::integer::discrete_aabb3_aabb3 (self, other)
}
}