vg_algebra/vectors/
vector2d.rs1use std::ops::{Add, Mul, Sub};
2
3use super::{BivectorTrait, VectorTrait};
4
5#[derive(Debug, Clone, Copy, PartialEq)]
7pub struct Vector {
8 pub x: f64,
9 pub y: f64,
10}
11
12impl Vector {
13 pub fn new(x: f64, y: f64) -> Vector {
15 return Vector { x, y };
16 }
17}
18
19impl VectorTrait for Vector {
20 fn scale(&self, other: f64) -> Self {
21 Vector {
22 x: self.x * other,
23 y: self.y * other,
24 }
25 }
26
27 fn length(&self) -> f64 {
28 f64::sqrt((self.x * self.x) + (self.y * self.y))
29 }
30
31 fn normalize(&self) -> Vector {
32 let length = self.length();
33 Vector::new(self.x / length, self.y / length)
34 }
35
36 fn is_colinear_to(&self, rhs: Self) -> bool {
37 let factor_x = self.x / rhs.x;
38 let factor_y = self.y / rhs.y;
39
40 let difference = factor_x - factor_y;
41
42 difference.abs() <= f64::EPSILON
43 }
44
45 type WedgeProductOutput = Bivector;
46 fn wedge_product(&self, rhs: Self) -> Self::WedgeProductOutput {
47 Bivector(self.x * rhs.y - self.y * rhs.x)
48 }
49
50 type CrossProductOutput = f64;
51 fn cross_product(&self, rhs: Self) -> Self::CrossProductOutput {
52 self.wedge_product(rhs).0
53 }
54
55 fn dot_product(&self, rhs: Self) -> f64 {
56 (self.x * rhs.x) + (self.y * rhs.y)
57 }
58}
59
60impl Add for Vector {
61 type Output = Vector;
62
63 fn add(self, rhs: Self) -> Vector {
64 Vector {
65 x: self.x + rhs.x,
66 y: self.y + rhs.y,
67 }
68 }
69}
70
71impl Sub for Vector {
72 type Output = Vector;
73
74 fn sub(self, rhs: Self) -> Self::Output {
75 Vector {
76 x: self.x - rhs.x,
77 y: self.y - rhs.y,
78 }
79 }
80}
81
82impl Mul for Vector {
83 type Output = Rotor;
84
85 fn mul(self, rhs: Self) -> Self::Output {
86 let scalar = self.dot_product(rhs);
87 let bivector = self.wedge_product(rhs);
88
89 Rotor { scalar, bivector }
90 }
91}
92
93#[derive(Debug, PartialEq)]
95pub struct Bivector(pub f64);
96
97impl BivectorTrait for Bivector {
98 fn scale(&self, p: f64) -> Self {
99 Bivector(self.0 * p)
100 }
101
102 fn magnitude(&self) -> f64 {
103 self.0
104 }
105}
106
107#[derive(Debug, PartialEq)]
108pub struct Rotor {
109 pub scalar: f64,
110 pub bivector: Bivector,
111}
112
113#[cfg(test)]
114mod test_vectors {
115 use crate::vectors::{
116 vector2d::{Bivector, Rotor},
117 VectorTrait,
118 };
119
120 use super::Vector;
121
122 #[test]
123 fn test_new() {
124 let expected = Vector { x: 0.1, y: 0.2 };
125 let result = Vector::new(0.1, 0.2);
126 assert_eq!(expected, result)
127 }
128
129 #[test]
130 fn test_scale() {
131 let vector = Vector::new(1.0, 1.0);
132
133 let expected = Vector::new(2.0, 2.0);
134 let result = vector.scale(2.0);
135
136 assert_eq!(expected, result)
137 }
138
139 #[test]
140 fn test_length() {
141 let vector = Vector::new(1.0, 1.0);
142
143 let expected = f64::sqrt(2.0);
144 let result = vector.length();
145
146 assert_eq!(expected, result)
147 }
148
149 #[test]
150 fn test_is_colinear_to() {
151 let a = Vector::new(0.1, 0.3);
152 let b = Vector::new(2.0, 0.3);
153 let c = Vector::new(0.2, 0.6);
154
155 assert_eq!(a.is_colinear_to(b), b.is_colinear_to(c));
156 assert!(a.is_colinear_to(c));
157 assert!(a.is_colinear_to(a))
158 }
159
160 #[test]
161 fn test_addition() {
162 let a = Vector::new(1.0, 2.0);
163 let b = Vector::new(0.5, 1.0);
164
165 let expected = Vector::new(1.5, 3.0);
166 let result = a + b;
167
168 assert_eq!(expected, result)
169 }
170
171 #[test]
172 fn test_subtraction() {
173 let a = Vector::new(1.0, 2.0);
174 let b = Vector::new(0.5, 1.0);
175
176 let expected = Vector::new(0.5, 1.0);
177 let result = a - b;
178
179 assert_eq!(expected, result)
180 }
181
182 #[test]
183 fn test_vector_multiplication() {
184 let a = Vector::new(1.0, 0.5);
185 let b = Vector::new(2.0, 0.0);
186
187 let expected_with_help = Rotor {
188 scalar: a.dot_product(b),
189 bivector: a.wedge_product(b),
190 };
191 let expected_without_help = Rotor {
192 scalar: 2.0,
193 bivector: Bivector(-1.0),
194 };
195
196 let result = a * b;
197 assert_eq!(expected_with_help, expected_without_help);
198 assert_eq!(expected_with_help, result);
199 assert_eq!(expected_without_help, result);
200 }
201}