import { EPS , TAU } from "@thi.ng/math/api" ; import { abs2 } from "@thi.ng/vectors/abs" ; import { angleBetween2 } from "@thi.ng/vectors/angle-between" ; import { ReadonlyVec , Vec , X2 } from "@thi.ng/vectors/api" ; import { div2 } from "@thi.ng/vectors/div" ; import { eqDelta2 } from "@thi.ng/vectors/eqdelta" ; import { mulN2 } from "@thi.ng/vectors/muln" ; import { neg } from "@thi.ng/vectors/neg" ; import { powN2 } from "@thi.ng/vectors/pown" ; import { sub2 } from "@thi.ng/vectors/sub" ; import { submN2 } from "@thi.ng/vectors/submn" ; /**
 * Conversion from endpoint to center parameterization.
 *
 *  https *
 * Returns undefined if `a` & `b` are equal or any `radii` component is
 * zero.
 *
 *  param a param b param radii param axis param xl param cw export const fromEndPoints = ( a , b , radii , axis = 0 , xl = false , cw = false ) => { const r = abs2 ( [ ] , radii ) ; if ( eqDelta2 ( a , b ) || r [ 0 ] < EPS || r [ 1 ] < EPS ) { return ; } axis %= TAU ; const d = submN2 ( [ ] , a , b , 0.5 ) ; const c = Math . cos ( axis ) ; const s = Math . sin ( axis ) ; const tp = [ c * d [ 0 ] + s * d [ 1 ] , - s * d [ 0 ] + c * d [ 1 ] ] ; const [ tx2 , ty2 ] = powN2 ( [ ] , tp , 2 ) ; const rc = tx2 / ( r [ 0 ] * r [ 0 ] ) + ty2 / ( r [ 1 ] * r [ 1 ] ) ; rc > 1 && mulN2 ( r , r , Math . sqrt ( rc ) ) ; const [ rx , ry ] = r ; const rx2 = rx * rx ; const ry2 = ry * ry ; const radicant = Math . max ( 0 , ( rx2 * ry2 - rx2 * ty2 - ry2 * tx2 ) / ( rx2 * ty2 + ry2 * tx2 ) ) ; const coeff = ( xl !== cw ? 1 : - 1 ) * Math . sqrt ( radicant ) ; const tc = [ coeff * ( ( rx * tp [ 1 ] ) / ry ) , coeff * ( - ( ry * tp [ 0 ] ) / rx ) ] ; const center = [ c * tc [ 0 ] - s * tc [ 1 ] + ( a [ 0 ] + b [ 0 ] ) / 2 , s * tc [ 0 ] + c * tc [ 1 ] + ( a [ 1 ] + b [ 1 ] ) / 2 , ] ; const ta = div2 ( null , sub2 ( [ ] , tp , tc ) , r ) ; const tb = div2 ( null , sub2 ( null , neg ( [ ] , tp ) , tc ) , r ) ; const start = angleBetween2 ( X2 , ta ) ; let sweep = angleBetween2 ( ta , tb ) ; if ( ! cw && sweep > 0 ) { sweep -= TAU ; } else if ( cw && sweep < 0 ) { sweep += TAU ; } sweep %= TAU ; return { center , r , axis , start , end : start + sweep , xl , cw , } ; } ;