1use std::fmt::Debug;
3use std::hash::Hash;
4use std::ops::{Add, Sub};
5
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Serialize, Deserialize)]
10pub struct Point2d<T: Copy + PartialOrd + PartialEq + Debug + Add + Sub> {
11 pub x: T,
13
14 pub y: T,
16}
17
18impl Hash for Point2d<f64> {
19 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
20 let xbits = if self.x.is_nan() {
21 f64::NAN.to_bits()
22 } else {
23 self.x.to_bits()
24 };
25 let ybits = if self.y.is_nan() {
26 f64::NAN.to_bits()
27 } else {
28 self.y.to_bits()
29 };
30 xbits.hash(state);
31 ybits.hash(state);
32 }
33}
34
35#[derive(
37 Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Hash, Serialize, Deserialize,
38)]
39pub struct Point3d<T: Copy + PartialOrd + PartialEq + Debug + Add + Sub> {
40 pub x: T,
42
43 pub y: T,
45
46 pub z: T,
48}
49
50impl<T: Copy + PartialOrd + PartialEq + Debug + Add + Sub> Point2d<T> {
51 pub const fn new(x: T, y: T) -> Self {
53 Self { x, y }
54 }
55
56 pub const fn x(&self) -> T {
58 self.x
59 }
60
61 pub const fn y(&self) -> T {
63 self.y
64 }
65}
66
67impl<T: Copy + PartialOrd + PartialEq + Debug + Add + Sub> Point3d<T> {
68 pub const fn new(x: T, y: T, z: T) -> Self {
70 Self { x, y, z }
71 }
72
73 pub const fn x(&self) -> T {
75 self.x
76 }
77
78 pub const fn y(&self) -> T {
80 self.y
81 }
82
83 pub const fn z(&self) -> T {
85 self.z
86 }
87}