pasture_core/math/
minmax.rs

1use std::cmp;
2
3use nalgebra::{Scalar, Vector3};
4
5/// Helper trait for computing minimum and maximum values for types. This is used in conjunction
6/// with `PrimitiveType` to enable min/max computations even for vector types
7pub trait MinMax {
8    /// Computes the infimum of this value and `other`. For scalar types, the infimum is simply the
9    /// minimum of the two types (as defined by `PartialOrd`), for vector types, this is the component-wise
10    /// minimum
11    ///
12    /// # Example
13    /// ```
14    /// use pasture_core::math::MinMax;
15    /// # use pasture_core::nalgebra::Vector3;
16    ///
17    /// assert_eq!(5i32.infimum(&3i32), 3i32);
18    /// assert_eq!(Vector3::new(1.0, 2.0, 3.0).infimum(&Vector3::new(2.0, 1.0, 0.0)), Vector3::new(1.0, 1.0, 0.0));
19    /// ```
20    fn infimum(&self, other: &Self) -> Self;
21    /// Computes the supremum of this value and `other`. For scalar types, the infimum is simply the
22    /// maximum of the two types (as defined by `PartialOrd`), for vector types, this is the component-wise
23    /// maximum
24    ///
25    /// # Example
26    /// ```
27    /// use pasture_core::math::MinMax;
28    /// # use pasture_core::nalgebra::Vector3;
29    ///
30    /// assert_eq!(5i32.supremum(&3i32), 5i32);
31    /// assert_eq!(Vector3::new(1.0, 2.0, 3.0).supremum(&Vector3::new(2.0, 1.0, 4.0)), Vector3::new(2.0, 2.0, 4.0));
32    /// ```
33    fn supremum(&self, other: &Self) -> Self;
34}
35
36macro_rules! impl_minmax_for_primitive_type {
37    ($type:tt) => {
38        impl MinMax for $type {
39            fn infimum(&self, other: &Self) -> Self {
40                cmp::min(*self, *other)
41            }
42
43            fn supremum(&self, other: &Self) -> Self {
44                cmp::max(*self, *other)
45            }
46        }
47    };
48}
49
50impl_minmax_for_primitive_type! {u8}
51impl_minmax_for_primitive_type! {u16}
52impl_minmax_for_primitive_type! {u32}
53impl_minmax_for_primitive_type! {u64}
54impl_minmax_for_primitive_type! {i8}
55impl_minmax_for_primitive_type! {i16}
56impl_minmax_for_primitive_type! {i32}
57impl_minmax_for_primitive_type! {i64}
58impl_minmax_for_primitive_type! {bool}
59
60impl MinMax for f32 {
61    fn infimum(&self, other: &Self) -> Self {
62        if *self < *other {
63            *self
64        } else {
65            *other
66        }
67    }
68
69    fn supremum(&self, other: &Self) -> Self {
70        if *self > *other {
71            *self
72        } else {
73            *other
74        }
75    }
76}
77
78impl MinMax for f64 {
79    fn infimum(&self, other: &Self) -> Self {
80        if *self < *other {
81            *self
82        } else {
83            *other
84        }
85    }
86
87    fn supremum(&self, other: &Self) -> Self {
88        if *self > *other {
89            *self
90        } else {
91            *other
92        }
93    }
94}
95
96impl<T: MinMax + Scalar> MinMax for Vector3<T> {
97    fn infimum(&self, other: &Self) -> Self {
98        Vector3::new(
99            self.x.infimum(&other.x),
100            self.y.infimum(&other.y),
101            self.z.infimum(&other.z),
102        )
103    }
104
105    fn supremum(&self, other: &Self) -> Self {
106        Vector3::new(
107            self.x.supremum(&other.x),
108            self.y.supremum(&other.y),
109            self.z.supremum(&other.z),
110        )
111    }
112}