class Simplify < P extends fabric . Point > { public set tolerance ( tolerance ) { if ( typeof tolerance !== "number" ) { tolerance = 1 ; } this . _tolerance = tolerance ; this . sqTolerance = tolerance * tolerance ; } public get tolerance ( ) { return this . _tolerance ; } private _tolerance : number = 1 ; private sqTolerance : number = 1 ; public getSquareDistance ( p1 , p2 ) { let dx = p1 . x - p2 . x , dy = p1 . y - p2 . y ; return dx * dx + dy * dy ; } public getSquareSegmentDistance ( p , p1 , p2 ) { let x = p1 . x , y = p1 . y , dx = p2 . x - x , dy = p2 . y - y ; if ( dx !== 0 || dy !== 0 ) { let t = ( ( p . x - x ) * dx + ( p . y - y ) * dy ) / ( dx * dx + dy * dy ) ; if ( t > 1 ) { x = p2 . x ; y = p2 . y ; } else if ( t > 0 ) { x += dx * t ; y += dy * t ; } } dx = p . x - x ; dy = p . y - y ; return dx * dx + dy * dy ; } public simplifyRadialDistance ( points ) { let prevPoint = points [ 0 ] , newPoints = [ prevPoint ] , point ; for ( let i = 1 , len = points . length ; i < len ; i ++ ) { point = points [ i ] ; if ( this . getSquareDistance ( point , prevPoint ) > this . sqTolerance ) { newPoints . push ( point ) ; prevPoint = point ; } } if ( prevPoint !== point ) { newPoints . push ( point ) ; } return newPoints ; } public simplifyDouglasPeucker ( points ) { let len = points . length , MarkerArray = typeof Uint8Array !== "undefined" ? Uint8Array : Array , markers = new MarkerArray ( len ) , first = 0 , last = len - 1 , stack = [ ] , newPoints = [ ] , i , maxSqDist , sqDist , index ; markers [ first ] = markers [ last ] = 1 ; while ( last ) { maxSqDist = 0 ; for ( i = first + 1 ; i < last ; i ++ ) { sqDist = this . getSquareSegmentDistance ( points [ i ] , points [ first ] , points [ last ] ) ; if ( sqDist > maxSqDist ) { index = i ; maxSqDist = sqDist ; } } if ( maxSqDist > this . sqTolerance ) { markers [ index ] = 1 ; stack . push ( first , index , index , last ) ; } last = stack . pop ( ) ; first = stack . pop ( ) ; } for ( i = 0 ; i < len ; i ++ ) { if ( markers [ i ] ) { newPoints . push ( points [ i ] ) ; } } return newPoints ; } public do ( points , highestQuality ) { points = highestQuality ? points : this . simplifyRadialDistance ( points ) ; points = this . simplifyDouglasPeucker ( points ) ; return points ; } } export default Simplify ;