ga2/
bivector.rs

1use crate::*;
2
3use derive_more::{Add, AddAssign, Neg, Sub, SubAssign};
4use num_traits::{real::Real, Zero};
5use std::ops::{Div, DivAssign, Mul, MulAssign};
6use vector_space::{DotProduct, InnerSpace, VectorSpace};
7
8/// The 2D bivector type.
9#[derive(Copy, Clone, Debug, PartialEq, Eq, Add, AddAssign, Sub, SubAssign, Neg)]
10pub struct Bivector<T> {
11    /// The component representing the xy plane.
12    pub xy: T,
13}
14
15impl<T> Bivector<T> {
16    /// Creates a new bivector from its components.
17    pub fn new(xy: T) -> Self {
18        Self { xy }
19    }
20}
21
22impl<T: Real> Bivector<T> {
23    /// Returns the exponent of the bivector as a rotor.
24    pub fn exp(self) -> Rotor<T> {
25        let (xy, scalar) = self.xy.sin_cos();
26        Rotor { scalar, xy }
27    }
28}
29
30impl<T: Zero> Bivector<T> {
31    /// Creates a new bivector along the xy plane.
32    pub fn xy(xy: T) -> Self {
33        Self { xy }
34    }
35}
36
37impl<T: Zero> Zero for Bivector<T> {
38    fn zero() -> Self {
39        Self { xy: T::zero() }
40    }
41
42    fn is_zero(&self) -> bool {
43        self.xy.is_zero()
44    }
45}
46
47impl<T> Mul<T> for Bivector<T>
48where
49    T: Mul<Output = T> + Copy,
50{
51    type Output = Self;
52    fn mul(self, other: T) -> Self {
53        Self {
54            xy: self.xy * other,
55        }
56    }
57}
58
59impl<T> MulAssign<T> for Bivector<T>
60where
61    T: MulAssign + Copy,
62{
63    fn mul_assign(&mut self, other: T) {
64        self.xy *= other;
65    }
66}
67
68impl<T> Div<T> for Bivector<T>
69where
70    T: Div<Output = T> + Copy,
71{
72    type Output = Self;
73    fn div(self, other: T) -> Self {
74        Self {
75            xy: self.xy / other,
76        }
77    }
78}
79
80impl<T> DivAssign<T> for Bivector<T>
81where
82    T: DivAssign + Copy,
83{
84    fn div_assign(&mut self, other: T) {
85        self.xy /= other;
86    }
87}
88
89impl<T: Real> VectorSpace for Bivector<T> {
90    type Scalar = T;
91}
92
93impl<T: Real> DotProduct for Bivector<T> {
94    type Output = Self::Scalar;
95    fn dot(self, other: Self) -> T {
96        -self.xy * other.xy
97    }
98}
99
100impl<T: Real> DotProduct<Vector<T>> for Bivector<T> {
101    type Output = Vector<T>;
102    #[inline]
103    fn dot(self, other: Vector<T>) -> Vector<T> {
104        other.dot(self)
105    }
106}
107
108impl<T: Real> DotProduct<Rotor<T>> for Bivector<T> {
109    type Output = Rotor<T>;
110    fn dot(self, other: Rotor<T>) -> Rotor<T> {
111        Rotor {
112            scalar: -self.xy * other.xy,
113            xy: self.xy * other.scalar,
114        }
115    }
116}
117
118impl<T: Real> InnerSpace for Bivector<T> {
119    fn scalar(self, other: Self) -> T {
120        self.dot(other)
121    }
122
123    fn magnitude2(self) -> T {
124        -self.dot(self)
125    }
126}