deki_lerp/
relative.rs

1use crate::*;
2
3// Linear Interpolation \\
4
5    /// Any type that implemients necessary math traits for linear interpolation (lerp)
6    pub trait Lerpable {
7        /// Perform linear interpolation
8        fn lerp(&self,to:Self,lerp:f32) -> Self;
9    }
10
11    impl <A> Lerpable for A 
12    where A: Clone
13        + Add<Output=A>
14        + Sub<Output=A>
15        + Mul<f32,Output=A>
16    {
17        fn lerp(&self,to:Self,lerp:f32) -> Self {
18            self.clone().add(to.sub(self.clone()).mul(lerp))
19        }
20    }
21
22    /// Any type that implemients necessary math traits for linear interpolation (lerp)
23    pub trait LerpableF32 {
24        /// Perform linear interpolation
25        fn lerp(&self,to:Self,lerp:f32) -> Self;
26    }
27
28    impl <A> LerpableF32 for A 
29    where A: Clone
30        + Add<Output=A>
31        + Sub<Output=A>
32        + MulF32
33    {
34        /// wonky lerp, mainly meant for integers
35        fn lerp(&self,to:Self,lerp:f32) -> Self {
36            self.clone().add(to.sub(self.clone()).mul_f32(lerp))
37        }
38    }
39
40// Gated Linear Interpolation \\
41
42    /// Any type that implements necessary math traits for linear interpolation (lerp)
43    pub trait Glerpable {
44        /// Perform linear interpolation or snap to a threshold, true if 'arrived'
45        fn glerp(&mut self,to:Self,lerp:f32,thresh:Self) -> bool;
46    }
47
48    buns::sandwich!{
49        impl Glerpable for ^0 {
50            #[inline]
51            fn glerp(&mut self,to:Self,lerp:f32,thresh:Self) -> bool {
52                let delta = to - *self;
53                if delta.abs() <= thresh || lerp >= 1. {
54                    *self = to; 
55                    true
56                } else {
57                    *self += delta.mul_f32(lerp);
58                    false
59                }
60            }
61        }
62        #f32 #f64 #i8 #i16 #i32 #i64 #i128 #isize
63    }
64    
65// Cycling Linear Interpolation \\
66
67    pub trait Clerpable {
68        /// get closest delta, whichever direction is closer
69        /// - assumes self and the target are inside range
70        fn delta_qucy(&self,to:Self,min:Self,max:Self) -> Self;
71        /// lerp to a value, auto-choosing which direction is fastest
72        /// - assumes self and the target are inside range
73        fn lerp_qucy(&self,to:Self,lerp:f32,min:Self,max:Self) -> Self;
74        /// lerp to a value, auto-choosing which direction is fastest, snaps to goal with 
75        /// using a threshold
76        /// - assumes self and the target are inside range
77        fn glerp_qucy(&mut self,to:Self,lerp:f32,thresh:Self,min:Self,max:Self) -> bool;
78    }
79
80    buns::sandwich!{
81        impl Clerpable for ^0 {
82            #[inline]
83            fn delta_qucy(&self,to:Self,min:Self,max:Self) -> Self {
84                let delta = to - *self;
85                let deltabs = delta.abs();
86                let dolta = max - min - deltabs;
87                if deltabs < dolta {delta} else {-dolta * delta.signum()}
88            }
89            #[inline]
90            fn lerp_qucy(&self,to:Self,lerp:f32,min:Self,max:Self) -> Self {
91                let delta = self.delta_qucy(to,min,max);
92                self.add_qucy((delta as f32 * lerp) as ^0,min,max)
93            }
94            #[inline]
95            fn glerp_qucy(&mut self,to:Self,lerp:f32,thresh:Self,min:Self,max:Self) -> bool {
96                let delta = self.delta_qucy(to,min,max);
97                if delta.abs() <= thresh || lerp >= 1. {
98                    *self = to; 
99                    true
100                } else {
101                    *self = self.add_qucy(delta.mul_f32(lerp),min,max);
102                    false
103                }          
104            }
105        }
106        #f32 #f64 #i8 #i16 #i32 #i64 #i128 #isize
107    }
108
109// EOF \\