Skip to main content

simple_vectors/
point.rs

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