import { PathData , GroupParameters } from "../interfaces" ; import parseGroupParameter from "./parseGroupParameter" ; import { radiansDelta , radToAngle , round } from "../../misc" ; import { curry } from "ramda" ; const log = require ( "loglevel" ) . getLogger ( "path-log" ) ; const getAdaptArmsValue = ( group , vertexIndex ) : boolean => { let parameter = group . adaptArms ; parameter = parseGroupParameter ( parameter , vertexIndex ) ; if ( ! parameter ) return parameter ; else if ( typeof parameter !== "boolean" ) throw `Wrong 'adaptArms' parameter in group number ${ group . pk }` ; else return parameter ; } ; const getSmartRoundValue = ( group , vertexIndex ) : boolean => { let parameter = group . smartRound ; parameter = parseGroupParameter ( parameter , vertexIndex ) ; if ( ! parameter ) return parameter ; else if ( typeof parameter !== "boolean" ) throw `Wrong 'smartRound' parameter in group number ${ group . pk }` ; else return parameter ; } ; const getLengthBasedRoundValue = ( group , vertexIndex ) : boolean => { let parameter = group . lengthBasedRound ; parameter = parseGroupParameter ( parameter , vertexIndex ) ; if ( ! parameter ) return parameter ; else if ( typeof parameter !== "boolean" ) throw `Wrong 'lengthBasedRound' parameter in group number ${ group . pk }` ; else return parameter ; } ; const setArms = ( mode , path ) : PathData => { var { vertexes } = path ; var { groups , averageLength } = path . parameters ; var numOfPoints = vertexes . length - 1 ; var averageLength ; for ( let i = 1 ; i < vertexes . length ; i ++ ) { let firstArmAdapt = getAdaptArmsValue ( groups [ vertexes [ i - 1 ] . group ] , vertexes [ i - 1 ] . indexWithingGroup ) ; let secondArmAdapt = getAdaptArmsValue ( groups [ vertexes [ i ] . group ] , vertexes [ i ] . indexWithingGroup ) ; if ( mode === "init" && firstArmAdapt && secondArmAdapt ) continue ; else if ( mode === "adapt" && ! firstArmAdapt && ! secondArmAdapt ) continue ; let firstArmLength , secondArmLength ; let firstArmSmartRound = getSmartRoundValue ( groups [ vertexes [ i - 1 ] . group ] , vertexes [ i - 1 ] . indexWithingGroup ) ; let secondArmSmartRound = getSmartRoundValue ( groups [ vertexes [ i ] . group ] , vertexes [ i ] . indexWithingGroup ) ; let firstArmLengthBasedRound = getLengthBasedRoundValue ( groups [ vertexes [ i - 1 ] . group ] , vertexes [ i - 1 ] . indexWithingGroup ) ; let secondArmLengthBasedRound = getLengthBasedRoundValue ( groups [ vertexes [ i ] . group ] , vertexes [ i ] . indexWithingGroup ) ; let individualFactor ; if ( firstArmSmartRound || secondArmSmartRound ) { let distanceRadians = radiansDelta ( vertexes [ i - 1 ] . radians , vertexes [ i ] . radians ) ; individualFactor = ( 2 * Math . PI ) / distanceRadians ; } if ( ( mode === "adapt" && firstArmAdapt ) || ( mode === "init" && ! firstArmAdapt ) ) { log . info ( `calc first arm. Mode: ${ mode }` ) ; let firstArmFactor = firstArmSmartRound ? individualFactor : numOfPoints ; firstArmLength = ( 4 / 3 ) * Math . tan ( Math . PI / ( 2 * firstArmFactor ) ) ; if ( mode === "adapt" ) { let firstArmScaleFactor = firstArmLengthBasedRound ? vertexes [ i - 1 ] . length : averageLength ; firstArmLength *= firstArmScaleFactor ; } firstArmLength *= vertexes [ i - 1 ] . round [ 1 ] ; let firstArmRadians = vertexes [ i - 1 ] . radians + Math . PI / 2 ; let firstArmAngle = radToAngle ( firstArmRadians ) ; log . debug ( "first arm angle" , firstArmAngle ) ; let cosx1 = round ( Math . cos ( firstArmRadians ) ) ; if ( mode === "adapt" ) cosx1 *= - 1 ; let siny1 = round ( Math . sin ( firstArmRadians ) ) ; let x1 = cosx1 * firstArmLength + vertexes [ i - 1 ] . x ; let y1 = siny1 * firstArmLength + vertexes [ i - 1 ] . y ; log . debug ( `vertex ${ i } first arm x: ${ x1 } y: ${ y1 }` ) ; vertexes [ i ] = { ... vertexes [ i ] , x1 , y1 , cosx1 , siny1 } ; } if ( ( mode === "adapt" && secondArmAdapt ) || ( mode === "init" && ! secondArmAdapt ) ) { log . info ( `calc second arm. Mode: ${ mode }` ) ; let secondArmFactor = secondArmSmartRound ? individualFactor : numOfPoints ; secondArmLength = ( 4 / 3 ) * Math . tan ( Math . PI / ( 2 * secondArmFactor ) ) ; if ( mode === "adapt" ) { let secondArmScaleFactor = secondArmLengthBasedRound ? vertexes [ i ] . length : averageLength ; secondArmLength *= secondArmScaleFactor ; } secondArmLength *= vertexes [ i ] . round [ 0 ] ; let secondArmRadians = vertexes [ i ] . radians - Math . PI / 2 ; let secondArmAngle = radToAngle ( secondArmRadians ) ; log . debug ( "second arm angle" , secondArmAngle ) ; let cosx2 = round ( Math . cos ( secondArmRadians ) ) ; if ( mode === "adapt" ) cosx2 *= - 1 ; let siny2 = round ( Math . sin ( secondArmRadians ) ) ; let x2 = cosx2 * secondArmLength + vertexes [ i ] . x ; let y2 = siny2 * secondArmLength + vertexes [ i ] . y ; log . debug ( `vertex ${ i } second arm x: ${ x2 } y: ${ y2 }` ) ; vertexes [ i ] = { ... vertexes [ i ] , x2 , y2 , cosx2 , siny2 } ; } } return path ; } ; export default curry ( setArms ) ;