1
2
3pub mod point;
4pub use self::point::{Point2, Point3};
5
6pub mod direction;
7pub use self::direction::{Direction2, Direction3,
8 X_AXIS_F32, Y_AXIS_F32, Z_AXIS_F32,
9 X_AXIS_F64, Y_AXIS_F64, Z_AXIS_F64};
10
11use std::ops::{Index, IndexMut, Mul, MulAssign, Div, DivAssign, Neg,
12 Add, AddAssign, Sub, SubAssign};
13use std::default::Default;
14use num_traits::NumCast;
15use float_cmp::{Ulps, ApproxEq};
16use FullFloat;
17
18#[repr(C)]
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21#[derive(Serialize, Deserialize)]
22pub struct Vec2<F> {
23 pub x: F,
24 pub y: F,
25}
26
27#[repr(C)]
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
30#[derive(Serialize, Deserialize)]
31pub struct Vec3<F> {
32 pub x: F,
33 pub y: F,
34 pub z: F,
35}
36
37#[repr(C)]
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
40#[derive(Serialize, Deserialize)]
41pub struct Vec4<F> {
42 pub x: F,
43 pub y: F,
44 pub z: F,
45 pub w: F,
46}
47
48impl<F: FullFloat> Index<usize> for Vec2<F> {
51 type Output = F;
52
53 #[inline]
54 fn index(&self, i: usize) -> &F {
55 match i {
56 0 => &self.x,
57 1 => &self.y,
58 _ => panic!("Index out of bounds for Vec2"),
59 }
60 }
61}
62
63impl<F: FullFloat> Index<usize> for Vec3<F> {
64 type Output = F;
65
66 #[inline]
67 fn index(&self, i: usize) -> &F {
68 match i {
69 0 => &self.x,
70 1 => &self.y,
71 2 => &self.z,
72 _ => panic!("Index out of bounds for Vec3"),
73 }
74 }
75}
76
77impl<F: FullFloat> Index<usize> for Vec4<F> {
78 type Output = F;
79
80 #[inline]
81 fn index(&self, i: usize) -> &F {
82 match i {
83 0 => &self.x,
84 1 => &self.y,
85 2 => &self.z,
86 3 => &self.w,
87 _ => panic!("Index out of bounds for Vec4"),
88 }
89 }
90}
91
92impl<F: FullFloat> IndexMut<usize> for Vec2<F> {
93 #[inline]
94 fn index_mut(&mut self, i: usize) -> &mut F {
95 match i {
96 0 => &mut self.x,
97 1 => &mut self.y,
98 _ => panic!("Index out of bounds for Vec2"),
99 }
100 }
101}
102
103impl<F: FullFloat> IndexMut<usize> for Vec3<F> {
104 #[inline]
105 fn index_mut(&mut self, i: usize) -> &mut F {
106 match i {
107 0 => &mut self.x,
108 1 => &mut self.y,
109 2 => &mut self.z,
110 _ => panic!("Index out of bounds for Vec3"),
111 }
112 }
113}
114
115impl<F: FullFloat> IndexMut<usize> for Vec4<F> {
116 #[inline]
117 fn index_mut(&mut self, i: usize) -> &mut F {
118 match i {
119 0 => &mut self.x,
120 1 => &mut self.y,
121 2 => &mut self.z,
122 3 => &mut self.w,
123 _ => panic!("Index out of bounds for Vec4"),
124 }
125 }
126}
127
128impl<F: FullFloat> Vec3<F> {
131 #[inline]
132 pub fn truncate_n(&self, n: usize) -> Vec2<F> {
133 match n {
134 0 => Vec2::new(self.y, self.z),
135 1 => Vec2::new(self.x, self.z),
136 2 => Vec2::new(self.x, self.y),
137 _ => panic!("Index out of bounds for Vec3"),
138 }
139 }
140}
141
142impl<F: FullFloat> Vec3<F> {
143 #[inline]
144 pub fn truncate_x(&self) -> Vec2<F> {
145 Vec2::new(self.y, self.z)
146 }
147 #[inline]
148 pub fn truncate_y(&self) -> Vec2<F> {
149 Vec2::new(self.x, self.z)
150 }
151 #[inline]
152 pub fn truncate_z(&self) -> Vec2<F> {
153 Vec2::new(self.x, self.y)
154 }
155}
156
157impl<F: FullFloat> Vec4<F> {
158 #[inline]
159 pub fn truncate_n(&self, n: usize) -> Vec3<F> {
160 match n {
161 0 => Vec3::new(self.y, self.z, self.w),
162 1 => Vec3::new(self.x, self.z, self.w),
163 2 => Vec3::new(self.x, self.y, self.w),
164 3 => Vec3::new(self.x, self.y, self.z),
165 _ => panic!("Index out of bounds for Vec4"),
166 }
167 }
168}
169
170impl<F: FullFloat> Vec4<F> {
171 #[inline]
172 pub fn truncate_x(&self) -> Vec3<F> {
173 Vec3::new(self.y, self.z, self.w)
174 }
175 #[inline]
176 pub fn truncate_y(&self) -> Vec3<F> {
177 Vec3::new(self.x, self.z, self.w)
178 }
179 #[inline]
180 pub fn truncate_z(&self) -> Vec3<F> {
181 Vec3::new(self.x, self.y, self.w)
182 }
183 #[inline]
184 pub fn truncate_w(&self) -> Vec3<F> {
185 Vec3::new(self.x, self.y, self.z)
186 }
187}
188
189macro_rules! impl_vector {
192 ($VecN:ident { $first:ident, $($field:ident),* }) => {
193 impl<F: FullFloat> $VecN<F> {
194 #[inline]
196 pub fn new($first: F, $($field: F),*) -> $VecN<F> {
197 $VecN { $first: $first, $($field: $field),* }
198 }
199 }
200
201 impl<F: FullFloat> $VecN<F> {
202 #[inline]
203 pub fn zero() -> $VecN<F> {
204 $VecN { $first: F::zero(), $($field: F::zero()),* }
205 }
206 }
207
208 impl<F: FullFloat> Default for $VecN<F> {
209 #[inline]
210 fn default() -> $VecN<F> {
211 $VecN { $first: F::default(), $($field: F::default()),* }
212 }
213 }
214
215 impl<F: FullFloat> $VecN<F>{
216 #[inline]
217 pub fn squared_magnitude(&self) -> F {
218 self.$first * self.$first $(+ self.$field * self.$field)*
219 }
220 }
221
222 impl<F: FullFloat> $VecN<F> {
223 #[inline]
224 pub fn magnitude(&self) -> F {
225 self.squared_magnitude().sqrt()
226 }
230 }
231
232 impl<F: FullFloat> $VecN<F> {
233 pub fn is_normal(&self) -> bool {
234 self.magnitude().approx_eq(
235 &F::one(),
236 <F as NumCast>::from(10.0_f32).unwrap() * F::epsilon(),
237 NumCast::from(10_u32).unwrap()
238 )
239 }
240 }
241
242 impl<F: FullFloat> Mul<F> for $VecN<F> {
243 type Output = $VecN<F>;
244
245 #[inline]
246 fn mul(self, rhs: F) -> $VecN<F> {
247 $VecN {
248 $first: self.$first * rhs,
249 $($field: self.$field * rhs),*
250 }
251 }
252 }
253
254 impl<F: FullFloat> Mul<$VecN<F>> for $VecN<F> {
255 type Output = $VecN<F>;
256
257 #[inline]
258 fn mul(self, rhs: $VecN<F>) -> $VecN<F> {
259 $VecN {
260 $first: self.$first * rhs.$first,
261 $($field: self.$field * rhs.$field),*
262 }
263 }
264 }
265
266 impl<F: FullFloat> MulAssign<F> for $VecN<F> {
267 #[inline]
268 fn mul_assign(&mut self, rhs: F) {
269 self.$first *= rhs;
270 $(self.$field *= rhs);*
271 }
272 }
273
274 impl<F: FullFloat> Div<F> for $VecN<F> {
275 type Output = $VecN<F>;
276
277 #[inline]
278 fn div(self, rhs: F) -> $VecN<F> {
279 $VecN {
280 $first: self.$first / rhs,
281 $($field: self.$field / rhs),*
282 }
283 }
284 }
285
286 impl<F: FullFloat> DivAssign<F> for $VecN<F> {
287 #[inline]
288 fn div_assign(&mut self, rhs: F) {
289 self.$first /= rhs;
290 $(self.$field /= rhs);*
291 }
292 }
293
294 impl<F: FullFloat> Neg for $VecN<F> {
295 type Output = $VecN<F>;
296
297 #[inline]
298 fn neg(self) -> $VecN<F> {
299 $VecN {
300 $first: -self.$first,
301 $($field: -self.$field),*
302 }
303 }
304 }
305
306 impl<F: FullFloat> Add for $VecN<F> {
307 type Output = $VecN<F>;
308
309 #[inline]
310 fn add(self, other: $VecN<F>) -> $VecN<F> {
311 $VecN {
312 $first: self.$first + other.$first,
313 $($field: self.$field + other.$field),*
314 }
315 }
316 }
317
318 impl<F: FullFloat> AddAssign<$VecN<F>> for $VecN<F> {
319 #[inline]
320 fn add_assign(&mut self, other: $VecN<F>) {
321 self.$first += other.$first;
322 $(self.$field += other.$field);*
323 }
324 }
325
326 impl<F: FullFloat> Sub for $VecN<F> {
327 type Output = $VecN<F>;
328
329 #[inline]
330 fn sub(self, other: $VecN<F>) -> $VecN<F> {
331 $VecN {
332 $first: self.$first - other.$first,
333 $($field: self.$field - other.$field),*
334 }
335 }
336 }
337
338 impl<F: FullFloat> SubAssign<$VecN<F>> for $VecN<F> {
339 #[inline]
340 fn sub_assign(&mut self, other: $VecN<F>) {
341 self.$first -= other.$first;
342 $(self.$field -= other.$field);*
343 }
344 }
345
346 impl<F: FullFloat> $VecN<F> {
347 #[inline]
348 pub fn dot(&self, rhs: $VecN<F>) -> F {
349 self.$first * rhs.$first
350 $(+ self.$field * rhs.$field)*
351 }
352 }
353
354 impl<F: FullFloat> $VecN<F> {
355 #[inline]
356 pub fn project_onto(&self, axis: $VecN<F>) -> $VecN<F> {
357 axis * (self.dot(axis) / axis.dot(axis))
358 }
359 }
360
361 impl<F: FullFloat> $VecN<F>
362 {
363 #[inline]
364 pub fn reject_onto(&self, axis: $VecN<F>) -> $VecN<F> {
365 *self - self.project_onto(axis)
366 }
367 }
368
369 impl<F: FullFloat> $VecN<F>
370 {
371 #[inline]
372 pub fn exp(&self) -> $VecN<F> {
373 $VecN {
374 $first: self.$first.exp(),
375 $($field: self.$field.exp()),*
376 }
377 }
378 }
379 }
380}
381
382impl_vector!(Vec2 { x, y });
383impl_vector!(Vec3 { x, y, z });
384impl_vector!(Vec4 { x, y, z, w });
385
386impl<F: FullFloat> Vec3<F> {
389 #[inline]
390 pub fn cross(&self, rhs: Vec3<F>) -> Vec3<F> {
391 Vec3::new(
392 self.y*rhs.z - self.z*rhs.y,
393 self.z*rhs.x - self.x*rhs.z,
394 self.x*rhs.y - self.y*rhs.x
395 )
396 }
397}
398
399impl<F: FullFloat> Vec3<F> {
400 #[inline]
401 pub fn triple_product(&self, b: Vec3<F>, c: Vec3<F>) -> F {
402 self.cross(b).dot(c)
403 }
404}
405
406impl<F: FullFloat> From<Vec4<F>> for Vec3<F> {
410 fn from(v: Vec4<F>) -> Vec3<F> {
411 Vec3 { x: v.x, y: v.y, z: v.z }
412 }
413}
414
415impl<F: FullFloat> From<Vec3<F>> for Vec2<F> {
416 fn from(v: Vec3<F>) -> Vec2<F> {
417 Vec2 { x: v.x, y: v.y }
418 }
419}
420
421impl<F: FullFloat> Vec3<F> {
424 pub fn to_vec4(&self, w: F) -> Vec4<F> {
425 Vec4 { x: self.x, y: self.y, z: self.z, w: w }
426 }
427}
428
429impl From<Vec2<f64>> for Vec2<f32> {
458 fn from(v: Vec2<f64>) -> Vec2<f32> {
459 Vec2 { x: v.x as f32, y: v.y as f32 }
460 }
461}
462
463impl From<Vec2<f32>> for Vec2<f64> {
464 fn from(v: Vec2<f32>) -> Vec2<f64> {
465 Vec2 { x: v.x as f64, y: v.y as f64 }
466 }
467}
468
469impl From<Vec3<f64>> for Vec3<f32> {
470 fn from(v: Vec3<f64>) -> Vec3<f32> {
471 Vec3 { x: v.x as f32, y: v.y as f32, z: v.z as f32 }
472 }
473}
474
475impl From<Vec3<f32>> for Vec3<f64> {
476 fn from(v: Vec3<f32>) -> Vec3<f64> {
477 Vec3 { x: v.x as f64, y: v.y as f64, z: v.z as f64 }
478 }
479}
480
481impl From<Vec4<f64>> for Vec4<f32> {
482 fn from(v: Vec4<f64>) -> Vec4<f32> {
483 Vec4 { x: v.x as f32, y: v.y as f32, z: v.z as f32, w: v.w as f32 }
484 }
485}
486
487impl From<Vec4<f32>> for Vec4<f64> {
488 fn from(v: Vec4<f32>) -> Vec4<f64> {
489 Vec4 { x: v.x as f64, y: v.y as f64, z: v.z as f64, w: v.w as f64 }
490 }
491}
492
493impl<F: FullFloat> ApproxEq for Vec2<F> {
497 type Flt = F;
498
499 fn approx_eq(&self, other: &Self,
500 epsilon: <F as ApproxEq>::Flt,
501 ulps: <<F as ApproxEq>::Flt as Ulps>::U) -> bool
502 {
503 self.x.approx_eq(&other.x, epsilon, ulps)
504 && self.y.approx_eq(&other.y, epsilon, ulps)
505 }
506}
507
508impl<F: FullFloat> ApproxEq for Vec3<F> {
509 type Flt = F;
510
511 fn approx_eq(&self, other: &Self,
512 epsilon: <F as ApproxEq>::Flt,
513 ulps: <<F as ApproxEq>::Flt as Ulps>::U) -> bool
514 {
515 self.x.approx_eq(&other.x, epsilon, ulps)
516 && self.y.approx_eq(&other.y, epsilon, ulps)
517 && self.z.approx_eq(&other.z, epsilon, ulps)
518 }
519}
520
521impl<F: FullFloat> ApproxEq for Vec4<F> {
522 type Flt = F;
523
524 fn approx_eq(&self, other: &Self,
525 epsilon: <F as ApproxEq>::Flt,
526 ulps: <<F as ApproxEq>::Flt as Ulps>::U) -> bool
527 {
528 self.x.approx_eq(&other.x, epsilon, ulps)
529 && self.y.approx_eq(&other.y, epsilon, ulps)
530 && self.z.approx_eq(&other.z, epsilon, ulps)
531 && self.w.approx_eq(&other.w, epsilon, ulps)
532 }
533}
534
535#[cfg(test)]
538mod tests {
539 use float_cmp:: ApproxEq;
540 use super::Vec2;
541 const VEC2: Vec2<f32> = Vec2 { x: 1.0, y: 2.0 };
542
543 #[test]
544 fn test_new() {
545 assert_eq!(Vec2::new(1.0_f32, 2.0_f32), VEC2);
546 }
547
548 #[test]
549 fn test_zero() {
550 assert_eq!(Vec2::new(0.0_f32, 0.0_f32), Vec2::zero());
551 let z: Vec2<f32> = Vec2::zero();
552 assert_eq!(z[0], 0.0_f32);
553 assert_eq!(z[1], 0.0_f32);
554 }
555
556 #[test]
557 fn test_squared_magnitude() {
558 assert!(VEC2.squared_magnitude().approx_eq(&5.0, ::std::f32::EPSILON, 1));
559 }
560
561 #[test]
562 fn test_index() {
563 assert_eq!(VEC2[0], VEC2.x);
564 assert_eq!(VEC2[1], VEC2.y);
565 }
566
567 #[test]
568 fn test_index_mut() {
569 let mut v: Vec2<f32> = Vec2::new(3.0, 5.0);
570 v[1] = 6.0;
571 assert_eq!(v.y, 6.0);
572 }
573}