1use crate::Vector;
2use inner_space::Transform;
3use scalars::Zero;
4
5use std::ops::{Add, AddAssign, Index, IndexMut, Sub, SubAssign};
6
7#[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 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}