Skip to main content

simple_vectors/
point.rs

1use crate::Vector;
2use inner_space::Transform;
3use scalars::Zero;
4
5use std::ops::{Add, AddAssign, Index, IndexMut, Sub, SubAssign};
6
7/// A generic, fixed-size affine point with compile-time dimension checking.
8#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
9pub struct Point<T, const N: usize>(pub(crate) [T; N]);
10
11impl<T, const N: usize> Point<T, N> {
12    /// Creates a new point from the given array of elements.
13    pub const fn new(elements: [T; N]) -> Self {
14        Self(elements)
15    }
16}
17
18impl<T: Zero + Copy, const N: usize> Default for Point<T, N> {
19    fn default() -> Self {
20        Self([T::zero(); N])
21    }
22}
23
24impl<T, const N: usize> Sub<Self> for Point<T, N>
25where
26    T: Sub<Output = T> + Copy,
27{
28    type Output = Vector<T, N>;
29    fn sub(self, other: Self) -> Vector<T, N> {
30        let mut elements = self.0;
31        for (element, &other_element) in elements.iter_mut().zip(other.0.iter()) {
32            *element = *element - other_element;
33        }
34        Vector::new(elements)
35    }
36}
37
38impl<T, const N: usize> Add<Vector<T, N>> for Point<T, N>
39where
40    T: Add<Output = T> + Copy,
41{
42    type Output = Self;
43    fn add(mut self, vector: Vector<T, N>) -> Self {
44        let vector_elements: [T; N] = vector.into();
45        for (element, &vector_element) in self.0.iter_mut().zip(vector_elements.iter()) {
46            *element = *element + vector_element;
47        }
48        self
49    }
50}
51
52impl<T, const N: usize> Sub<Vector<T, N>> for Point<T, N>
53where
54    T: Sub<Output = T> + Copy,
55{
56    type Output = Self;
57    fn sub(mut self, vector: Vector<T, N>) -> Self {
58        let vector_elements: [T; N] = vector.into();
59        for (element, &vector_element) in self.0.iter_mut().zip(vector_elements.iter()) {
60            *element = *element - vector_element;
61        }
62        self
63    }
64}
65
66impl<T, const N: usize> AddAssign<Vector<T, N>> for Point<T, N>
67where
68    T: AddAssign + Copy,
69{
70    fn add_assign(&mut self, vector: Vector<T, N>) {
71        let vector_elements: [T; N] = vector.into();
72        for (element, &vector_element) in self.0.iter_mut().zip(vector_elements.iter()) {
73            *element += vector_element;
74        }
75    }
76}
77
78impl<T, const N: usize> SubAssign<Vector<T, N>> for Point<T, N>
79where
80    T: SubAssign + Copy,
81{
82    fn sub_assign(&mut self, vector: Vector<T, N>) {
83        let vector_elements: [T; N] = vector.into();
84        for (element, &vector_element) in self.0.iter_mut().zip(vector_elements.iter()) {
85            *element -= vector_element;
86        }
87    }
88}
89
90impl<T, const N: usize> From<[T; N]> for Point<T, N> {
91    fn from(elements: [T; N]) -> Self {
92        Self::new(elements)
93    }
94}
95
96impl<T, const N: usize> From<Point<T, N>> for [T; N] {
97    fn from(point: Point<T, N>) -> Self {
98        point.0
99    }
100}
101
102impl<'a, T, const N: usize> From<&'a Point<T, N>> for &'a [T; N] {
103    fn from(point: &'a Point<T, N>) -> Self {
104        &point.0
105    }
106}
107
108impl<'a, T, const N: usize> From<&'a mut Point<T, N>> for &'a mut [T; N] {
109    fn from(point: &'a mut Point<T, N>) -> Self {
110        &mut point.0
111    }
112}
113
114impl<'a, T, const N: usize> From<&'a Point<T, N>> for &'a [T] {
115    fn from(point: &'a Point<T, N>) -> Self {
116        &point.0
117    }
118}
119
120impl<'a, T, const N: usize> From<&'a mut Point<T, N>> for &'a mut [T] {
121    fn from(point: &'a mut Point<T, N>) -> Self {
122        &mut point.0
123    }
124}
125
126impl<T, const N: usize> Transform<Point<T, N>> for Vector<T, N>
127where
128    T: Add<Output = T> + Copy,
129{
130    fn apply_point(&self, point: Point<T, N>) -> Point<T, N> {
131        point + *self
132    }
133}
134
135impl<I, T, const N: usize> Index<I> for Point<T, N>
136where
137    [T; N]: Index<I>,
138{
139    type Output = <[T; N] as Index<I>>::Output;
140    fn index(&self, index: I) -> &Self::Output {
141        &self.0[index]
142    }
143}
144
145impl<I, T, const N: usize> IndexMut<I> for Point<T, N>
146where
147    [T; N]: IndexMut<I>,
148{
149    fn index_mut(&mut self, index: I) -> &mut Self::Output {
150        &mut self.0[index]
151    }
152}