use crate::Vector;
use scalars::Zero;
use std::ops::{Add, AddAssign, Index, IndexMut, Sub, SubAssign};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Point<T, const N: usize>(pub(crate) [T; N]);
impl<T, const N: usize> Point<T, N> {
pub const fn new(elements: [T; N]) -> Self {
Self(elements)
}
}
impl<T: Zero + Copy, const N: usize> Default for Point<T, N> {
fn default() -> Self {
Self([T::zero(); N])
}
}
impl<T, const N: usize> Sub<Self> for Point<T, N>
where
T: Sub<Output = T> + Copy,
{
type Output = Vector<T, N>;
fn sub(self, other: Self) -> Vector<T, N> {
let mut elements = self.0;
for (element, &other_element) in elements.iter_mut().zip(other.0.iter()) {
*element = *element - other_element;
}
Vector::new(elements)
}
}
impl<T, const N: usize> Add<Vector<T, N>> for Point<T, N>
where
T: Add<Output = T> + Copy,
{
type Output = Self;
fn add(mut self, vector: Vector<T, N>) -> Self {
let vector_elements: [T; N] = vector.into();
for (element, &vector_element) in self.0.iter_mut().zip(vector_elements.iter()) {
*element = *element + vector_element;
}
self
}
}
impl<T, const N: usize> Sub<Vector<T, N>> for Point<T, N>
where
T: Sub<Output = T> + Copy,
{
type Output = Self;
fn sub(mut self, vector: Vector<T, N>) -> Self {
let vector_elements: [T; N] = vector.into();
for (element, &vector_element) in self.0.iter_mut().zip(vector_elements.iter()) {
*element = *element - vector_element;
}
self
}
}
impl<T, const N: usize> AddAssign<Vector<T, N>> for Point<T, N>
where
T: AddAssign + Copy,
{
fn add_assign(&mut self, vector: Vector<T, N>) {
let vector_elements: [T; N] = vector.into();
for (element, &vector_element) in self.0.iter_mut().zip(vector_elements.iter()) {
*element += vector_element;
}
}
}
impl<T, const N: usize> SubAssign<Vector<T, N>> for Point<T, N>
where
T: SubAssign + Copy,
{
fn sub_assign(&mut self, vector: Vector<T, N>) {
let vector_elements: [T; N] = vector.into();
for (element, &vector_element) in self.0.iter_mut().zip(vector_elements.iter()) {
*element -= vector_element;
}
}
}
impl<T, const N: usize> From<[T; N]> for Point<T, N> {
fn from(elements: [T; N]) -> Self {
Self::new(elements)
}
}
impl<T, const N: usize> From<Point<T, N>> for [T; N] {
fn from(point: Point<T, N>) -> Self {
point.0
}
}
impl<I, T, const N: usize> Index<I> for Point<T, N>
where
[T; N]: Index<I>,
{
type Output = <[T; N] as Index<I>>::Output;
fn index(&self, index: I) -> &Self::Output {
&self.0[index]
}
}
impl<I, T, const N: usize> IndexMut<I> for Point<T, N>
where
[T; N]: IndexMut<I>,
{
fn index_mut(&mut self, index: I) -> &mut Self::Output {
&mut self.0[index]
}
}