simple_vector2/
lib.rs

1#![cfg_attr(not(test), no_std)]
2
3use core::fmt::{Display, Formatter};
4use core::ops::{Add, Div, Mul, Sub};
5use libm::{sqrt, sqrtf};
6
7pub mod vector_2_to_decimal;
8pub mod mul;
9
10
11#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct Vector2<T> {
14    pub x: T,
15    pub y: T
16}
17
18impl<T> Vector2<T> {
19    /// Make a new vector
20    pub const fn new(x: T, y: T) -> Vector2<T> {
21        Self {
22            x,
23            y
24        }
25    }
26
27    /// Cast a vector from type T to type R
28    pub fn cast_to<R: From<T>>(self) -> Vector2<R> {
29        Vector2::<R> {
30            x: R::from(self.x),
31            y: R::from(self.y),
32        }
33    }
34
35    pub fn map<R, M: FnMut(T) -> R>(self, mut f: M) -> Vector2<R> {
36        Vector2::<R> {
37            x: f(self.x),
38            y: f(self.y),
39        }
40    }
41}
42
43impl<T: Add<Output=T>+Mul<Output=T>+Copy> Vector2<T> {
44
45    /// Returns the value of (x * x) + (y * y). Integer types don't implement sqrt so we
46    /// can't implement magnitude.
47    pub fn square_magnitude(&self) -> T {
48        (self.x * self.x) + (self.y * self.y)
49    }
50}
51
52fn abs_sub<T: Sub<Output=T>+PartialOrd>(a:T, b:T) -> T {
53    if a > b {
54        a - b
55    } else {
56        b - a
57    }
58}
59
60impl<T: Mul<Output=T>+Add<Output=T>+Sub<Output=T>+Copy+PartialOrd> Vector2<T> {
61    /// Returns the value of (x_2 - x_1)^2 + (y_2 - y_1)^2. Integer types don't implement
62    /// sqrt so we can't implement distance.
63    pub fn square_distance(&self, from: &Vector2<T>) -> T {
64        let x_dist = abs_sub(from.x, self.x);
65        let y_dist = abs_sub(from.y, self.y);
66
67        (x_dist * x_dist) + (y_dist * y_dist)
68    }
69}
70
71impl Vector2<f32> {
72    pub fn magnitude(&self) -> f32 {
73        sqrtf(self.square_magnitude())
74    }
75    pub fn distance(&self, other: &Vector2<f32>) -> f32 {
76        sqrtf(self.square_distance(other))
77    }
78}
79
80impl Vector2<f64> {
81    pub fn magnitude(&self) -> f64 {
82        sqrt(self.square_magnitude())
83    }
84    pub fn distance(&self, other: &Vector2<f64>) -> f64 {
85        sqrt(self.square_distance(other))
86    }
87}
88
89impl<T> From<(T, T)> for Vector2<T> {
90    fn from(value: (T, T)) -> Self {
91        Vector2::new(value.0, value.1)
92    }
93}
94
95
96impl<T: Display> Display for Vector2<T> {
97    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
98        write!(f, "({}, {})", self.x, self.y)
99    }
100}
101
102impl<T:Default> Default for Vector2<T> {
103    fn default() -> Self {
104        Self {
105            x: T::default(),
106            y: T::default(),
107        }
108    }
109}
110
111impl<T> Add for Vector2<T> where T: Add<Output = T>{
112    type Output = Vector2<T>;
113
114    fn add(self, rhs: Self) -> Self::Output {
115        Self {
116            x: self.x + rhs.x,
117            y: self.y + rhs.y,
118        }
119    }
120}
121
122impl<T> Sub for Vector2<T> where T: Sub<Output = T>{
123    type Output = Vector2<T>;
124
125    fn sub(self, rhs: Self) -> Self::Output {
126        Self {
127            x: self.x - rhs.x,
128            y: self.y - rhs.y,
129        }
130    }
131}
132
133impl<T> Mul<T> for Vector2<T> where T: Mul<Output = T> + Copy {
134    type Output = Vector2<T>;
135
136    fn mul(self, scalar: T) -> Self::Output {
137        Self {
138            x: self.x * scalar.clone(),
139            y: self.y * scalar,
140        }
141    }
142}
143
144impl<T> Div<T> for Vector2<T> where T: Div<Output = T> + Copy {
145    type Output = Vector2<T>;
146
147    fn div(self, scalar: T) -> Self::Output {
148        Self {
149            x: self.x / scalar.clone(),
150            y: self.y / scalar,
151        }
152    }
153}
154
155
156#[cfg(test)]
157mod tests {
158    use crate::vector_2_to_decimal::{Vector2ToDouble, Vector2ToFloat};
159    use super::*;
160
161    #[test]
162    fn convert_i32_f32() {
163        let v1 = Vector2::new(3, 4);
164        let v2 = v1.to_float();
165        assert_eq!(v2, Vector2::new(3.0, 4.0))
166    }
167
168    #[test]
169    fn convert_i32_f64() {
170        let v1 = Vector2::new(3, 4);
171        let v2 = v1.to_double();
172        assert_eq!(v2, Vector2::new(3.0, 4.0))
173    }
174
175    #[test]
176    fn cast_i32_i64() {
177        let v1 = Vector2::new(3, 4);
178        let v2: Vector2<i64> = v1.cast_to();
179        assert_eq!(v2, Vector2::new(3, 4))
180    }
181
182    #[test]
183    fn add() {
184        let v1 = Vector2::new(1, 2);
185        let v2 = Vector2::new(2, 2);
186        assert_eq!(v1 + v2, Vector2::new(3, 4))
187    }
188
189    #[test]
190    fn sub() {
191        let v1 = Vector2::new(1, 2);
192        let v2 = Vector2::new(2, 2);
193        assert_eq!(v2 - v1, Vector2::new(1, 0))
194    }
195
196    #[test]
197    fn mul() {
198        let v1 = Vector2::new(1, 1);
199        let v2 = 2 * v1;
200        assert_eq!(v2, Vector2::new(2, 2))
201    }
202
203    #[test]
204    fn div() {
205        let v1 = Vector2::new(2, 2);
206        let v2 = v1 / 2;
207
208        assert_eq!(v2, Vector2::new(1, 1))
209    }
210
211    #[test]
212    fn map() {
213        let v1 = Vector2::new(1, 2);
214        assert_eq!(Vector2::new(2, 4), v1.map(|x| x * 2))
215    }
216
217    #[test]
218    fn underflow() {
219        let a = Vector2::new(0_u8, 0_u8);
220        let b = Vector2::new(1_u8, 1_u8);
221
222        assert_eq!(a.square_distance(&b), 2);
223        assert_eq!(b.square_distance(&a), 2)
224
225    }
226}