1use crate::rects::Rect2D;
6use core::cmp::Ordering;
7use core::ops::Add;
10use irox_bits::{FromBEBytes, ToBEBytes};
11
12pub trait Point2D {
14 type Output: Copy + Add;
15 fn get_x(&self) -> Self::Output;
16 fn get_y(&self) -> Self::Output;
17
18 #[must_use]
19 fn new(x: Self::Output, y: Self::Output) -> Self;
20
21 #[must_use]
22 fn new_f64(x: f64, y: f64) -> Double2D {
23 Double2D { x, y }
24 }
25 #[must_use]
26 fn new_f32(x: f32, y: f32) -> Float2D {
27 Float2D { x, y }
28 }
29}
30
31pub trait EncodablePoint2D<const N: usize>: Point2D {
32 fn encode(&self) -> [u8; N];
33 fn decode(value: [u8; N]) -> Self;
34}
35
36#[derive(Default, Debug, Copy, Clone, PartialEq)]
38pub struct Double2D {
39 pub x: f64,
40 pub y: f64,
41}
42impl Double2D {
43 #[must_use]
44 pub const fn new(x: f64, y: f64) -> Self {
45 Double2D { x, y }
46 }
47 #[must_use]
48 pub fn new_f64(x: f64, y: f64) -> Self {
49 Double2D { x, y }
50 }
51 #[must_use]
52 pub fn get_x(&self) -> f64 {
53 self.x
54 }
55 #[must_use]
56 pub fn get_y(&self) -> f64 {
57 self.y
58 }
59
60 #[must_use]
61 pub fn translate(&self, vec: &Vec2D) -> Double2D {
62 Self {
63 x: self.x + vec.x,
64 y: self.y + vec.y,
65 }
66 }
67
68 pub fn translate_mut(&mut self, vec: &Vec2D) {
69 self.x += vec.x;
70 self.y += vec.y;
71 }
72}
73impl From<[f64; 2]> for Double2D {
74 fn from(val: [f64; 2]) -> Double2D {
75 let [x, y] = val;
76 Double2D { x, y }
77 }
78}
79impl Eq for Double2D {}
80impl PartialOrd for Double2D {
81 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
82 Some(self.cmp(other))
83 }
84}
85impl Ord for Double2D {
86 fn cmp(&self, other: &Self) -> Ordering {
87 let x = self.x.total_cmp(&other.x);
88 if x != Ordering::Equal {
89 return x;
90 }
91 self.y.total_cmp(&other.y)
92 }
93}
94impl core::ops::Sub for Double2D {
95 type Output = Vec2D;
96
97 fn sub(self, rhs: Self) -> Self::Output {
98 let x = self.x - rhs.x;
99 let y = self.y - rhs.y;
100 Vec2D { x, y }
101 }
102}
103
104impl Point2D for Double2D {
105 type Output = f64;
106
107 fn get_x(&self) -> Self::Output {
108 self.x
109 }
110
111 fn get_y(&self) -> Self::Output {
112 self.y
113 }
114
115 fn new(x: Self::Output, y: Self::Output) -> Self {
116 Double2D { x, y }
117 }
118}
119impl EncodablePoint2D<16> for Double2D {
120 fn encode(&self) -> [u8; 16] {
121 [self.x, self.y].to_be_bytes()
122 }
123
124 fn decode(val: [u8; 16]) -> Self {
125 <[f64; 2]>::from_be_bytes(val).into()
126 }
127}
128
129#[derive(Default, Debug, Copy, Clone, PartialEq, PartialOrd)]
131pub struct Float2D {
132 pub x: f32,
133 pub y: f32,
134}
135impl From<[f32; 2]> for Float2D {
136 fn from(val: [f32; 2]) -> Float2D {
137 let [x, y] = val;
138 Float2D { x, y }
139 }
140}
141impl Point2D for Float2D {
142 type Output = f32;
143
144 fn get_x(&self) -> Self::Output {
145 self.x
146 }
147
148 fn get_y(&self) -> Self::Output {
149 self.y
150 }
151
152 fn new(x: Self::Output, y: Self::Output) -> Self {
153 Float2D { x, y }
154 }
155}
156impl EncodablePoint2D<8> for Float2D {
157 fn encode(&self) -> [u8; 8] {
158 [self.x, self.y].to_be_bytes()
159 }
160
161 fn decode(val: [u8; 8]) -> Self {
162 <[f32; 2]>::from_be_bytes(val).into()
163 }
164}
165
166#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
168pub struct Quad2D {
169 pub x: u64,
170 pub y: u64,
171}
172impl From<[u64; 2]> for Quad2D {
173 fn from(val: [u64; 2]) -> Quad2D {
174 let [x, y] = val;
175 Quad2D { x, y }
176 }
177}
178impl Point2D for Quad2D {
179 type Output = u64;
180
181 fn get_x(&self) -> Self::Output {
182 self.x
183 }
184
185 fn get_y(&self) -> Self::Output {
186 self.y
187 }
188
189 fn new(x: Self::Output, y: Self::Output) -> Self {
190 Quad2D { x, y }
191 }
192}
193impl EncodablePoint2D<16> for Quad2D {
194 fn encode(&self) -> [u8; 16] {
195 [self.x, self.y].to_be_bytes()
196 }
197
198 fn decode(val: [u8; 16]) -> Self {
199 <[u64; 2]>::from_be_bytes(val).into()
200 }
201}
202
203#[derive(Debug, Copy, Clone, PartialEq)]
204pub struct Vec2D {
205 pub x: f64,
206 pub y: f64,
207}
208impl Default for Vec2D {
209 fn default() -> Self {
210 Vec2D { x: 1.0, y: 1.0 }
211 }
212}
213impl Eq for Vec2D {}
214impl PartialOrd for Vec2D {
215 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
216 Some(self.cmp(other))
217 }
218}
219impl Ord for Vec2D {
220 fn cmp(&self, other: &Self) -> Ordering {
221 let x = self.x.total_cmp(&other.x);
222 if x != Ordering::Equal {
223 return x;
224 }
225 self.y.total_cmp(&other.y)
226 }
227}
228impl Vec2D {
229 #[must_use]
230 pub fn new(x: f64, y: f64) -> Self {
231 Vec2D { x, y }
232 }
233 #[must_use]
234 pub fn get_x(&self) -> f64 {
235 self.x
236 }
237 #[must_use]
238 pub fn get_y(&self) -> f64 {
239 self.y
240 }
241
242 #[must_use]
243 pub fn with_origin(&self, origin: Double2D) -> Rect2D {
244 Rect2D {
245 origin,
246 far_point: origin.translate(self),
247 }
248 }
249}
250#[cfg(feature = "emath")]
251impl From<emath::Vec2> for Vec2D {
252 fn from(pos: emath::Vec2) -> Self {
253 Self {
254 x: pos.x as f64,
255 y: pos.y as f64,
256 }
257 }
258}
259#[cfg(feature = "emath")]
260impl From<emath::Pos2> for Double2D {
261 fn from(pos: emath::Pos2) -> Self {
262 Self {
263 x: pos.x as f64,
264 y: pos.y as f64,
265 }
266 }
267}
268#[cfg(feature = "emath")]
269impl From<Double2D> for emath::Pos2 {
270 fn from(value: Double2D) -> Self {
271 Self {
272 x: value.x as f32,
273 y: value.y as f32,
274 }
275 }
276}