use crate::*; use derive_more::{Add, AddAssign, Neg, Sub, SubAssign}; use num_traits::{real::Real, Zero}; use std::ops::{Div, DivAssign, Mul, MulAssign}; use vector_basis::Basis; use vector_space::{DotProduct, InnerSpace, VectorSpace}; /// The 2D vector type. #[derive(Copy, Clone, Debug, PartialEq, Eq, Add, AddAssign, Sub, SubAssign, Neg)] pub struct Vector { /// The component representing the x axis. pub x: T, /// The component representing the y axis. pub y: T, } impl Vector { /// Creates a new vector from its components. pub fn new(x: T, y: T) -> Self { Self { x, y } } } impl Vector { /// Creates a new vector along the x axis. pub fn x(x: T) -> Self { Self { x, y: T::zero() } } /// Creates a new vector along the y axis. pub fn y(y: T) -> Self { Self { x: T::zero(), y } } } impl Basis<0> for Vector { fn unit_basis() -> Self { Self { x: T::one(), y: T::zero(), } } fn basis_of(x: T) -> Self { Self { x, y: T::zero() } } fn basis(&self) -> Self::Scalar { self.x } fn basis_mut(&mut self) -> &mut Self::Scalar { &mut self.x } fn with_basis(self, x: T) -> Self { Self { x, ..self } } } impl Basis<1> for Vector { fn unit_basis() -> Self { Self { x: T::zero(), y: T::one(), } } fn basis_of(y: T) -> Self { Self { x: T::zero(), y } } fn basis(&self) -> Self::Scalar { self.y } fn basis_mut(&mut self) -> &mut Self::Scalar { &mut self.y } fn with_basis(self, y: T) -> Self { Self { y, ..self } } } impl Zero for Vector { fn zero() -> Self { Self { x: T::zero(), y: T::zero(), } } fn is_zero(&self) -> bool { self.x.is_zero() && self.y.is_zero() } } impl Mul for Vector where T: Mul + Copy, { type Output = Self; fn mul(self, other: T) -> Self { Self { x: self.x * other, y: self.y * other, } } } impl MulAssign for Vector where T: MulAssign + Copy, { fn mul_assign(&mut self, other: T) { self.x *= other; self.y *= other; } } impl Div for Vector where T: Div + Copy, { type Output = Self; fn div(self, other: T) -> Self { Self { x: self.x / other, y: self.y / other, } } } impl DivAssign for Vector where T: DivAssign + Copy, { fn div_assign(&mut self, other: T) { self.x /= other; self.y /= other; } } impl VectorSpace for Vector { type Scalar = T; } impl DotProduct for Vector { type Output = Self::Scalar; fn dot(self, other: Self) -> T { self.x * other.x + self.y * other.y } } impl DotProduct> for Vector { type Output = Self; fn dot(self, other: Bivector) -> Self { Self { x: -self.y * other.xy, y: self.x * other.xy, } } } impl DotProduct> for Vector { type Output = Self; fn dot(self, other: Rotor) -> Self { self * other.scalar + Self { x: -self.y * other.xy, y: self.x * other.xy, } } } impl InnerSpace for Vector { fn scalar(self, other: Self) -> T { self.dot(other) } } impl Mul for Vector { type Output = Rotor; fn mul(self, other: Self) -> Rotor { Rotor { scalar: self.dot(other), xy: self.x * other.y + self.y * other.x, } } } impl From<[T; 2]> for Vector { fn from([x, y]: [T; 2]) -> Self { Self { x, y } } } impl From> for [T; 2] { fn from(Vector { x, y }: Vector) -> Self { [x, y] } } impl From<(T, T)> for Vector { fn from((x, y): (T, T)) -> Self { Self { x, y } } } impl From> for (T, T) { fn from(Vector { x, y }: Vector) -> Self { (x, y) } }