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_space::{DotProduct, InnerSpace, VectorSpace}; /// The 2D bivector type. #[derive(Copy, Clone, Debug, PartialEq, Eq, Add, AddAssign, Sub, SubAssign, Neg)] pub struct Bivector { /// The component representing the xy plane. pub xy: T, } impl Bivector { /// Creates a new bivector from its components. pub fn new(xy: T) -> Self { Self { xy } } } impl Bivector { /// Returns the exponent of the bivector as a rotor. pub fn exp(self) -> Rotor { let (xy, scalar) = self.xy.sin_cos(); Rotor { scalar, xy } } } impl Bivector { /// Creates a new bivector along the xy plane. pub fn xy(xy: T) -> Self { Self { xy } } } impl Zero for Bivector { fn zero() -> Self { Self { xy: T::zero() } } fn is_zero(&self) -> bool { self.xy.is_zero() } } impl Mul for Bivector where T: Mul + Copy, { type Output = Self; fn mul(self, other: T) -> Self { Self { xy: self.xy * other, } } } impl MulAssign for Bivector where T: MulAssign + Copy, { fn mul_assign(&mut self, other: T) { self.xy *= other; } } impl Div for Bivector where T: Div + Copy, { type Output = Self; fn div(self, other: T) -> Self { Self { xy: self.xy / other, } } } impl DivAssign for Bivector where T: DivAssign + Copy, { fn div_assign(&mut self, other: T) { self.xy /= other; } } impl VectorSpace for Bivector { type Scalar = T; } impl DotProduct for Bivector { type Output = Self::Scalar; fn dot(self, other: Self) -> T { -self.xy * other.xy } } impl DotProduct> for Bivector { type Output = Vector; #[inline] fn dot(self, other: Vector) -> Vector { other.dot(self) } } impl DotProduct> for Bivector { type Output = Rotor; fn dot(self, other: Rotor) -> Rotor { Rotor { scalar: -self.xy * other.xy, xy: self.xy * other.scalar, } } } impl InnerSpace for Bivector { fn scalar(self, other: Self) -> T { self.dot(other) } fn magnitude2(self) -> T { -self.dot(self) } }