use crate::*; use derive_more::{Add, AddAssign, Neg, Sub, SubAssign}; use num_traits::{real::Real, Inv, One, 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 Rotor { /// The scalar component. pub scalar: T, /// The component representing the xy plane. pub xy: T, } impl Rotor { /// Creates a new rotor from its components. pub fn new(scalar: T, xy: T) -> Self { Self { scalar, xy } } } impl Rotor { /// Rotates a vector by the rotor. pub fn rotate(self, vector: Vector) -> Vector { self.normalize().rotate_normalized(vector) } /// Rotates a vector by the rotor. /// The rotor has to be normalized already. pub fn rotate_normalized(self, vector: Vector) -> Vector { let Self { scalar, xy } = self * self; Vector { x: scalar * vector.x + xy * vector.y, y: scalar * vector.y - xy * vector.x, } } /// The reverse of the rotor. pub fn reverse(self) -> Self { Self { scalar: self.scalar, xy: -self.xy, } } } impl Rotor { /// Creates a new scalar rotor. pub fn scalar(scalar: T) -> Self { Self { scalar, xy: T::zero(), } } /// Creates a new rotor along the xy plane. pub fn xy(xy: T) -> Self { Self { scalar: T::zero(), xy, } } } impl Zero for Rotor { fn zero() -> Self { Self { scalar: T::zero(), xy: T::zero(), } } fn is_zero(&self) -> bool { self.scalar.is_zero() && self.xy.is_zero() } } impl One for Rotor { fn one() -> Self { Self { scalar: T::one(), xy: T::zero(), } } fn is_one(&self) -> bool { self.scalar.is_one() && self.xy.is_zero() } } impl Inv for Rotor { type Output = Self; fn inv(self) -> Self { let rev = self.reverse(); rev / self.dot(rev) } } impl From for Rotor { fn from(scalar: T) -> Self { Self::scalar(scalar) } } impl Mul for Rotor where T: Mul + Copy, { type Output = Self; fn mul(self, other: T) -> Self { Self { scalar: self.scalar * other, xy: self.xy * other, } } } impl MulAssign for Rotor where T: MulAssign + Copy, { fn mul_assign(&mut self, other: T) { self.scalar *= other; self.xy *= other; } } impl Div for Rotor where T: Div + Copy, { type Output = Self; fn div(self, other: T) -> Self { Self { scalar: self.scalar / other, xy: self.xy / other, } } } impl DivAssign for Rotor where T: DivAssign + Copy, { fn div_assign(&mut self, other: T) { self.scalar /= other; self.xy /= other; } } impl VectorSpace for Rotor { type Scalar = T; } impl DotProduct for Rotor { type Output = Self::Scalar; fn dot(self, other: Self) -> T { self.scalar * other.scalar - self.xy * other.xy } } impl DotProduct> for Rotor { type Output = Vector; #[inline] fn dot(self, other: Vector) -> Vector { other.dot(self) } } impl DotProduct> for Rotor { type Output = Self; #[inline] fn dot(self, other: Bivector) -> Self { other.dot(self) } } impl InnerSpace for Rotor { fn scalar(self, other: Self) -> T { self.dot(other) } fn magnitude2(self) -> T { self.dot(self.reverse()) } } impl Mul for Rotor { type Output = Self; fn mul(self, other: Self) -> Self { Self { scalar: self.dot(other), xy: self.scalar * other.xy + other.scalar * self.xy, } } } impl MulAssign for Rotor { fn mul_assign(&mut self, other: Self) { *self = *self * other; } } impl Div for Rotor { type Output = Self; fn div(self, other: Self) -> Self { self * other.inv() } } impl DivAssign for Rotor { fn div_assign(&mut self, other: Self) { *self = *self / other; } }