import { all , eqProps } from 'ramda' ; import { IPathResultItem } from '../../typings' ; import { APOS_LARGE , APOS_ROTATION , APOS_RX , APOS_RY , APOS_SWEEP , APOS_X , APOS_Y , CIRC } from '../const' ; import { plus } from '../math/plus' ; import { toFixed } from '../math/to-fixed' ; import { Vector } from '../math/vector' ; import { getAbs , getAbsHV , getRel , getRelHV } from './translate' ; export const combineHV = ( subPath , pathItem , index ) => { const relVal = getRelHV ( pathItem ) ; if ( subPath [ index - 1 ] . type . toLowerCase ( ) === pathItem . type . toLowerCase ( ) ) { const lastItem = subPath [ index - 1 ] ; if ( getRelHV ( lastItem ) * relVal >= 0 ) { lastItem . val [ 0 ] = getAbsHV ( pathItem ) ; lastItem . type = lastItem . type . toUpperCase ( ) ; subPath . splice ( index , 1 ) ; } } } ; export const combineL = ( subPath , pathItem , index , digit ) => { const fixed = toFixed ( digit ) ; if ( subPath [ index - 1 ] . type . toLowerCase ( ) === 'l' ) { const lastItem = subPath [ index - 1 ] ; const relVal = getRel ( pathItem ) ; const lastRelVal = getRel ( lastItem ) ; if ( fixed ( Math . atan2 ( lastRelVal [ 0 ] , lastRelVal [ 1 ] ) ) === fixed ( Math . atan2 ( relVal [ 0 ] , relVal [ 1 ] ) ) ) { lastItem . val = [ plus ( lastItem . val [ 0 ] , relVal [ 0 ] ) , plus ( lastItem . val [ 1 ] , relVal [ 1 ] ) ] ; lastItem . type = 'l' ; subPath . splice ( index , 1 ) ; } } } ; const getCenter = ( pathItem , digit ) : number [ ] => { const rotation = pathItem . val [ APOS_ROTATION ] ; const rx = pathItem . val [ APOS_RX ] ; const ry = pathItem . val [ APOS_RY ] ; const ccw = pathItem . val [ APOS_LARGE ] === pathItem . val [ APOS_SWEEP ] ; const abs = getAbs ( { type : pathItem . type , val : pathItem . val . slice ( APOS_X ) , from : pathItem . from , } ) ; const v1 = new Vector ( pathItem . from [ 0 ] , pathItem . from [ 1 ] ) ; const v2 = new Vector ( abs [ 0 ] , abs [ 1 ] ) ; if ( rotation ) { v1 . rotate ( - rotation * Math . PI * 2 / CIRC ) ; v2 . rotate ( - rotation * Math . PI * 2 / CIRC ) ; } if ( rx !== ry ) { v1 . y *= rx / ry ; v2 . y *= rx / ry ; } const v = new Vector ( v2 . x - v1 . x , v2 . y - v1 . y ) ; let r = rx ; if ( r < v . modulo / 2 ) { r = v . modulo / 2 ; } v . modulo = Math . sqrt ( r * r - Math . pow ( v . modulo / 2 , 2 ) ) ; const arc = ccw ? - Math . PI / 2 : Math . PI / 2 ; v . rotate ( arc ) ; v . x += ( v1 . x + v2 . x ) / 2 ; v . y += ( v1 . y + v2 . y ) / 2 ; if ( rx !== ry ) { v . y *= ry / rx ; } if ( rotation ) { v . rotate ( rotation * Math . PI * 2 / CIRC ) ; } return [ toFixed ( digit , v . x ) , toFixed ( digit , v . y ) ] ; } ; export const combineA = ( subPath , pathItem , index , digit ) => { const lastItem = subPath [ index - 1 ] ; if ( lastItem . type . toLowerCase ( ) === 'a' ) { const _eqProps = ( prop ) => eqProps ( `${ prop }` , lastItem . val , pathItem . val ) ; if ( all ( _eqProps , [ APOS_RX , APOS_RY , APOS_ROTATION , APOS_SWEEP ] ) ) { const center = getCenter ( pathItem , digit ) ; const lastCenter = getCenter ( lastItem , digit ) ; if ( center [ 0 ] === lastCenter [ 0 ] && center [ 1 ] === lastCenter [ 1 ] ) { const vbase = new Vector ( lastItem . from [ 0 ] - center [ 0 ] , lastItem . from [ 1 ] - center [ 1 ] ) ; const lastAbs = getAbs ( { type : lastItem . type , val : lastItem . val . slice ( APOS_X ) , from : lastItem . from , } ) ; const v1 = new Vector ( lastAbs [ 0 ] - center [ 0 ] , lastAbs [ 1 ] - center [ 1 ] ) ; const abs = getAbs ( { type : pathItem . type , val : pathItem . val . slice ( APOS_X ) , from : pathItem . from , } ) ; const v2 = new Vector ( abs [ 0 ] - center [ 0 ] , abs [ 1 ] - center [ 1 ] ) ; let radian1 = Vector . radian ( vbase , v1 ) ; if ( lastItem . val [ APOS_LARGE ] === 1 ) { radian1 = Math . PI * 2 - radian1 ; } let radian2 = Vector . radian ( v1 , v2 ) ; if ( pathItem . val [ APOS_LARGE ] === 1 ) { radian2 = Math . PI * 2 - radian2 ; } if ( radian1 + radian2 >= Math . PI * 2 ) { return ; } if ( radian1 + radian2 > Math . PI && lastItem . val [ APOS_LARGE ] === 0 ) { lastItem . val [ APOS_LARGE ] = 1 ; } lastItem . type = 'A' ; lastItem . val [ APOS_X ] = abs [ 0 ] ; lastItem . val [ APOS_Y ] = abs [ 1 ] ; subPath . splice ( index , 1 ) ; } } } return ; } ;