e2rcore/implement/math/
linearinterp.rs1extern crate mazth;
2
3use std::cmp;
4
5use self::mazth::mat::*;
6use interface::i_interpolate::*;
7
8#[derive(Debug)]
9#[derive(Clone)]
10pub struct LinearInterp {
11 pub _ctl: [ Mat4x1< f64 > ; 2 ],
12 pub _point: Mat4x1< f64 >,
13 pub _steps: i64,
14 pub _step_current: i64,
15}
16
17impl LinearInterp {
18 pub fn init( s: i64, cp0: Mat4x1< f64 >, cp1: Mat4x1< f64 > ) -> LinearInterp {
19 assert!( s > 2 );
20 LinearInterp {
21 _ctl: [ cp0, cp1 ],
22 _point: cp0, _steps: s,
24 _step_current: -1i64,
25 }
26 }
27}
28
29#[allow(unused_variables)]
30impl IInterpolate< Mat4x1< f64 > > for LinearInterp {
31 fn num_steps( & self ) -> u64 {
32 self._steps as u64
33 }
34 fn interp_delta( & mut self, steps: i64 ) -> Option< Mat4x1< f64 > > {
35 self._step_current = cmp::min( self._step_current + steps, self._steps );
36 self._step_current = cmp::max( self._step_current, -1 );
37
38 let clamp = if self._step_current < 0 {
39 0
40 } else if self._step_current >= self._steps {
41 self._steps - 1
42 } else {
43 self._step_current
44 };
45 let fraction = clamp as f64 / ( self._steps - 1 ) as f64;
46 let d = self._ctl[1].minus( &self._ctl[0] ).unwrap();
47 let offset = d.scale( fraction ).unwrap();
48 self._point = self._ctl[0].plus( &offset ).unwrap();
49 Some( self._point )
50 }
51 fn interp_current( & self ) -> Mat4x1< f64 > {
52 self._point
53 }
54 fn interp_is_end( & self ) -> bool {
55 self._step_current == self._steps
56 }
57 fn interp_is_start( & self ) -> bool {
58 self._step_current == -1
59 }
60 fn reset( & mut self ){
61 self._step_current = -1i64;
62 }
63}
64
65impl Iterator for LinearInterp { type Item = Mat4x1< f64 >;
67 fn next( & mut self ) -> Option< Mat4x1< f64 > > {
68 self._step_current = cmp::min( self._step_current + 1, self._steps );
69 if self._step_current == self._steps {
70 None
71 } else {
72 let clamp = if self._step_current < 0 {
73 0
74 } else if self._step_current >= self._steps {
75 self._steps
76 } else {
77 self._step_current
78 };
79
80 let fraction = clamp as f64 / ( self._steps - 1 ) as f64;
81 let d = self._ctl[1].minus( &self._ctl[0] ).unwrap();
82 let offset = d.scale( fraction ).unwrap();
83 self._point = self._ctl[0].plus( &offset ).unwrap();
84 Some( self._point )
85 }
86 }
87}
88
89impl DoubleEndedIterator for LinearInterp {
90 fn next_back( & mut self ) -> Option< Mat4x1< f64 > > {
91 self._step_current = cmp::max( self._step_current - 1, -1 );
92 if self._step_current == -1 {
93 None
94 } else {
95 let clamp = if self._step_current < 0 {
96 0
97 } else if self._step_current >= self._steps {
98 self._steps
99 } else {
100 self._step_current
101 };
102
103 let fraction = clamp as f64 / ( self._steps - 1 ) as f64;
104 let d = self._ctl[1].minus( &self._ctl[0] ).unwrap();
105 let offset = d.scale( fraction ).unwrap();
106 self._point = self._ctl[0].plus( &offset ).unwrap();
107 Some( self._point )
108 }
109 }
110}