siege_math/vector/
point.rs

1
2use std::ops::{Deref, Sub, Add, Neg};
3use float_cmp::{Ulps, ApproxEq};
4use super::{Vec2, Vec3, Vec4};
5use FullFloat;
6
7/// Point vector in 2-dimensions
8#[repr(C)]
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10#[derive(Serialize, Deserialize)]
11pub struct Point2<F>(pub Vec2<F>);
12
13/// Point vector in 3-dimensions
14#[repr(C)]
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16#[derive(Serialize, Deserialize)]
17pub struct Point3<F>(pub Vec3<F>);
18
19
20impl<F: FullFloat> Point2<F> {
21    #[inline]
22    pub fn new(x: F, y: F) -> Point2<F> {
23        Point2(Vec2::new(x,y))
24    }
25}
26
27impl<F: FullFloat> Point3<F> {
28    #[inline]
29    pub fn new(x: F, y: F, z: F) -> Point3<F> {
30        Point3(Vec3::new(x,y,z))
31    }
32}
33
34// ----------------------------------------------------------------------------
35
36impl<F: FullFloat> Deref for Point2<F> {
37    type Target = Vec2<F>;
38
39    fn deref(&self) -> &Vec2<F>
40    {
41        &self.0
42    }
43}
44
45impl<F: FullFloat> Deref for Point3<F> {
46    type Target = Vec3<F>;
47
48    fn deref(&self) -> &Vec3<F>
49    {
50        &self.0
51    }
52}
53
54// ----------------------------------------------------------------------------
55
56impl<F: FullFloat> From<Point2<F>> for Vec2<F> {
57    fn from(v: Point2<F>) -> Vec2<F> {
58        v.0
59    }
60}
61impl<F: FullFloat> From<Point3<F>> for Vec3<F> {
62    fn from(v: Point3<F>) -> Vec3<F> {
63        v.0
64    }
65}
66impl<F: FullFloat> From<Point3<F>> for Vec4<F> {
67    fn from(v: Point3<F>) -> Vec4<F> {
68        Vec4::new(v.0.x, v.0.y, v.0.z, F::one())
69    }
70}
71impl<F: FullFloat> From<Vec2<F>> for Point2<F> {
72    fn from(v: Vec2<F>) -> Point2<F> {
73        Point2(v)
74    }
75}
76impl<F: FullFloat> From<Vec3<F>> for Point3<F> {
77    fn from(v: Vec3<F>) -> Point3<F> {
78        Point3(v)
79    }
80}
81impl<F: FullFloat> From<Vec4<F>> for Point3<F> {
82    fn from(v: Vec4<F>) -> Point3<F> {
83        Point3(From::from(v))
84    }
85}
86
87// ----------------------------------------------------------------------------
88
89impl<F: FullFloat> Point3<F> {
90    #[allow(dead_code)]
91    #[inline]
92    fn from_vec4(v: Vec4<F>) -> Option<Point3<F>> {
93        if v.w == F::zero() { return None; }
94        Some(Point3(Vec3::new(v.x/v.w, v.y/v.w, v.z/v.w)))
95    }
96}
97
98// ----------------------------------------------------------------------------
99
100impl<F: FullFloat> Add<Vec2<F>> for Point2<F> {
101    type Output = Point2<F>;
102
103    #[inline]
104    fn add(self, other: Vec2<F>) -> Point2<F> {
105        Point2(self.0 + other)
106    }
107}
108impl<F: FullFloat> Add<Vec3<F>> for Point3<F> {
109    type Output = Point3<F>;
110
111    #[inline]
112    fn add(self, other: Vec3<F>) -> Point3<F> {
113        Point3(self.0 + other)
114    }
115}
116
117// point - vector = point
118impl<F: FullFloat> Sub<Vec2<F>> for Point2<F> {
119    type Output = Point2<F>;
120
121    #[inline]
122    fn sub(self, other: Vec2<F>) -> Point2<F> {
123        Point2(self.0 - other)
124    }
125}
126impl<F: FullFloat> Sub<Vec3<F>> for Point3<F> {
127    type Output = Point3<F>;
128
129    #[inline]
130    fn sub(self, other: Vec3<F>) -> Point3<F> {
131        Point3(self.0 - other)
132    }
133}
134
135// point - point = vector
136impl<F: FullFloat> Sub<Point2<F>> for Point2<F> {
137    type Output = Vec2<F>;
138
139    #[inline]
140    fn sub(self, other: Point2<F>) -> Vec2<F> {
141        self.0 - other.0
142    }
143}
144impl<F: FullFloat> Sub<Point3<F>> for Point3<F> {
145    type Output = Vec3<F>;
146
147    #[inline]
148    fn sub(self, other: Point3<F>) -> Vec3<F> {
149        self.0 - other.0
150    }
151}
152
153// ----------------------------------------------------------------------------
154// Neg
155
156impl<F: FullFloat> Neg for Point3<F> {
157    type Output = Point3<F>;
158
159    #[inline]
160    fn neg(self) -> Point3<F> {
161        Point3(-self.0)
162    }
163}
164
165// ----------------------------------------------------------------------------
166// casting between float types
167
168impl From<Point2<f64>> for Point2<f32> {
169    fn from(p: Point2<f64>) -> Point2<f32> {
170        Point2(From::from(p.0))
171    }
172}
173
174impl From<Point2<f32>> for Point2<f64> {
175    fn from(p: Point2<f32>) -> Point2<f64> {
176        Point2(From::from(p.0))
177    }
178}
179
180impl From<Point3<f64>> for Point3<f32> {
181    fn from(p: Point3<f64>) -> Point3<f32> {
182        Point3(From::from(p.0))
183    }
184}
185
186impl From<Point3<f32>> for Point3<f64> {
187    fn from(p: Point3<f32>) -> Point3<f64> {
188        Point3(From::from(p.0))
189    }
190}
191
192// ----------------------------------------------------------------------------
193// ApproxEq
194
195impl<F: FullFloat> ApproxEq for Point2<F> {
196    type Flt = F;
197
198    fn approx_eq(&self, other: &Self,
199                 epsilon: <F as ApproxEq>::Flt,
200                 ulps: <<F as ApproxEq>::Flt as Ulps>::U) -> bool
201    {
202        self.0.approx_eq(&other.0, epsilon, ulps)
203    }
204}
205
206impl<F: FullFloat> ApproxEq for Point3<F> {
207    type Flt = F;
208
209    fn approx_eq(&self, other: &Self,
210                 epsilon: <F as ApproxEq>::Flt,
211                 ulps: <<F as ApproxEq>::Flt as Ulps>::U) -> bool
212    {
213        self.0.approx_eq(&other.0, epsilon, ulps)
214    }
215}