import { List } from 'immutable' ; import xs from 'xstream' ; import { ImgItem , ComponentSinks , Item , Point , PolygonItem , PolylineItem , Rect , State , } from '../interfaces' ; export function getMaxItemId ( state ) { return state . items . map ( item => item . id ) . max ( ) || 0 ; } export function getNextItemId ( state ) { return getMaxItemId ( state ) + 1 ; } export function isPolygonItem ( item ) { return item instanceof PolygonItem ; } export function isPolylineItem ( item ) { return item instanceof PolylineItem ; } export function isImgItem ( item ) { return item instanceof ImgItem ; } export function getBoundingBoxOfPoints ( points ) { if ( points . isEmpty ( ) ) { return null ; } const xs = points . map ( p => p . x ) ; const ys = points . map ( p => p . y ) ; const x = xs . min ( ) ; const y = ys . min ( ) ; const width = xs . max ( ) - x ; const height = ys . max ( ) - y ; return { x , y , width , height } ; } export function round ( number , n ) { const t = 10 ** n ; return Math . round ( number * t ) / t ; } export const round3 = ( number ) => round ( number , 3 ) ; export function containsPoint ( vs , p ) { const { x , y } = p ; let inside = false ; for ( let i = 0 , j = vs . length - 1 ; i < vs . length ; j = i , i += 1 ) { const xi = vs [ i ] . x ; const yi = vs [ i ] . y ; const xj = vs [ j ] . x ; const yj = vs [ j ] . y ; const intersect = yi > y !== yj > y && x < ( xj - xi ) * ( y - yi ) / ( yj - yi ) + xi ; if ( intersect ) inside = ! inside ; } return inside ; } export function getCoordinateUpdater ( anchor , start , end ) { return ( target ) => anchor + ( end - anchor ) * ( target - anchor ) / ( start - anchor ) ; } const square = ( x ) => x * x ; const dist2 = ( a , b ) => square ( a . x - b . x ) + square ( a . y - b . y ) ; export function distanceBetweenPointAndPoint ( point1 , point2 ) { const dx = point1 . x - point2 . x ; const dy = point1 . y - point2 . y ; return Math . sqrt ( dx * dx + dy * dy ) ; } export function distanceBetweenPointAndSegment ( point , start , end ) { const length2 = dist2 ( start , end ) ; if ( length2 === 0 ) { return distanceBetweenPointAndPoint ( point , start ) ; } const t = ( ( point . x - start . x ) * ( end . x - start . x ) + ( point . y - start . y ) * ( end . y - start . y ) ) / length2 ; if ( t <= 0 ) { return distanceBetweenPointAndPoint ( start , point ) ; } else if ( t >= 1 ) { return distanceBetweenPointAndPoint ( end , point ) ; } return Math . sqrt ( dist2 ( point , { x : start . x + t * ( end . x - start . x ) , y : start . y + t * ( end . y - start . y ) , } ) ) ; } export function getIn ( obj , keyPath ) { return keyPath . split ( '.' ) . reduce ( ( result , part ) => result && result [ part ] , obj ) ; } export function mergeSinks < K extends keyof ComponentSinks > ( sinksArray , keyPath ) { return xs . merge ( ... ( sinksArray . map ( sinks => getIn ( sinks , keyPath ) ) . filter ( Boolean ) as any ) ) ; }