1use crate::{coord, CoordNum, Point};
2
3#[derive(Eq, PartialEq, Clone, Copy, Hash, Default)]
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25pub struct Coord<T: CoordNum = f64> {
26 pub x: T,
27 pub y: T,
28}
29
30#[deprecated(note = "Renamed to `geo_types::Coord` (or `geo::Coord`)")]
31pub type Coordinate<T = f64> = Coord<T>;
32
33impl<T: CoordNum> From<(T, T)> for Coord<T> {
34 #[inline]
35 fn from(coords: (T, T)) -> Self {
36 coord! {
37 x: coords.0,
38 y: coords.1,
39 }
40 }
41}
42
43impl<T: CoordNum> From<[T; 2]> for Coord<T> {
44 #[inline]
45 fn from(coords: [T; 2]) -> Self {
46 coord! {
47 x: coords[0],
48 y: coords[1],
49 }
50 }
51}
52
53impl<T: CoordNum> From<Point<T>> for Coord<T> {
54 #[inline]
55 fn from(point: Point<T>) -> Self {
56 coord! {
57 x: point.x(),
58 y: point.y(),
59 }
60 }
61}
62
63impl<T: CoordNum> From<Coord<T>> for (T, T) {
64 #[inline]
65 fn from(coord: Coord<T>) -> Self {
66 (coord.x, coord.y)
67 }
68}
69
70impl<T: CoordNum> From<Coord<T>> for [T; 2] {
71 #[inline]
72 fn from(coord: Coord<T>) -> Self {
73 [coord.x, coord.y]
74 }
75}
76
77impl<T: CoordNum> Coord<T> {
78 #[inline]
95 pub fn x_y(&self) -> (T, T) {
96 (self.x, self.y)
97 }
98}
99
100use core::ops::{Add, Div, Mul, Neg, Sub};
101
102impl<T> Neg for Coord<T>
116where
117 T: CoordNum + Neg<Output = T>,
118{
119 type Output = Self;
120
121 #[inline]
122 fn neg(self) -> Self {
123 coord! {
124 x: -self.x,
125 y: -self.y,
126 }
127 }
128}
129
130impl<T: CoordNum> Add for Coord<T> {
145 type Output = Self;
146
147 #[inline]
148 fn add(self, rhs: Self) -> Self {
149 coord! {
150 x: self.x + rhs.x,
151 y: self.y + rhs.y,
152 }
153 }
154}
155
156impl<T: CoordNum> Sub for Coord<T> {
171 type Output = Self;
172
173 #[inline]
174 fn sub(self, rhs: Self) -> Self {
175 coord! {
176 x: self.x - rhs.x,
177 y: self.y - rhs.y,
178 }
179 }
180}
181
182impl<T: CoordNum> Mul<T> for Coord<T> {
196 type Output = Self;
197
198 #[inline]
199 fn mul(self, rhs: T) -> Self {
200 coord! {
201 x: self.x * rhs,
202 y: self.y * rhs,
203 }
204 }
205}
206
207impl<T: CoordNum> Div<T> for Coord<T> {
221 type Output = Self;
222
223 #[inline]
224 fn div(self, rhs: T) -> Self {
225 coord! {
226 x: self.x / rhs,
227 y: self.y / rhs,
228 }
229 }
230}
231
232use num_traits::Zero;
233impl<T: CoordNum> Coord<T> {
247 #[inline]
248 pub fn zero() -> Self {
249 coord! {
250 x: T::zero(),
251 y: T::zero(),
252 }
253 }
254}
255
256impl<T: CoordNum> Zero for Coord<T> {
257 #[inline]
258 fn zero() -> Self {
259 Self::zero()
260 }
261 #[inline]
262 fn is_zero(&self) -> bool {
263 self.x.is_zero() && self.y.is_zero()
264 }
265}
266
267#[cfg(any(feature = "approx", test))]
268mod approx_integration {
269 use super::*;
270 use approx::{AbsDiffEq, RelativeEq, UlpsEq};
271
272 impl<T> AbsDiffEq for Coord<T>
273 where
274 T: CoordNum + AbsDiffEq<Epsilon = T>,
275 {
276 type Epsilon = T::Epsilon;
277
278 #[inline]
279 fn default_epsilon() -> T::Epsilon {
280 T::default_epsilon()
281 }
282
283 #[inline]
284 fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
285 T::abs_diff_eq(&self.x, &other.x, epsilon) && T::abs_diff_eq(&self.y, &other.y, epsilon)
286 }
287 }
288
289 impl<T> RelativeEq for Coord<T>
290 where
291 T: CoordNum + RelativeEq<Epsilon = T>,
292 {
293 #[inline]
294 fn default_max_relative() -> T::Epsilon {
295 T::default_max_relative()
296 }
297
298 #[inline]
299 fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
300 T::relative_eq(&self.x, &other.x, epsilon, max_relative)
301 && T::relative_eq(&self.y, &other.y, epsilon, max_relative)
302 }
303 }
304
305 impl<T> UlpsEq for Coord<T>
306 where
307 T: CoordNum + UlpsEq<Epsilon = T>,
308 {
309 #[inline]
310 fn default_max_ulps() -> u32 {
311 T::default_max_ulps()
312 }
313
314 #[inline]
315 fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
316 T::ulps_eq(&self.x, &other.x, epsilon, max_ulps)
317 && T::ulps_eq(&self.y, &other.y, epsilon, max_ulps)
318 }
319 }
320}
321
322#[cfg(feature = "rstar_0_8")]
323impl<T> ::rstar_0_8::Point for Coord<T>
324where
325 T: ::num_traits::Float + ::rstar_0_8::RTreeNum,
326{
327 type Scalar = T;
328
329 const DIMENSIONS: usize = 2;
330
331 #[inline]
332 fn generate(generator: impl Fn(usize) -> Self::Scalar) -> Self {
333 coord! {
334 x: generator(0),
335 y: generator(1),
336 }
337 }
338
339 #[inline]
340 fn nth(&self, index: usize) -> Self::Scalar {
341 match index {
342 0 => self.x,
343 1 => self.y,
344 _ => unreachable!(),
345 }
346 }
347
348 #[inline]
349 fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
350 match index {
351 0 => &mut self.x,
352 1 => &mut self.y,
353 _ => unreachable!(),
354 }
355 }
356}
357
358#[cfg(feature = "rstar_0_9")]
359impl<T> ::rstar_0_9::Point for Coord<T>
360where
361 T: ::num_traits::Float + ::rstar_0_9::RTreeNum,
362{
363 type Scalar = T;
364
365 const DIMENSIONS: usize = 2;
366
367 #[inline]
368 fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self {
369 coord! {
370 x: generator(0),
371 y: generator(1),
372 }
373 }
374
375 #[inline]
376 fn nth(&self, index: usize) -> Self::Scalar {
377 match index {
378 0 => self.x,
379 1 => self.y,
380 _ => unreachable!(),
381 }
382 }
383
384 #[inline]
385 fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
386 match index {
387 0 => &mut self.x,
388 1 => &mut self.y,
389 _ => unreachable!(),
390 }
391 }
392}
393
394#[cfg(feature = "rstar_0_10")]
395impl<T> ::rstar_0_10::Point for Coord<T>
396where
397 T: ::num_traits::Float + ::rstar_0_10::RTreeNum,
398{
399 type Scalar = T;
400
401 const DIMENSIONS: usize = 2;
402
403 #[inline]
404 fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self {
405 coord! {
406 x: generator(0),
407 y: generator(1),
408 }
409 }
410
411 #[inline]
412 fn nth(&self, index: usize) -> Self::Scalar {
413 match index {
414 0 => self.x,
415 1 => self.y,
416 _ => unreachable!(),
417 }
418 }
419
420 #[inline]
421 fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
422 match index {
423 0 => &mut self.x,
424 1 => &mut self.y,
425 _ => unreachable!(),
426 }
427 }
428}
429
430#[cfg(feature = "rstar_0_11")]
431impl<T> ::rstar_0_11::Point for Coord<T>
432where
433 T: ::num_traits::Float + ::rstar_0_11::RTreeNum,
434{
435 type Scalar = T;
436
437 const DIMENSIONS: usize = 2;
438
439 #[inline]
440 fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self {
441 coord! {
442 x: generator(0),
443 y: generator(1),
444 }
445 }
446
447 #[inline]
448 fn nth(&self, index: usize) -> Self::Scalar {
449 match index {
450 0 => self.x,
451 1 => self.y,
452 _ => unreachable!(),
453 }
454 }
455
456 #[inline]
457 fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
458 match index {
459 0 => &mut self.x,
460 1 => &mut self.y,
461 _ => unreachable!(),
462 }
463 }
464}
465
466#[cfg(feature = "rstar_0_12")]
467impl<T> ::rstar_0_12::Point for Coord<T>
468where
469 T: ::num_traits::Float + ::rstar_0_12::RTreeNum,
470{
471 type Scalar = T;
472
473 const DIMENSIONS: usize = 2;
474
475 #[inline]
476 fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self {
477 coord! {
478 x: generator(0),
479 y: generator(1),
480 }
481 }
482
483 #[inline]
484 fn nth(&self, index: usize) -> Self::Scalar {
485 match index {
486 0 => self.x,
487 1 => self.y,
488 _ => unreachable!(),
489 }
490 }
491
492 #[inline]
493 fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
494 match index {
495 0 => &mut self.x,
496 1 => &mut self.y,
497 _ => unreachable!(),
498 }
499 }
500}
501
502impl<T: CoordNum> AsRef<Coord<T>> for Coord<T> {
503 fn as_ref(&self) -> &Coord<T> {
504 self
505 }
506}