webgl_matrix/
vec3.rs

1#[cfg(feature = "Matrix3")]
2use crate::mat3::Mat3;
3#[cfg(feature = "Matrix4")]
4use crate::mat4::Mat4;
5use crate::slice_ops::*;
6#[cfg(feature = "Matrix4")]
7use crate::vec4::Vec4;
8#[cfg(any(feature = "Matrix3", feature = "Matrix4"))]
9use crate::vector::MulVectorMatrix;
10use crate::vector::Vector;
11use std::f32;
12
13pub type Vec3 = [f32; 3];
14
15impl_vector!(Vec3, 3);
16
17#[cfg(feature = "Matrix3")]
18impl MulVectorMatrix<Mat3> for Vec3 {
19    type VectorType = Vec3;
20
21    fn mul_matrix_left(&self, lhs: &Mat3) -> Self::VectorType {
22        let x = self[0];
23        let y = self[1];
24        let z = self[2];
25
26        [
27            lhs[0] * x + lhs[1] * y + lhs[2] * z,
28            lhs[3] * x + lhs[4] * y + lhs[5] * z,
29            lhs[6] * x + lhs[7] * y + lhs[8] * z,
30        ]
31    }
32
33    fn mul_matrix(&self, rhs: &Mat3) -> Self::VectorType {
34        let x = self[0];
35        let y = self[1];
36        let z = self[2];
37
38        [
39            rhs[0] * x + rhs[3] * y + rhs[6] * z,
40            rhs[1] * x + rhs[4] * y + rhs[7] * z,
41            rhs[2] * x + rhs[5] * y + rhs[8] * z,
42        ]
43    }
44}
45
46#[cfg(feature = "Matrix4")]
47impl MulVectorMatrix<Mat4> for Vec3 {
48    type VectorType = Vec4;
49
50    /// Interprets `self` as a column vector with the 4th component equal to 1 and multiplies the given matrix
51    /// from the left-hand-side, i.e. `lhs * [...self, 1.0]`
52    fn mul_matrix_left(&self, lhs: &Mat4) -> Self::VectorType {
53        let x = self[0];
54        let y = self[1];
55        let z = self[2];
56        // let w = 1.0
57
58        [
59            lhs[0] * x + lhs[1] * y + lhs[2] * z + lhs[3],
60            lhs[4] * x + lhs[5] * y + lhs[6] * z + lhs[7],
61            lhs[8] * x + lhs[9] * y + lhs[10] * z + lhs[11],
62            lhs[12] * x + lhs[13] * y + lhs[14] * z + lhs[15],
63        ]
64    }
65
66    /// Interprets `self` as a row vector with the 4th component equal to 1 and multiplies the given matrix
67    /// from the right-hand-side, i.e. `[...self, 1.0] * rhs`
68    fn mul_matrix(&self, rhs: &Mat4) -> Self::VectorType {
69        let x = self[0];
70        let y = self[1];
71        let z = self[2];
72        // let w = 1.0;
73
74        [
75            rhs[0] * x + rhs[4] * y + rhs[8] * z + rhs[12],
76            rhs[1] * x + rhs[5] * y + rhs[9] * z + rhs[13],
77            rhs[2] * x + rhs[6] * y + rhs[10] * z + rhs[14],
78            rhs[3] * x + rhs[7] * y + rhs[11] * z + rhs[15],
79        ]
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86    use crate::utils::almost_eq;
87
88    #[test]
89    #[cfg(feature = "Matrix3")]
90    fn vec3_mul_matrix_left() {
91        let a = [1., 2., 3., 4., 5., 6., 7., 8., 9.];
92        let b = [11., 12., 13.];
93
94        let c = b.mul_matrix_left(&a);
95        assert_eq!(c, [74., 182., 290.]);
96    }
97
98    #[test]
99    #[cfg(feature = "Matrix3")]
100    fn vec3_mul_matrix() {
101        let a = [1., 2., 3., 4., 5., 6., 7., 8., 9.];
102        let b = [11., 12., 13.];
103
104        let c = b.mul_matrix(&a);
105        assert_eq!(c, [150., 186., 222.]);
106    }
107    #[test]
108    #[cfg(feature = "Matrix4")]
109    fn vec3_mul_matrix4() {
110        let a = [
111            1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.,
112        ];
113        let b = [17., 18., 19.];
114
115        let c = b.mul_matrix(&a);
116        assert_eq!(c, [291., 346., 401., 456.]);
117    }
118
119    #[test]
120    #[cfg(feature = "Matrix4")]
121    fn vec3_mul_matrix4_left() {
122        let a = [
123            1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.,
124        ];
125        let b = [17., 18., 19.];
126
127        let c = b.mul_matrix_left(&a);
128        assert_eq!(c, [114., 334., 554., 774.]);
129    }
130
131    #[test]
132    fn vec3_is_immutable() {
133        let b = [2., 3., 4.];
134        let c = [3., 2., 3.];
135
136        let _d = b.add(&c);
137        assert_eq!(b, [2., 3., 4.]);
138    }
139
140    #[test]
141    fn vec3_add() {
142        let a = [1., 2., 3.];
143        let b = [-1., -2., -3.];
144
145        assert_eq!(a.add(&b), [0., 0., 0.]);
146    }
147
148    #[test]
149    fn vec3_sub() {
150        let a = [1., 2., 3.];
151        let b = [1., 2., 3.];
152
153        assert_eq!(a.sub(&b), [0., 0., 0.]);
154    }
155
156    #[test]
157    fn vec3_mul() {
158        let a = [1., 2., 3.];
159        let b = [2., 3., 4.];
160
161        assert_eq!(a.mul(&b), [2., 6., 12.]);
162    }
163
164    #[test]
165    fn vec3_scale() {
166        let a = [1., 2., 3.];
167
168        assert_eq!(a.scale(3.), [3., 6., 9.]);
169    }
170
171    #[test]
172    fn vec3_dot() {
173        let a = [1., 2., 3.];
174        let b = [2., 3., 4.];
175
176        assert_eq!(a.dot(&b), 2. + 6. + 12.);
177    }
178    #[test]
179    fn vec3_mag() {
180        let b = [2., 3., 4.];
181        assert!(almost_eq(&[b.mag()], &[5.385164807]));
182    }
183    #[test]
184    fn vec3_mag2() {
185        let b = [2., 3., 4.];
186        assert!(almost_eq(&[b.mag2()], &[29.]));
187    }
188}