import * as _ from "lodash" ; export class LowPassFilter { private _bufferMaxSize : number ; private _buffer : number [ ] ; private _smoothing : number ; constructor ( smoothing ? ) { this . _smoothing = smoothing || 0.5 ; this . _buffer = [ ] ; this . _bufferMaxSize = 10 ; } param { number [ ] } values returns { number [ ] } public init ( values ) { for ( let i = 0 ; i < values . length ; i ++ ) { this . __push ( values [ i ] ) ; } return this . _buffer ; } param { number } value returns { number } private public __push ( value ) { const removed = ( this . _buffer . length === this . _bufferMaxSize ) ? this . _buffer . shift ( ) : 0 ; this . _buffer . push ( value ) ; return removed ; } param { number } nextValue returns { number } public next ( nextValue ) { const self = this ; const removed = this . __push ( nextValue ) ; const result = this . _buffer . reduce ( ( last , current ) => { return self . _smoothing * current + ( 1 - self . _smoothing ) * last ; } , removed ) ; this . _buffer [ this . _buffer . length - 1 ] = result ; return result ; } param { number [ ] } values returns { number [ ] } public smoothArray ( values ) { let value = values [ 0 ] ; for ( let i = 1 ; i < values . length ; i ++ ) { const currentValue = values [ i ] ; value += ( currentValue - value ) * this . _smoothing ; values [ i ] = Math . round ( value ) ; } return values ; } param { number [ ] } values param { number [ ] } scale param { number } positiveVariationTrigger param { number } negativeVariationTrigger returns { number [ ] } public adaptiveSmoothArray ( values , scale , positiveVariationTrigger ? , negativeVariationTrigger ? ) { let value = values [ 0 ] ; for ( let i = 1 ; i < values . length ; i ++ ) { const deltaValue = ( values [ i ] - values [ i - 1 ] ) ; const deltaScale = ( scale [ i ] - scale [ i - 1 ] ) ; const variation = deltaValue / deltaScale ; if ( _ . isNumber ( positiveVariationTrigger ) && variation >= 0 && Math . abs ( variation ) >= positiveVariationTrigger ) { value += ( values [ i ] - value ) * this . _smoothing ; } else if ( _ . isNumber ( negativeVariationTrigger ) && variation < 0 && Math . abs ( variation ) >= negativeVariationTrigger ) { value += ( values [ i ] - value ) * this . _smoothing ; } else { value = values [ i ] ; } values [ i ] = Math . round ( value ) ; } return values ; } get bufferMaxSize ( ) : number { return this . _bufferMaxSize ; } set bufferMaxSize ( value ) { this . _bufferMaxSize = value ; } get buffer ( ) : number [ ] { return this . _buffer ; } set buffer ( value ) { this . _buffer = value ; } get smoothing ( ) : number { return this . _smoothing ; } set smoothing ( value ) { this . _smoothing = value ; } }