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#[derive(Copy, Clone, Debug, PartialEq, Eq, Add, AddAssign, Sub, SubAssign, Neg)]
10pub struct Bivector<T> {
11 pub xy: T,
13}
14
15impl<T> Bivector<T> {
16 pub fn new(xy: T) -> Self {
18 Self { xy }
19 }
20}
21
22impl<T: Real> Bivector<T> {
23 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 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}