extern crate mazth;
use std::cmp;
use self::mazth::mat::*;
use interface::i_interpolate::*;
#[derive(Debug)]
#[derive(Clone)]
pub struct LinearInterp {
pub _ctl: [ Mat4x1< f64 > ; 2 ],
pub _point: Mat4x1< f64 >,
pub _steps: i64,
pub _step_current: i64,
}
impl LinearInterp {
pub fn init( s: i64, cp0: Mat4x1< f64 >, cp1: Mat4x1< f64 > ) -> LinearInterp {
assert!( s > 2 );
LinearInterp {
_ctl: [ cp0, cp1 ],
_point: cp0, _steps: s,
_step_current: -1i64,
}
}
}
#[allow(unused_variables)]
impl IInterpolate< Mat4x1< f64 > > for LinearInterp {
fn num_steps( & self ) -> u64 {
self._steps as u64
}
fn interp_delta( & mut self, steps: i64 ) -> Option< Mat4x1< f64 > > {
self._step_current = cmp::min( self._step_current + steps, self._steps );
self._step_current = cmp::max( self._step_current, -1 );
let clamp = if self._step_current < 0 {
0
} else if self._step_current >= self._steps {
self._steps - 1
} else {
self._step_current
};
let fraction = clamp as f64 / ( self._steps - 1 ) as f64;
let d = self._ctl[1].minus( &self._ctl[0] ).unwrap();
let offset = d.scale( fraction ).unwrap();
self._point = self._ctl[0].plus( &offset ).unwrap();
Some( self._point )
}
fn interp_current( & self ) -> Mat4x1< f64 > {
self._point
}
fn interp_is_end( & self ) -> bool {
self._step_current == self._steps
}
fn interp_is_start( & self ) -> bool {
self._step_current == -1
}
fn reset( & mut self ){
self._step_current = -1i64;
}
}
impl Iterator for LinearInterp { type Item = Mat4x1< f64 >;
fn next( & mut self ) -> Option< Mat4x1< f64 > > {
self._step_current = cmp::min( self._step_current + 1, self._steps );
if self._step_current == self._steps {
None
} else {
let clamp = if self._step_current < 0 {
0
} else if self._step_current >= self._steps {
self._steps
} else {
self._step_current
};
let fraction = clamp as f64 / ( self._steps - 1 ) as f64;
let d = self._ctl[1].minus( &self._ctl[0] ).unwrap();
let offset = d.scale( fraction ).unwrap();
self._point = self._ctl[0].plus( &offset ).unwrap();
Some( self._point )
}
}
}
impl DoubleEndedIterator for LinearInterp {
fn next_back( & mut self ) -> Option< Mat4x1< f64 > > {
self._step_current = cmp::max( self._step_current - 1, -1 );
if self._step_current == -1 {
None
} else {
let clamp = if self._step_current < 0 {
0
} else if self._step_current >= self._steps {
self._steps
} else {
self._step_current
};
let fraction = clamp as f64 / ( self._steps - 1 ) as f64;
let d = self._ctl[1].minus( &self._ctl[0] ).unwrap();
let offset = d.scale( fraction ).unwrap();
self._point = self._ctl[0].plus( &offset ).unwrap();
Some( self._point )
}
}
}