fey_math/
projection.rs

1use crate::{Num, impl_approx, impl_bytemuck, impl_casts, impl_serde, impl_tuple_arr};
2
3pub type ProjectionF = Projection<f32>;
4
5/// Represents the projection of a 2D shape on an axis.
6///
7/// This primitive does not contain the axis itself, merely
8/// the start and end bounds of the projection. This is used
9/// in overlap checks for convex shapes.
10#[repr(C)]
11#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
12pub struct Projection<T> {
13    pub min: T,
14    pub max: T,
15}
16
17impl_bytemuck!(Projection);
18
19impl_tuple_arr!(
20    NAME = Projection
21    LEN = 2
22    FIELDS = (min, max)
23    TUPLE = (T, T)
24);
25
26impl_approx!(
27    NAME = Projection
28    FIELDS = (min, max)
29);
30
31impl_serde!(
32    NAME = Projection
33    FIELDS = (min, max)
34);
35
36impl_casts!(
37    NAME = Projection
38    FIELDS = (min, max)
39);
40
41impl<T> Projection<T> {
42    /// Create a new projection.
43    #[inline]
44    pub const fn new(min: T, max: T) -> Self {
45        Self { min, max }
46    }
47}
48
49impl<T: Num> Projection<T> {
50    /// Returns true if this projection overlaps the other.
51    #[inline]
52    pub fn overlaps(&self, other: Projection<T>) -> bool {
53        self.min < other.max && self.max > other.min
54    }
55
56    /// If this projection overlaps the other, returns the amount
57    /// which it overlaps.
58    #[inline]
59    pub fn overlap(&self, other: Projection<T>) -> Option<T> {
60        (self.min < other.max && self.max > other.min).then(|| self.max - other.min)
61    }
62
63    /// Length of the projection.
64    #[inline]
65    pub fn len(&self) -> T {
66        self.max - self.min
67    }
68}