e2r 0.2.0

experimental rendering engine in rust
Documentation
use std::cmp;

use implement::math::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, //start point
            _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 { //required by IInterpolate
    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 )
        }
    }
}