1use num_traits::{Bounded, Float, NumCast};
21use std::fmt;
22use std::mem;
23use std::ops::*;
24
25use structure::*;
26
27use approx;
28use num::{BaseFloat, BaseNum};
29use vector::{Vector1, Vector2, Vector3, Vector4};
30
31#[cfg(feature = "mint")]
32use mint;
33
34#[repr(C)]
38#[derive(PartialEq, Eq, Copy, Clone, Hash)]
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40pub struct Point1<S> {
41 pub x: S,
42}
43
44#[repr(C)]
48#[derive(PartialEq, Eq, Copy, Clone, Hash)]
49#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
50pub struct Point2<S> {
51 pub x: S,
52 pub y: S,
53}
54
55#[repr(C)]
59#[derive(PartialEq, Eq, Copy, Clone, Hash)]
60#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
61pub struct Point3<S> {
62 pub x: S,
63 pub y: S,
64 pub z: S,
65}
66
67impl<S: BaseNum> Point3<S> {
68 #[inline]
69 pub fn from_homogeneous(v: Vector4<S>) -> Point3<S> {
70 let e = v.truncate() * (S::one() / v.w);
71 Point3::new(e.x, e.y, e.z) }
73
74 #[inline]
75 pub fn to_homogeneous(self) -> Vector4<S> {
76 Vector4::new(self.x, self.y, self.z, S::one())
77 }
78}
79
80macro_rules! impl_point {
81 ($PointN:ident { $($field:ident),+ }, $VectorN:ident, $n:expr, $constructor:ident) => {
82 impl<S> $PointN<S> {
83 #[inline]
85 pub const fn new($($field: S),+) -> $PointN<S> {
86 $PointN { $($field: $field),+ }
87 }
88
89 #[inline]
92 pub fn map<U, F>(self, mut f: F) -> $PointN<U>
93 where F: FnMut(S) -> U
94 {
95 $PointN { $($field: f(self.$field)),+ }
96 }
97
98 #[inline]
102 pub fn zip<S2, S3, F>(self, p2: $PointN<S2>, mut f: F) -> $PointN<S3>
103 where F: FnMut(S, S2) -> S3
104 {
105 $PointN { $($field: f(self.$field, p2.$field)),+ }
106 }
107 }
108
109 #[inline]
111 pub const fn $constructor<S>($($field: S),+) -> $PointN<S> {
112 $PointN::new($($field),+)
113 }
114
115 impl<S: BaseNum> Array for $PointN<S> {
116 type Element = S;
117
118 #[inline]
119 fn len() -> usize {
120 $n
121 }
122
123 #[inline]
124 fn from_value(scalar: S) -> $PointN<S> {
125 $PointN { $($field: scalar),+ }
126 }
127
128 #[inline]
129 fn sum(self) -> S where S: Add<Output = S> {
130 fold_array!(add, { $(self.$field),+ })
131 }
132
133 #[inline]
134 fn product(self) -> S where S: Mul<Output = S> {
135 fold_array!(mul, { $(self.$field),+ })
136 }
137
138 fn is_finite(&self) -> bool where S: Float {
139 $(self.$field.is_finite())&&+
140 }
141 }
142
143 impl<S: NumCast + Copy> $PointN<S> {
144 #[inline]
146 pub fn cast<T: NumCast>(&self) -> Option<$PointN<T>> {
147 $(
148 let $field = match NumCast::from(self.$field) {
149 Some(field) => field,
150 None => return None
151 };
152 )+
153 Some($PointN { $($field),+ })
154 }
155 }
156
157 impl<S: BaseFloat> MetricSpace for $PointN<S> {
158 type Metric = S;
159
160 #[inline]
161 fn distance2(self, other: Self) -> S {
162 (other - self).magnitude2()
163 }
164 }
165
166 impl<S: BaseNum> EuclideanSpace for $PointN<S> {
167 type Scalar = S;
168 type Diff = $VectorN<S>;
169
170 #[inline]
171 fn origin() -> $PointN<S> {
172 $PointN { $($field: S::zero()),+ }
173 }
174
175 #[inline]
176 fn from_vec(v: $VectorN<S>) -> $PointN<S> {
177 $PointN::new($(v.$field),+)
178 }
179
180 #[inline]
181 fn to_vec(self) -> $VectorN<S> {
182 $VectorN::new($(self.$field),+)
183 }
184
185 #[inline]
186 fn dot(self, v: $VectorN<S>) -> S {
187 $VectorN::new($(self.$field * v.$field),+).sum()
188 }
189 }
190
191 impl<S: BaseFloat> approx::AbsDiffEq for $PointN<S> {
192 type Epsilon = S::Epsilon;
193
194 #[inline]
195 fn default_epsilon() -> S::Epsilon {
196 S::default_epsilon()
197 }
198
199 #[inline]
200 fn abs_diff_eq(&self, other: &Self, epsilon: S::Epsilon)
201 -> bool
202 {
203 $(S::abs_diff_eq(&self.$field, &other.$field, epsilon))&&+
204 }
205 }
206
207 impl<S: BaseFloat> approx::RelativeEq for $PointN<S> {
208 #[inline]
209 fn default_max_relative() -> S::Epsilon {
210 S::default_max_relative()
211 }
212
213 #[inline]
214 fn relative_eq(&self, other: &Self, epsilon: S::Epsilon, max_relative: S::Epsilon) -> bool {
215 $(S::relative_eq(&self.$field, &other.$field, epsilon, max_relative))&&+
216 }
217 }
218
219 impl<S: BaseFloat> approx::UlpsEq for $PointN<S> {
220 #[inline]
221 fn default_max_ulps() -> u32 {
222 S::default_max_ulps()
223 }
224
225 #[inline]
226 fn ulps_eq(&self, other: &Self, epsilon: S::Epsilon, max_ulps: u32) -> bool {
227 $(S::ulps_eq(&self.$field, &other.$field, epsilon, max_ulps))&&+
228 }
229 }
230
231 impl<S: Bounded> Bounded for $PointN<S> {
232 #[inline]
233 fn min_value() -> $PointN<S> {
234 $PointN { $($field: S::min_value()),+ }
235 }
236
237 #[inline]
238 fn max_value() -> $PointN<S> {
239 $PointN { $($field: S::max_value()),+ }
240 }
241 }
242
243 impl_operator!(<S: BaseNum> Add<$VectorN<S> > for $PointN<S> {
244 fn add(lhs, rhs) -> $PointN<S> { $PointN::new($(lhs.$field + rhs.$field),+) }
245 });
246 impl_operator!(<S: BaseNum> Sub<$VectorN<S>> for $PointN<S> {
247 fn sub(lhs, rhs) -> $PointN<S> { $PointN::new($(lhs.$field - rhs.$field),+) }
248 });
249 impl_assignment_operator!(<S: BaseNum> AddAssign<$VectorN<S> > for $PointN<S> {
250 fn add_assign(&mut self, vector) { $(self.$field += vector.$field);+ }
251 });
252 impl_assignment_operator!(<S: BaseNum> SubAssign<$VectorN<S>> for $PointN<S> {
253 fn sub_assign(&mut self, vector) { $(self.$field -= vector.$field);+ }
254 });
255
256 impl_operator!(<S: BaseNum> Sub<$PointN<S> > for $PointN<S> {
257 fn sub(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field - rhs.$field),+) }
258 });
259
260 impl_operator!(<S: BaseNum> Mul<S> for $PointN<S> {
261 fn mul(point, scalar) -> $PointN<S> { $PointN::new($(point.$field * scalar),+) }
262 });
263 impl_operator!(<S: BaseNum> Div<S> for $PointN<S> {
264 fn div(point, scalar) -> $PointN<S> { $PointN::new($(point.$field / scalar),+) }
265 });
266 impl_operator!(<S: BaseNum> Rem<S> for $PointN<S> {
267 fn rem(point, scalar) -> $PointN<S> { $PointN::new($(point.$field % scalar),+) }
268 });
269 impl_assignment_operator!(<S: BaseNum> MulAssign<S> for $PointN<S> {
270 fn mul_assign(&mut self, scalar) { $(self.$field *= scalar);+ }
271 });
272 impl_assignment_operator!(<S: BaseNum> DivAssign<S> for $PointN<S> {
273 fn div_assign(&mut self, scalar) { $(self.$field /= scalar);+ }
274 });
275 impl_assignment_operator!(<S: BaseNum> RemAssign<S> for $PointN<S> {
276 fn rem_assign(&mut self, scalar) { $(self.$field %= scalar);+ }
277 });
278
279 impl<S: BaseNum> ElementWise for $PointN<S> {
280 #[inline] fn add_element_wise(self, rhs: $PointN<S>) -> $PointN<S> { $PointN::new($(self.$field + rhs.$field),+) }
281 #[inline] fn sub_element_wise(self, rhs: $PointN<S>) -> $PointN<S> { $PointN::new($(self.$field - rhs.$field),+) }
282 #[inline] fn mul_element_wise(self, rhs: $PointN<S>) -> $PointN<S> { $PointN::new($(self.$field * rhs.$field),+) }
283 #[inline] fn div_element_wise(self, rhs: $PointN<S>) -> $PointN<S> { $PointN::new($(self.$field / rhs.$field),+) }
284 #[inline] fn rem_element_wise(self, rhs: $PointN<S>) -> $PointN<S> { $PointN::new($(self.$field % rhs.$field),+) }
285
286 #[inline] fn add_assign_element_wise(&mut self, rhs: $PointN<S>) { $(self.$field += rhs.$field);+ }
287 #[inline] fn sub_assign_element_wise(&mut self, rhs: $PointN<S>) { $(self.$field -= rhs.$field);+ }
288 #[inline] fn mul_assign_element_wise(&mut self, rhs: $PointN<S>) { $(self.$field *= rhs.$field);+ }
289 #[inline] fn div_assign_element_wise(&mut self, rhs: $PointN<S>) { $(self.$field /= rhs.$field);+ }
290 #[inline] fn rem_assign_element_wise(&mut self, rhs: $PointN<S>) { $(self.$field %= rhs.$field);+ }
291 }
292
293 impl<S: BaseNum> ElementWise<S> for $PointN<S> {
294 #[inline] fn add_element_wise(self, rhs: S) -> $PointN<S> { $PointN::new($(self.$field + rhs),+) }
295 #[inline] fn sub_element_wise(self, rhs: S) -> $PointN<S> { $PointN::new($(self.$field - rhs),+) }
296 #[inline] fn mul_element_wise(self, rhs: S) -> $PointN<S> { $PointN::new($(self.$field * rhs),+) }
297 #[inline] fn div_element_wise(self, rhs: S) -> $PointN<S> { $PointN::new($(self.$field / rhs),+) }
298 #[inline] fn rem_element_wise(self, rhs: S) -> $PointN<S> { $PointN::new($(self.$field % rhs),+) }
299
300 #[inline] fn add_assign_element_wise(&mut self, rhs: S) { $(self.$field += rhs);+ }
301 #[inline] fn sub_assign_element_wise(&mut self, rhs: S) { $(self.$field -= rhs);+ }
302 #[inline] fn mul_assign_element_wise(&mut self, rhs: S) { $(self.$field *= rhs);+ }
303 #[inline] fn div_assign_element_wise(&mut self, rhs: S) { $(self.$field /= rhs);+ }
304 #[inline] fn rem_assign_element_wise(&mut self, rhs: S) { $(self.$field %= rhs);+ }
305 }
306
307 impl_scalar_ops!($PointN<usize> { $($field),+ });
308 impl_scalar_ops!($PointN<u8> { $($field),+ });
309 impl_scalar_ops!($PointN<u16> { $($field),+ });
310 impl_scalar_ops!($PointN<u32> { $($field),+ });
311 impl_scalar_ops!($PointN<u64> { $($field),+ });
312 impl_scalar_ops!($PointN<isize> { $($field),+ });
313 impl_scalar_ops!($PointN<i8> { $($field),+ });
314 impl_scalar_ops!($PointN<i16> { $($field),+ });
315 impl_scalar_ops!($PointN<i32> { $($field),+ });
316 impl_scalar_ops!($PointN<i64> { $($field),+ });
317 impl_scalar_ops!($PointN<f32> { $($field),+ });
318 impl_scalar_ops!($PointN<f64> { $($field),+ });
319
320 impl_index_operators!($PointN<S>, $n, S, usize);
321 impl_index_operators!($PointN<S>, $n, [S], Range<usize>);
322 impl_index_operators!($PointN<S>, $n, [S], RangeTo<usize>);
323 impl_index_operators!($PointN<S>, $n, [S], RangeFrom<usize>);
324 impl_index_operators!($PointN<S>, $n, [S], RangeFull);
325 }
326}
327
328macro_rules! impl_scalar_ops {
329 ($PointN:ident<$S:ident> { $($field:ident),+ }) => {
330 impl_operator!(Mul<$PointN<$S>> for $S {
331 fn mul(scalar, point) -> $PointN<$S> { $PointN::new($(scalar * point.$field),+) }
332 });
333 impl_operator!(Div<$PointN<$S>> for $S {
334 fn div(scalar, point) -> $PointN<$S> { $PointN::new($(scalar / point.$field),+) }
335 });
336 impl_operator!(Rem<$PointN<$S>> for $S {
337 fn rem(scalar, point) -> $PointN<$S> { $PointN::new($(scalar % point.$field),+) }
338 });
339 };
340}
341
342impl_point!(Point1 { x }, Vector1, 1, point1);
343impl_point!(Point2 { x, y }, Vector2, 2, point2);
344impl_point!(Point3 { x, y, z }, Vector3, 3, point3);
345
346impl<S: Copy> Point1<S> {
347 impl_swizzle_functions!(Point1, Point2, Point3, S, x);
348}
349
350impl<S: Copy> Point2<S> {
351 impl_swizzle_functions!(Point1, Point2, Point3, S, xy);
352}
353
354impl<S: Copy> Point3<S> {
355 impl_swizzle_functions!(Point1, Point2, Point3, S, xyz);
356}
357
358impl_fixed_array_conversions!(Point1<S> { x: 0 }, 1);
359impl_fixed_array_conversions!(Point2<S> { x: 0, y: 1 }, 2);
360impl_fixed_array_conversions!(Point3<S> { x: 0, y: 1, z: 2 }, 3);
361
362impl_tuple_conversions!(Point1<S> { x }, (S,));
363impl_tuple_conversions!(Point2<S> { x, y }, (S, S));
364impl_tuple_conversions!(Point3<S> { x, y, z }, (S, S, S));
365
366#[cfg(feature = "mint")]
367impl_mint_conversions!(Point2 { x, y }, Point2);
368#[cfg(feature = "mint")]
369impl_mint_conversions!(Point3 { x, y, z }, Point3);
370
371impl<S: fmt::Debug> fmt::Debug for Point1<S> {
372 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
373 write!(f, "Point1 ")?;
374 <[S; 1] as fmt::Debug>::fmt(self.as_ref(), f)
375 }
376}
377
378impl<S: fmt::Debug> fmt::Debug for Point2<S> {
379 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
380 write!(f, "Point2 ")?;
381 <[S; 2] as fmt::Debug>::fmt(self.as_ref(), f)
382 }
383}
384
385impl<S: fmt::Debug> fmt::Debug for Point3<S> {
386 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
387 write!(f, "Point3 ")?;
388 <[S; 3] as fmt::Debug>::fmt(self.as_ref(), f)
389 }
390}
391
392#[cfg(test)]
393mod tests {
394 mod point2 {
395 use point::*;
396
397 const POINT2: Point2<i32> = Point2 { x: 1, y: 2 };
398
399 #[test]
400 fn test_index() {
401 assert_eq!(POINT2[0], POINT2.x);
402 assert_eq!(POINT2[1], POINT2.y);
403 }
404
405 #[test]
406 fn test_index_mut() {
407 let mut p = POINT2;
408 *&mut p[0] = 0;
409 assert_eq!(p, [0, 2].into());
410 }
411
412 #[test]
413 #[should_panic]
414 fn test_index_out_of_bounds() {
415 POINT2[2];
416 }
417
418 #[test]
419 fn test_index_range() {
420 assert_eq!(&POINT2[..0], &[]);
421 assert_eq!(&POINT2[..1], &[1]);
422 assert_eq!(POINT2[..0].len(), 0);
423 assert_eq!(POINT2[..1].len(), 1);
424 assert_eq!(&POINT2[2..], &[]);
425 assert_eq!(&POINT2[1..], &[2]);
426 assert_eq!(POINT2[2..].len(), 0);
427 assert_eq!(POINT2[1..].len(), 1);
428 assert_eq!(&POINT2[..], &[1, 2]);
429 assert_eq!(POINT2[..].len(), 2);
430 }
431
432 #[test]
433 fn test_into() {
434 let p = POINT2;
435 {
436 let p: [i32; 2] = p.into();
437 assert_eq!(p, [1, 2]);
438 }
439 {
440 let p: (i32, i32) = p.into();
441 assert_eq!(p, (1, 2));
442 }
443 }
444
445 #[test]
446 fn test_as_ref() {
447 let p = POINT2;
448 {
449 let p: &[i32; 2] = p.as_ref();
450 assert_eq!(p, &[1, 2]);
451 }
452 {
453 let p: &(i32, i32) = p.as_ref();
454 assert_eq!(p, &(1, 2));
455 }
456 }
457
458 #[test]
459 fn test_as_mut() {
460 let mut p = POINT2;
461 {
462 let p: &mut [i32; 2] = p.as_mut();
463 assert_eq!(p, &mut [1, 2]);
464 }
465 {
466 let p: &mut (i32, i32) = p.as_mut();
467 assert_eq!(p, &mut (1, 2));
468 }
469 }
470
471 #[test]
472 fn test_from() {
473 assert_eq!(Point2::from([1, 2]), POINT2);
474 {
475 let p = &[1, 2];
476 let p: &Point2<_> = From::from(p);
477 assert_eq!(p, &POINT2);
478 }
479 {
480 let p = &mut [1, 2];
481 let p: &mut Point2<_> = From::from(p);
482 assert_eq!(p, &POINT2);
483 }
484 assert_eq!(Point2::from((1, 2)), POINT2);
485 {
486 let p = &(1, 2);
487 let p: &Point2<_> = From::from(p);
488 assert_eq!(p, &POINT2);
489 }
490 {
491 let p = &mut (1, 2);
492 let p: &mut Point2<_> = From::from(p);
493 assert_eq!(p, &POINT2);
494 }
495 }
496
497 #[test]
498 fn test_zip() {
499 assert_eq!(
500 Point2::new(true, false),
501 Point2::new(-2, 1).zip(Point2::new(-1, -1), |a, b| a < b)
502 );
503 }
504 }
505
506 mod point3 {
507 use point::*;
508
509 const POINT3: Point3<i32> = Point3 { x: 1, y: 2, z: 3 };
510
511 #[test]
512 fn test_index() {
513 assert_eq!(POINT3[0], POINT3.x);
514 assert_eq!(POINT3[1], POINT3.y);
515 assert_eq!(POINT3[2], POINT3.z);
516 }
517
518 #[test]
519 fn test_index_mut() {
520 let mut p = POINT3;
521 *&mut p[1] = 0;
522 assert_eq!(p, [1, 0, 3].into());
523 }
524
525 #[test]
526 #[should_panic]
527 fn test_index_out_of_bounds() {
528 POINT3[3];
529 }
530
531 #[test]
532 fn test_index_range() {
533 assert_eq!(&POINT3[..1], &[1]);
534 assert_eq!(&POINT3[..2], &[1, 2]);
535 assert_eq!(POINT3[..1].len(), 1);
536 assert_eq!(POINT3[..2].len(), 2);
537 assert_eq!(&POINT3[2..], &[3]);
538 assert_eq!(&POINT3[1..], &[2, 3]);
539 assert_eq!(POINT3[2..].len(), 1);
540 assert_eq!(POINT3[1..].len(), 2);
541 assert_eq!(&POINT3[..], &[1, 2, 3]);
542 assert_eq!(POINT3[..].len(), 3);
543 }
544
545 #[test]
546 fn test_into() {
547 let p = POINT3;
548 {
549 let p: [i32; 3] = p.into();
550 assert_eq!(p, [1, 2, 3]);
551 }
552 {
553 let p: (i32, i32, i32) = p.into();
554 assert_eq!(p, (1, 2, 3));
555 }
556 }
557
558 #[test]
559 fn test_as_ref() {
560 let p = POINT3;
561 {
562 let p: &[i32; 3] = p.as_ref();
563 assert_eq!(p, &[1, 2, 3]);
564 }
565 {
566 let p: &(i32, i32, i32) = p.as_ref();
567 assert_eq!(p, &(1, 2, 3));
568 }
569 }
570
571 #[test]
572 fn test_as_mut() {
573 let mut p = POINT3;
574 {
575 let p: &mut [i32; 3] = p.as_mut();
576 assert_eq!(p, &mut [1, 2, 3]);
577 }
578 {
579 let p: &mut (i32, i32, i32) = p.as_mut();
580 assert_eq!(p, &mut (1, 2, 3));
581 }
582 }
583
584 #[test]
585 fn test_from() {
586 assert_eq!(Point3::from([1, 2, 3]), POINT3);
587 {
588 let p = &[1, 2, 3];
589 let p: &Point3<_> = From::from(p);
590 assert_eq!(p, &POINT3);
591 }
592 {
593 let p = &mut [1, 2, 3];
594 let p: &mut Point3<_> = From::from(p);
595 assert_eq!(p, &POINT3);
596 }
597 assert_eq!(Point3::from((1, 2, 3)), POINT3);
598 {
599 let p = &(1, 2, 3);
600 let p: &Point3<_> = From::from(p);
601 assert_eq!(p, &POINT3);
602 }
603 {
604 let p = &mut (1, 2, 3);
605 let p: &mut Point3<_> = From::from(p);
606 assert_eq!(p, &POINT3);
607 }
608 }
609
610 #[test]
611 fn test_zip() {
612 assert_eq!(
613 Point3::new(true, false, false),
614 Point3::new(-2, 1, 0).zip(Point3::new(-1, -1, -1), |a, b| a < b)
615 );
616 }
617 }
618}