makepad_math/
math_f64.rs

1//use std::f64::consts::PI;
2
3use {
4    std::{fmt, ops},
5    crate::math_f32::*,
6    //    makepad_microserde::*,
7    //    crate::colorhex::*
8};
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    // This trait requires `fmt` with this exact signature.
347    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
357//------ Vec2 operators
358
359impl 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}