hex_math/
vector.rs

1use {
2    crate::num::Real,
3    alloc::vec::Vec,
4    core::ops::{Add, Div, Mul, Sub},
5};
6
7pub trait Vector<F: Field>:
8    Mul<F, Output = Self> + Add<Self, Output = Self> + Sized + Copy
9{
10    fn len(self) -> F;
11    fn dot(self, rhs: Self) -> F;
12    fn norm(self) -> Self;
13    fn cross(self, rhs: Self) -> Self;
14}
15
16pub trait Field: Add + Sub + Div + Mul + Sized {}
17
18impl<F: Add<F> + Sub<F> + Mul<F> + Div<F> + Sized> Field for F {}
19
20#[derive(Clone, Copy)]
21pub struct R3(pub [f32; 3]);
22
23impl Vector<f32> for R3 {
24    fn len(self) -> f32 {
25        self.dot(self).sqrt()
26    }
27
28    fn dot(self, rhs: Self) -> f32 {
29        let a = self.0;
30        let b = rhs.0;
31
32        a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
33    }
34
35    fn norm(self) -> Self {
36        self / self.len()
37    }
38
39    fn cross(self, rhs: Self) -> Self {
40        let a = self.0;
41        let b = rhs.0;
42
43        [
44            a[1] * b[2] - a[2] * b[1],
45            a[2] * b[0] - a[0] * b[2],
46            a[0] * b[1] - a[1] * b[0],
47        ]
48        .into()
49    }
50}
51
52pub fn span<V: Vector<f32>>(basis: [V; 2], range: u32) -> Vec<V> {
53    let range = range as i32;
54
55    let mut span = Vec::new();
56    for y in -range..=range {
57        for x in -range..=range {
58            span.push(basis[0] * x as f32 + basis[1] * y as f32)
59        }
60    }
61
62    span
63}
64
65impl core::ops::Add for R3 {
66    type Output = Self;
67
68    fn add(self, rhs: R3) -> Self {
69        let a = self.0;
70        let b = rhs.0;
71
72        [a[0] + b[0], a[1] + b[1], a[2] + b[2]].into()
73    }
74}
75
76impl core::ops::Neg for R3 {
77    type Output = Self;
78
79    fn neg(self) -> R3 {
80        let a = self.0;
81        [-a[0], -a[1], -a[2]].into()
82    }
83}
84
85impl core::ops::Sub for R3 {
86    type Output = Self;
87
88    fn sub(self, rhs: R3) -> R3 {
89        self + -rhs
90    }
91}
92
93impl core::ops::Div<f32> for R3 {
94    type Output = Self;
95
96    fn div(self, rhs: f32) -> Self {
97        let a = self.0;
98
99        [a[0] / rhs, a[1] / rhs, a[2] / rhs].into()
100    }
101}
102
103impl core::ops::Mul<f32> for R3 {
104    type Output = Self;
105
106    fn mul(self, rhs: f32) -> Self {
107        let a = self.0;
108
109        [a[0] * rhs, a[1] * rhs, a[2] * rhs].into()
110    }
111}
112
113impl core::ops::Index<u8> for R3 {
114    type Output = f32;
115
116    fn index(&self, idx: u8) -> &Self::Output {
117        &self.0[idx as usize]
118    }
119}
120
121impl From<[f32; 3]> for R3 {
122    fn from(r3: [f32; 3]) -> Self {
123        Self(r3)
124    }
125}
126
127#[cfg(test)]
128mod test {
129    use super::*;
130
131    #[test]
132    fn add() {
133        let x: R3 = [1.0, 2.0, 3.0].into();
134        let y: R3 = [4.0, 5.0, 6.0].into();
135
136        assert_eq!(x + y, [5.0, 7.0, 9.0].into())
137    }
138
139    #[test]
140    fn sub() {
141        let x: R3 = [1.0, 0.0, 0.0].into();
142        let y: R3 = [1.0, 0.0, 0.0].into();
143
144        assert_eq!(x - y, [0.0, 0.0, 0.0].into())
145    }
146
147    #[test]
148    fn orthogonal_dot_product() {
149        let x: R3 = [1.0, 0.0, 0.0].into();
150        let y: R3 = [0.0, 1.0, 0.0].into();
151
152        assert_eq!(x.dot(y), 0.0)
153    }
154
155    #[test]
156    fn unit_len() {
157        let x: R3 = [1.0, 0.0, 0.0].into();
158        assert_eq!(x.len(), 1.0)
159    }
160
161    #[test]
162    fn norm() {
163        let x: R3 = [2.0, 0.0, 0.0].into();
164        assert_eq!(x.norm(), [1.0, 0.0, 0.0].into())
165    }
166}