cgmath/
point.rs

1// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
2// refer to the Cargo.toml file at the top-level directory of this distribution.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Points are fixed positions in affine space with no length or direction. This
17//! distinguishes them from vectors, which have a length and direction, but do
18//! not have a fixed position.
19
20use 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/// A point in 1-dimensional space.
35///
36/// This type is marked as `#[repr(C)]`.
37#[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/// A point in 2-dimensional space.
45///
46/// This type is marked as `#[repr(C)]`.
47#[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/// A point in 3-dimensional space.
56///
57/// This type is marked as `#[repr(C)]`.
58#[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) //FIXME
72    }
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            /// Construct a new point, using the provided values.
84            #[inline]
85            pub const fn new($($field: S),+) -> $PointN<S> {
86                $PointN { $($field: $field),+ }
87            }
88
89            /// Perform the given operation on each field in the point, returning a new point
90            /// constructed from the operations.
91            #[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            /// Construct a new point where each component is the result of
99            /// applying the given operation to each pair of components of the
100            /// given points.
101            #[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        /// The short constructor.
110        #[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            /// Component-wise casting to another type
145            #[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}