makepad_math/
math_f64.rs

1use {
2    std::{fmt, ops},
3    crate::math_f32::*,
4    //    makepad_microserde::*,
5    //    crate::colorhex::*
6};
7
8
9pub struct PrettyPrintedF64(pub f64);
10
11impl fmt::Display for PrettyPrintedF64 {
12    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
13        if self.0.abs().fract() < 0.00000001 {
14            write!(f, "{}.0", self.0)
15        } else {
16            write!(f, "{}", self.0)
17        }
18    }
19}
20
21
22#[derive(Clone, Copy, Default, Debug, PartialEq)]
23pub struct Rect {
24    pub pos: DVec2,
25    pub size: DVec2,
26}
27
28impl Rect {
29    
30    pub fn translate(self, pos: DVec2) -> Rect {
31        Rect {pos: self.pos + pos, size: self.size}
32    }
33    
34    pub fn contains(&self, pos: DVec2) -> bool {
35        pos.x >= self.pos.x && pos.x <= self.pos.x + self.size.x &&
36        pos.y >= self.pos.y && pos.y <= self.pos.y + self.size.y
37    }
38    
39    pub fn center(&self) -> DVec2 {
40        DVec2 {
41            x: self.pos.x + self.size.x * 0.5,
42            y: self.pos.y + self.size.y * 0.5,
43        }
44    }
45    
46    pub fn scale_and_shift(&self, center: DVec2, scale: f64, shift: DVec2) -> Rect {
47        Rect {
48            pos: (self.pos - center) * scale + center + shift,
49            size: self.size * scale
50        }
51    }
52    
53    pub fn intersects(&self, r: Rect) -> bool {
54        !(
55            r.pos.x > self.pos.x + self.size.x ||
56            r.pos.x + r.size.x < self.pos.x ||
57            r.pos.y > self.pos.y + self.size.y ||
58            r.pos.y + r.size.y < self.pos.y
59        )
60    }
61    
62    pub fn add_margin(self, size: DVec2) -> Rect {
63        Rect {pos: self.pos - size, size: self.size + 2.0 * size}
64    }
65    
66    pub fn contain(&self, other: Rect) -> Rect {
67        let mut pos = other.pos;
68        if pos.x < self.pos.x{ pos.x = self.pos.x };
69        if pos.y < self.pos.y{ pos.y = self.pos.y };
70        if pos.x + other.size.x > self.pos.x + self.size.x{
71            pos.x = self.pos.x + self.size.x - other.size.x
72        }
73        if pos.y + other.size.y > self.pos.y+ self.size.y{
74            pos.y = self.pos.y + self.size.y - other.size.y
75        }
76        Rect{
77            pos,
78            size:other.size
79        }
80    }
81    
82    pub fn clip(&self, clip: (DVec2, DVec2)) -> Rect {
83        let mut x1 = self.pos.x;
84        let mut y1 = self.pos.y;
85        let mut x2 = x1 + self.size.x;
86        let mut y2 = y1 + self.size.y;
87        x1 = x1.max(clip.0.x).min(clip.1.x);
88        y1 = y1.max(clip.0.y).min(clip.1.y);
89        x2 = x2.max(clip.0.x).min(clip.1.x);
90        y2 = y2.max(clip.0.y).min(clip.1.y);
91        Rect {pos: dvec2(x1, y1), size: dvec2(x2 - x1, y2 - y1)}
92    }
93    
94    pub fn from_lerp(a: Rect, b: Rect, f: f64) -> Rect {
95        Rect {
96            pos: (b.pos - a.pos) * f + a.pos,
97            size: (b.size - a.size) * f + a.size
98        }
99    }
100
101    pub fn dpi_snap(&self, f:f64)->Rect{
102        Rect{
103            pos: dvec2((self.pos.x / f).floor() * f,(self.pos.y / f).floor() * f),
104            size:  dvec2((self.size.x / f).floor() * f,(self.size.y / f).floor() * f),
105        }
106    }
107    
108    pub fn is_nan(&self)->bool{
109        self.pos.is_nan() || self.size.is_nan()
110    }
111
112}
113
114
115#[derive(Clone, Copy, Default, Debug, PartialEq)]
116pub struct DVec2 {
117    pub x: f64,
118    pub y: f64,
119}
120
121impl std::convert::From<Vec2> for DVec2 {
122    fn from(other: Vec2) -> DVec2 {DVec2 {x: other.x as f64, y: other.y as f64}}
123}
124
125impl std::convert::From<DVec2> for Vec2 {
126    fn from(other: DVec2) -> Vec2 {Vec2 {x: other.x as f32, y: other.y as f32}}
127}
128
129impl std::convert::From<(DVec2, DVec2)> for Rect {
130    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)}}
131}
132
133impl DVec2 {
134    pub fn new() -> DVec2 {
135        DVec2::default()
136    }
137
138
139    pub fn dpi_snap(&self, f:f64)->DVec2{
140        DVec2{
141            x:(self.x * f).round() / f,
142            y:(self.y * f).round() / f
143        }
144    }
145    
146    pub fn all(x: f64) -> DVec2 {
147        DVec2 {x, y: x}
148    }
149    
150    pub fn index(&self, index:Vec2Index)->f64{
151        match index{
152            Vec2Index::X=>self.x,
153            Vec2Index::Y=>self.y
154        }
155    }
156
157    pub fn set_index(&mut self, index:Vec2Index, v: f64){
158        match index{
159            Vec2Index::X=>{self.x = v},
160            Vec2Index::Y=>{self.y = v}
161        }
162    }
163    
164    pub fn from_index_pair(index:Vec2Index, a: f64, b:f64)->Self{
165        match index{
166            Vec2Index::X=>{Self{x:a,y:b}},
167            Vec2Index::Y=>{Self{x:b,y:a}}
168        }
169    }
170    
171    pub fn into_vec2(self) -> Vec2 {
172        Vec2 {x: self.x as f32, y: self.y as f32}
173    }
174    
175    pub fn from_lerp(a: DVec2, b: DVec2, f: f64) -> DVec2 {
176        let nf = 1.0 - f;
177        DVec2 {
178            x: nf * a.x + f * b.x,
179            y: nf * a.y + f * b.y,
180        }
181    }
182    
183    pub fn floor(self) -> DVec2 {
184        DVec2 {
185            x: self.x.floor(), 
186            y: self.y.floor(),
187        }
188    }
189        
190    pub fn ceil(self) -> DVec2 {
191        DVec2 {
192            x: self.x.ceil(), 
193            y: self.y.ceil(),
194        }
195    }
196    
197    pub fn distance(&self, other: &DVec2) -> f64 {
198        let dx = self.x - other.x;
199        let dy = self.y - other.y;
200        (dx * dx + dy * dy).sqrt()
201    }
202    
203    pub fn length(&self) -> f64 {
204        (self.x * self.x + self.y * self.y).sqrt()
205    }
206    
207    pub fn is_nan(&self)->bool{
208        self.x.is_nan() || self.y.is_nan()
209    }
210}
211
212impl fmt::Display for DVec2 {
213    // This trait requires `fmt` with this exact signature.
214    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
215        write!(f, "vec2f64({},{})", self.x, self.y)
216    }
217}
218
219pub fn dvec2(x: f64, y: f64) -> DVec2 {DVec2 {x, y}}
220
221//------ Vec2 operators
222
223impl ops::Add<DVec2> for DVec2 {
224    type Output = DVec2;
225    fn add(self, rhs: DVec2) -> DVec2 {
226        DVec2 {x: self.x + rhs.x, y: self.y + rhs.y}
227    }
228}
229
230impl ops::Sub<DVec2> for DVec2 {
231    type Output = DVec2;
232    fn sub(self, rhs: DVec2) -> DVec2 {
233        DVec2 {x: self.x - rhs.x, y: self.y - rhs.y}
234    }
235}
236
237impl ops::Mul<DVec2> for DVec2 {
238    type Output = DVec2;
239    fn mul(self, rhs: DVec2) -> DVec2 {
240        DVec2 {x: self.x * rhs.x, y: self.y * rhs.y}
241    }
242}
243
244impl ops::Div<DVec2> for DVec2 {
245    type Output = DVec2;
246    fn div(self, rhs: DVec2) -> DVec2 {
247        DVec2 {x: self.x / rhs.x, y: self.y / rhs.y}
248    }
249}
250
251
252impl ops::Add<DVec2> for f64 {
253    type Output = DVec2;
254    fn add(self, rhs: DVec2) -> DVec2 {
255        DVec2 {x: self + rhs.x, y: self + rhs.y}
256    }
257}
258
259impl ops::Sub<DVec2> for f64 {
260    type Output = DVec2;
261    fn sub(self, rhs: DVec2) -> DVec2 {
262        DVec2 {x: self -rhs.x, y: self -rhs.y}
263    }
264}
265
266impl ops::Mul<DVec2> for f64 {
267    type Output = DVec2;
268    fn mul(self, rhs: DVec2) -> DVec2 {
269        DVec2 {x: self *rhs.x, y: self *rhs.y}
270    }
271}
272
273impl ops::Div<DVec2> for f64 {
274    type Output = DVec2;
275    fn div(self, rhs: DVec2) -> DVec2 {
276        DVec2 {x: self / rhs.x, y: self / rhs.y}
277    }
278}
279
280
281impl ops::Add<f64> for DVec2 {
282    type Output = DVec2;
283    fn add(self, rhs: f64) -> DVec2 {
284        DVec2 {x: self.x + rhs, y: self.y + rhs}
285    }
286}
287
288impl ops::Sub<f64> for DVec2 {
289    type Output = DVec2;
290    fn sub(self, rhs: f64) -> DVec2 {
291        DVec2 {x: self.x - rhs, y: self.y - rhs}
292    }
293}
294
295impl ops::Mul<f64> for DVec2 {
296    type Output = DVec2;
297    fn mul(self, rhs: f64) -> DVec2 {
298        DVec2 {x: self.x * rhs, y: self.y * rhs}
299    }
300}
301
302impl ops::Div<f64> for DVec2 {
303    type Output = DVec2;
304    fn div(self, rhs: f64) -> DVec2 {
305        DVec2 {x: self.x / rhs, y: self.y / rhs}
306    }
307}
308
309impl ops::AddAssign<DVec2> for DVec2 {
310    fn add_assign(&mut self, rhs: DVec2) {
311        self.x = self.x + rhs.x;
312        self.y = self.y + rhs.y;
313    }
314}
315
316impl ops::SubAssign<DVec2> for DVec2 {
317    fn sub_assign(&mut self, rhs: DVec2) {
318        self.x = self.x - rhs.x;
319        self.y = self.y - rhs.y;
320    }
321}
322
323impl ops::MulAssign<DVec2> for DVec2 {
324    fn mul_assign(&mut self, rhs: DVec2) {
325        self.x = self.x * rhs.x;
326        self.y = self.y * rhs.y;
327    }
328}
329
330impl ops::DivAssign<DVec2> for DVec2 {
331    fn div_assign(&mut self, rhs: DVec2) {
332        self.x = self.x / rhs.x;
333        self.y = self.y / rhs.y;
334    }
335}
336
337
338impl ops::AddAssign<f64> for DVec2 {
339    fn add_assign(&mut self, rhs: f64) {
340        self.x = self.x + rhs;
341        self.y = self.y + rhs;
342    }
343}
344
345impl ops::SubAssign<f64> for DVec2 {
346    fn sub_assign(&mut self, rhs: f64) {
347        self.x = self.x - rhs;
348        self.y = self.y - rhs;
349    }
350}
351
352impl ops::MulAssign<f64> for DVec2 {
353    fn mul_assign(&mut self, rhs: f64) {
354        self.x = self.x * rhs;
355        self.y = self.y * rhs;
356    }
357}
358
359impl ops::DivAssign<f64> for DVec2 {
360    fn div_assign(&mut self, rhs: f64) {
361        self.x = self.x / rhs;
362        self.y = self.y / rhs;
363    }
364}
365
366impl ops::Neg for DVec2 {
367    type Output = DVec2;
368    fn neg(self) -> Self {DVec2 {x: -self.x, y: -self.y}}
369}
370