1use serde::Deserialize;
6use serde::Serialize;
7
8use crate::traits::FloatExt;
9use crate::Approximately;
10use crate::Float;
11use crate::Vector;
12
13#[derive(Serialize, Deserialize, Debug, Default, Clone, Copy, PartialEq, PartialOrd)]
14#[repr(C)]
15pub struct Bivector {
16 pub xy: Float,
17 pub xz: Float,
18 pub yz: Float,
19}
20
21impl Bivector {
22 #[inline]
23 pub fn new<F: Into<Float>>(xy: F, xz: F, yz: F) -> Self {
24 Self {
25 xy: xy.into(),
26 xz: xz.into(),
27 yz: yz.into(),
28 }
29 }
30
31 #[inline]
32 pub fn zero() -> Self {
33 Self {
34 xy: Float::ZERO,
35 xz: Float::ZERO,
36 yz: Float::ZERO,
37 }
38 }
39
40 #[inline]
41 pub fn unit_xy() -> Self {
42 Self {
43 xy: Float::ONE,
44 xz: Float::ZERO,
45 yz: Float::ZERO,
46 }
47 }
48
49 #[inline]
50 pub fn unit_xz() -> Self {
51 Self {
52 xy: Float::ZERO,
53 xz: Float::ONE,
54 yz: Float::ZERO,
55 }
56 }
57
58 #[inline]
59 pub fn unit_yz() -> Self {
60 Self {
61 xy: Float::ZERO,
62 xz: Float::ZERO,
63 yz: Float::ONE,
64 }
65 }
66
67 #[inline]
68 pub fn from_axis_vector(axis: Vector) -> Self {
69 Self::new(axis.z, axis.y, axis.x)
70 }
71
72 #[inline]
73 pub fn from_wedge<V>(u: V, v: V) -> Self
74 where
75 V: Into<Vector>,
76 {
77 let u: Vector = u.into();
78 let v: Vector = v.into();
79 Self {
80 xy: u.x * v.y - u.y * v.x,
81 xz: u.x * v.z - u.z * v.x,
82 yz: u.y * v.z - u.z * v.y,
83 }
84 }
85
86 #[inline]
87 pub fn magnitude_sq(&self) -> Float {
88 self.xy * self.xy
89 }
90
91 #[inline]
92 pub fn magnitude(&self) -> Float {
93 self.xy
94 }
95}
96
97impl Approximately for Bivector {
98 fn approximately(&self, other: Self, epsilon: Float) -> bool {
99 self.xy.approximately(other.xy, epsilon)
100 && self.xz.approximately(other.xz, epsilon)
101 && self.yz.approximately(other.yz, epsilon)
102 }
103}