simple-vectors 0.5.0

Simple, dimension generic vector math
Documentation
use crate::Vector;
use scalars::Zero;

use std::ops::{Add, AddAssign, Index, IndexMut, Sub, SubAssign};

/// A generic, fixed-size affine point with compile-time dimension checking.
#[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> {
    /// Creates a new point from the given array of elements.
    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]
    }
}