1use {
4 std::{fmt, ops},
5 crate::math_f32::*,
6 };
9
10
11pub struct PrettyPrintedF64(pub f64);
12
13impl fmt::Display for PrettyPrintedF64 {
14 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
15 if self.0.abs().fract() < 0.00000001 {
16 write!(f, "{}.0", self.0)
17 } else {
18 write!(f, "{}", self.0)
19 }
20 }
21}
22
23
24#[derive(Clone, Copy, Default, Debug, PartialEq)]
25pub struct Rect {
26 pub pos: DVec2,
27 pub size: DVec2,
28}
29
30impl Rect {
31
32 pub fn translate(self, pos: DVec2) -> Rect {
33 Rect {pos: self.pos + pos, size: self.size}
34 }
35
36 pub fn contains(&self, pos: DVec2) -> bool {
37 pos.x >= self.pos.x && pos.x <= self.pos.x + self.size.x &&
38 pos.y >= self.pos.y && pos.y <= self.pos.y + self.size.y
39 }
40
41 pub fn center(&self) -> DVec2 {
42 DVec2 {
43 x: self.pos.x + self.size.x * 0.5,
44 y: self.pos.y + self.size.y * 0.5,
45 }
46 }
47
48 pub fn scale_and_shift(&self, center: DVec2, scale: f64, shift: DVec2) -> Rect {
49 Rect {
50 pos: (self.pos - center) * scale + center + shift,
51 size: self.size * scale
52 }
53 }
54
55 pub fn inside(&self, r:Rect) -> bool {
56 if self.pos.x >= r.pos.x &&
57 self.pos.y >= r.pos.y &&
58 self.pos.x + self.size.x <= r.pos.x + r.size.x &&
59 self.pos.y + self.size.y <= r.pos.y + r.size.y
60 {
61 return true;
62 }
63 return false;
64 }
65
66 pub fn intersects(&self, r: Rect) -> bool {
67 r.pos.x < self.pos.x + self.size.x &&
68 r.pos.x + r.size.x > self.pos.x &&
69 r.pos.y < self.pos.y + self.size.y &&
70 r.pos.y + r.size.y > self.pos. y
71 }
72
73 pub fn add_margin(self, size: DVec2) -> Rect {
74 Rect {pos: self.pos - size, size: self.size + 2.0 * size}
75 }
76
77 pub fn contain(&self, other: Rect) -> Rect {
78 let mut pos = other.pos;
79 if pos.x < self.pos.x{ pos.x = self.pos.x };
80 if pos.y < self.pos.y{ pos.y = self.pos.y };
81 if pos.x + other.size.x > self.pos.x + self.size.x{
82 pos.x = self.pos.x + self.size.x - other.size.x
83 }
84 if pos.y + other.size.y > self.pos.y+ self.size.y{
85 pos.y = self.pos.y + self.size.y - other.size.y
86 }
87 Rect{
88 pos,
89 size:other.size
90 }
91 }
92
93 pub fn hull(&self, other: Rect) -> Rect {
94 let otherpos = other.pos;
95 let otherfarside = other.pos + other.size;
96 let farside = self.pos + self.size;
97 let mut finalpos = self.pos;
98 let mut finalfarside = farside;
99 if otherpos.x < finalpos.x{ finalpos.x = otherpos.x };
100 if otherpos.y < finalpos.y{ finalpos.y = otherpos.y };
101
102 if otherfarside.x > finalfarside.x{ finalfarside.x = otherfarside.x };
103 if otherfarside.y > finalfarside.y{ finalfarside.y = otherfarside.y };
104 let finalsize = finalfarside - finalpos;
105 Rect{
106 pos: finalpos,
107 size: finalsize
108 }
109 }
110
111 pub fn clip(&self, clip: (DVec2, DVec2)) -> Rect {
112 let mut x1 = self.pos.x;
113 let mut y1 = self.pos.y;
114 let mut x2 = x1 + self.size.x;
115 let mut y2 = y1 + self.size.y;
116 x1 = x1.max(clip.0.x).min(clip.1.x);
117 y1 = y1.max(clip.0.y).min(clip.1.y);
118 x2 = x2.max(clip.0.x).min(clip.1.x);
119 y2 = y2.max(clip.0.y).min(clip.1.y);
120 Rect {pos: dvec2(x1, y1), size: dvec2(x2 - x1, y2 - y1)}
121 }
122
123 pub fn from_lerp(a: Rect, b: Rect, f: f64) -> Rect {
124 Rect {
125 pos: (b.pos - a.pos) * f + a.pos,
126 size: (b.size - a.size) * f + a.size
127 }
128 }
129
130 pub fn dpi_snap(&self, f:f64)->Rect{
131 Rect{
132 pos: dvec2((self.pos.x / f).floor() * f,(self.pos.y / f).floor() * f),
133 size: dvec2((self.size.x / f).floor() * f,(self.size.y / f).floor() * f),
134 }
135 }
136
137 pub fn grow(&mut self, amt:f64){
138 self.pos.x = self.pos.x - amt;
139 self.pos.y = self.pos.y - amt;
140 self.size.x = self.size.x + amt * 2.;
141 self.size.y = self.size.y + amt * 2.;
142 }
143
144 pub fn clip_y_between(&mut self, y1: f64, y2: f64)
145 {
146 if self.pos.y < y1
147 {
148 let diff = y1 - self.pos.y;
149 self.pos.y = y1;
150 self.size.y = self.size.y - diff;
151 }
152
153 if (self.pos.y + self.size.y) > y2
154 {
155 let diff = y2 - (self.pos.y + self.size.y);
156 self.size.y = self.size.y + diff;
157 }
158 }
159
160 pub fn clip_x_between(&mut self, x1: f64, x2: f64)
161 {
162 if self.pos.x < x1
163 {
164 let diff = x1 - self.pos.x;
165 self.pos.x = x1;
166 self.size.x = self.size.x - diff;
167 }
168
169 if (self.pos.x + self.size.x) > x2
170 {
171 let diff = x2 - (self.pos.x + self.size.x);
172 self.size.x = self.size.x + diff;
173 }
174 }
175
176
177 pub fn is_nan(&self)->bool{
178 self.pos.is_nan() || self.size.is_nan()
179 }
180
181}
182
183#[derive(Clone, Copy, Default, Debug, PartialEq)]
184pub struct DVec4 {
185 pub x: f64,
186 pub y: f64,
187 pub z: f64,
188 pub w: f64,
189}
190
191
192#[derive(Clone, Copy, Default, Debug, PartialEq)]
193pub struct DVec3 {
194 pub x: f64,
195 pub y: f64,
196 pub z: f64,
197}
198
199
200#[derive(Clone, Copy, Default, Debug, PartialEq)]
201pub struct DVec2 {
202 pub x: f64,
203 pub y: f64,
204}
205
206impl std::convert::From<Vec2> for DVec2 {
207 fn from(other: Vec2) -> DVec2 {DVec2 {x: other.x as f64, y: other.y as f64}}
208}
209
210impl std::convert::From<DVec2> for Vec2 {
211 fn from(other: DVec2) -> Vec2 {Vec2 {x: other.x as f32, y: other.y as f32}}
212}
213
214impl std::convert::From<(DVec2, DVec2)> for Rect {
215 fn from(o: (DVec2, DVec2)) -> Rect {Rect {pos: dvec2(o.0.x, o.0.y), size: dvec2(o.1.x - o.0.x, o.1.y - o.0.y)}}
216}
217
218impl DVec2 {
219 pub const fn new() -> DVec2 {
220 DVec2 {x: 0.0, y: 0.0}
221 }
222
223 pub fn zero(&mut self) {
224 self.x = 0.;
225 self.y = 0.;
226
227 }
228
229 pub fn dpi_snap(&self, f:f64)->DVec2{
230 DVec2{
231 x:(self.x * f).round() / f,
232 y:(self.y * f).round() / f
233 }
234 }
235
236 pub const fn all(x: f64) -> DVec2 {
237 DVec2 {x, y: x}
238 }
239
240 pub const fn index(&self, index:Vec2Index)->f64{
241 match index{
242 Vec2Index::X=>self.x,
243 Vec2Index::Y=>self.y
244 }
245 }
246
247 pub fn set_index(&mut self, index:Vec2Index, v: f64){
248 match index{
249 Vec2Index::X=>{self.x = v},
250 Vec2Index::Y=>{self.y = v}
251 }
252 }
253
254 pub const fn from_index_pair(index:Vec2Index, a: f64, b:f64)->Self{
255 match index{
256 Vec2Index::X=>{Self{x:a,y:b}},
257 Vec2Index::Y=>{Self{x:b,y:a}}
258 }
259 }
260
261 pub const fn into_vec2(self) -> Vec2 {
262 Vec2 {x: self.x as f32, y: self.y as f32}
263 }
264
265 pub fn from_lerp(a: DVec2, b: DVec2, f: f64) -> DVec2 {
266 let nf = 1.0 - f;
267 DVec2 {
268 x: nf * a.x + f * b.x,
269 y: nf * a.y + f * b.y,
270 }
271 }
272
273 pub fn floor(self) -> DVec2 {
274 DVec2 {
275 x: self.x.floor(),
276 y: self.y.floor(),
277 }
278 }
279
280 pub fn ceil(self) -> DVec2 {
281 DVec2 {
282 x: self.x.ceil(),
283 y: self.y.ceil(),
284 }
285 }
286
287 pub fn distance(&self, other: &DVec2) -> f64 {
288 let dx = self.x - other.x;
289 let dy = self.y - other.y;
290 (dx * dx + dy * dy).sqrt()
291 }
292
293 pub fn angle_in_radians(&self) -> f64 {
294 self.y.atan2(self.x)
295 }
296 pub fn swapxy(&self) -> DVec2{
297 dvec2(self.y,self.x)
298 }
299 pub fn angle_in_degrees(&self) -> f64 {
300 self.y.atan2(self.x) * (360.0 / (2.* std::f64::consts::PI))
301 }
302
303 pub fn length(&self) -> f64 {
304 (self.x * self.x + self.y * self.y).sqrt()
305 }
306 pub fn normalize(&self) -> DVec2
307 {
308 let l = self.length();
309 if l == 0.0 {return dvec2(0.,0.);}
310 return dvec2(self.x/l, self.y/l);
311 }
312
313 pub fn clockwise_tangent(&self) -> DVec2
314 {
315 return dvec2(-self.y, self.x)
316 }
317
318 pub fn counterclockwise_tangent(&self) -> DVec2
319 {
320 return dvec2(self.y, -self.x)
321 }
322
323 pub fn normalize_to_x(&self) -> DVec2
324 {
325 let l = self.x;
326 if l == 0.0 {return dvec2(1.,0.);}
327 return dvec2(1., self.y/l);
328 }
329 pub fn normalize_to_y(&self) -> DVec2
330 {
331 let l = self.y;
332 if l == 0.0 {return dvec2(1.,0.);}
333 return dvec2(self.x/l, 1.);
334 }
335
336 pub fn lengthsquared(&self) -> f64 {
337 self.x * self.x + self.y * self.y
338 }
339
340 pub fn is_nan(&self)->bool{
341 self.x.is_nan() || self.y.is_nan()
342 }
343}
344
345impl fmt::Display for DVec2 {
346 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
348 write!(f, "vec2f64({},{})", self.x, self.y)
349 }
350}
351
352pub const fn dvec2(x: f64, y: f64) -> DVec2 {DVec2 {x, y}}
353
354pub const fn rect(x: f64, y: f64, w:f64, h:f64) -> Rect {Rect{pos:DVec2 {x, y}, size:DVec2{x:w, y:h}}}
355
356
357impl ops::Add<DVec2> for DVec2 {
360 type Output = DVec2;
361 fn add(self, rhs: DVec2) -> DVec2 {
362 DVec2 {x: self.x + rhs.x, y: self.y + rhs.y}
363 }
364}
365
366impl ops::Sub<DVec2> for DVec2 {
367 type Output = DVec2;
368 fn sub(self, rhs: DVec2) -> DVec2 {
369 DVec2 {x: self.x - rhs.x, y: self.y - rhs.y}
370 }
371}
372
373impl ops::Mul<DVec2> for DVec2 {
374 type Output = DVec2;
375 fn mul(self, rhs: DVec2) -> DVec2 {
376 DVec2 {x: self.x * rhs.x, y: self.y * rhs.y}
377 }
378}
379
380impl ops::Div<DVec2> for DVec2 {
381 type Output = DVec2;
382 fn div(self, rhs: DVec2) -> DVec2 {
383 DVec2 {x: self.x / rhs.x, y: self.y / rhs.y}
384 }
385}
386
387
388impl ops::Add<DVec2> for f64 {
389 type Output = DVec2;
390 fn add(self, rhs: DVec2) -> DVec2 {
391 DVec2 {x: self + rhs.x, y: self + rhs.y}
392 }
393}
394
395impl ops::Sub<DVec2> for f64 {
396 type Output = DVec2;
397 fn sub(self, rhs: DVec2) -> DVec2 {
398 DVec2 {x: self -rhs.x, y: self -rhs.y}
399 }
400}
401
402impl ops::Mul<DVec2> for f64 {
403 type Output = DVec2;
404 fn mul(self, rhs: DVec2) -> DVec2 {
405 DVec2 {x: self *rhs.x, y: self *rhs.y}
406 }
407}
408
409impl ops::Div<DVec2> for f64 {
410 type Output = DVec2;
411 fn div(self, rhs: DVec2) -> DVec2 {
412 DVec2 {x: self / rhs.x, y: self / rhs.y}
413 }
414}
415
416
417impl ops::Add<f64> for DVec2 {
418 type Output = DVec2;
419 fn add(self, rhs: f64) -> DVec2 {
420 DVec2 {x: self.x + rhs, y: self.y + rhs}
421 }
422}
423
424impl ops::Sub<f64> for DVec2 {
425 type Output = DVec2;
426 fn sub(self, rhs: f64) -> DVec2 {
427 DVec2 {x: self.x - rhs, y: self.y - rhs}
428 }
429}
430
431impl ops::Mul<f64> for DVec2 {
432 type Output = DVec2;
433 fn mul(self, rhs: f64) -> DVec2 {
434 DVec2 {x: self.x * rhs, y: self.y * rhs}
435 }
436}
437
438impl ops::Div<f64> for DVec2 {
439 type Output = DVec2;
440 fn div(self, rhs: f64) -> DVec2 {
441 DVec2 {x: self.x / rhs, y: self.y / rhs}
442 }
443}
444
445impl ops::AddAssign<DVec2> for DVec2 {
446 fn add_assign(&mut self, rhs: DVec2) {
447 self.x = self.x + rhs.x;
448 self.y = self.y + rhs.y;
449 }
450}
451
452impl ops::SubAssign<DVec2> for DVec2 {
453 fn sub_assign(&mut self, rhs: DVec2) {
454 self.x = self.x - rhs.x;
455 self.y = self.y - rhs.y;
456 }
457}
458
459impl ops::MulAssign<DVec2> for DVec2 {
460 fn mul_assign(&mut self, rhs: DVec2) {
461 self.x = self.x * rhs.x;
462 self.y = self.y * rhs.y;
463 }
464}
465
466impl ops::DivAssign<DVec2> for DVec2 {
467 fn div_assign(&mut self, rhs: DVec2) {
468 self.x = self.x / rhs.x;
469 self.y = self.y / rhs.y;
470 }
471}
472
473
474impl ops::AddAssign<f64> for DVec2 {
475 fn add_assign(&mut self, rhs: f64) {
476 self.x = self.x + rhs;
477 self.y = self.y + rhs;
478 }
479}
480
481impl ops::SubAssign<f64> for DVec2 {
482 fn sub_assign(&mut self, rhs: f64) {
483 self.x = self.x - rhs;
484 self.y = self.y - rhs;
485 }
486}
487
488impl ops::MulAssign<f64> for DVec2 {
489 fn mul_assign(&mut self, rhs: f64) {
490 self.x = self.x * rhs;
491 self.y = self.y * rhs;
492 }
493}
494
495impl ops::DivAssign<f64> for DVec2 {
496 fn div_assign(&mut self, rhs: f64) {
497 self.x = self.x / rhs;
498 self.y = self.y / rhs;
499 }
500}
501
502impl ops::Neg for DVec2 {
503 type Output = DVec2;
504 fn neg(self) -> Self {DVec2 {x: -self.x, y: -self.y}}
505}