export class Vec { param n param min static clamp ( n , min ) ; static clamp ( n , min , max ) ; static clamp ( n , min , max ? ) { return Math . max ( min , typeof max !== 'undefined' ? Math . min ( n , max ) : n ) ; } param n param min static clampV ( A , min ) ; static clampV ( A , min , max ) ; static clampV ( A , min , max ? ) { return A . map ( ( n ) => ( max ? Vec . clamp ( n , min , max ) : Vec . clamp ( n , min ) ) ) ; } param A static neg = ( A ) : number [ ] => { return [ - A [ 0 ] , - A [ 1 ] ] ; } ; param A param B static add = ( A , B ) : number [ ] => { return [ A [ 0 ] + B [ 0 ] , A [ 1 ] + B [ 1 ] ] ; } ; param A param B static addScalar = ( A , n ) : number [ ] => { return [ A [ 0 ] + n , A [ 1 ] + n ] ; } ; param A param B static sub = ( A , B ) : number [ ] => { return [ A [ 0 ] - B [ 0 ] , A [ 1 ] - B [ 1 ] ] ; } ; param A param B static subScalar = ( A , n ) : number [ ] => { return [ A [ 0 ] - n , A [ 1 ] - n ] ; } ; param A param B static vec = ( A , B ) : number [ ] => { return [ B [ 0 ] - A [ 0 ] , B [ 1 ] - A [ 1 ] ] ; } ; param A param n static mul = ( A , n ) : number [ ] => { return [ A [ 0 ] * n , A [ 1 ] * n ] ; } ; param A param B static mulV = ( A , B ) : number [ ] => { return [ A [ 0 ] * B [ 0 ] , A [ 1 ] * B [ 1 ] ] ; } ; param A param n static div = ( A , n ) : number [ ] => { return [ A [ 0 ] / n , A [ 1 ] / n ] ; } ; param A param n static divV = ( A , B ) : number [ ] => { return [ A [ 0 ] / B [ 0 ] , A [ 1 ] / B [ 1 ] ] ; } ; param A static per = ( A ) : number [ ] => { return [ A [ 1 ] , - A [ 0 ] ] ; } ; param A param B static dpr = ( A , B ) : number => { return A [ 0 ] * B [ 0 ] + A [ 1 ] * B [ 1 ] ; } ; param A param B static cpr = ( A , B ) : number => { return A [ 0 ] * B [ 1 ] - B [ 0 ] * A [ 1 ] ; } ; /**
     * Cross (for point in polygon)
     *
     */ static cross ( x , y , z ) { return ( y [ 0 ] - x [ 0 ] ) * ( z [ 1 ] - x [ 1 ] ) - ( z [ 0 ] - x [ 0 ] ) * ( y [ 1 ] - x [ 1 ] ) ; } param A static len2 = ( A ) : number => { return A [ 0 ] * A [ 0 ] + A [ 1 ] * A [ 1 ] ; } ; param A static len = ( A ) : number => { return Math . hypot ( A [ 0 ] , A [ 1 ] ) ; } ; param A param B static pry = ( A , B ) : number => { return Vec . dpr ( A , B ) / Vec . len ( B ) ; } ; param A static uni = ( A ) : number [ ] => { return Vec . div ( A , Vec . len ( A ) ) ; } ; param A static normalize = ( A ) : number [ ] => { return Vec . uni ( A ) ; } ; param A param B returns static tangent = ( A , B ) : number [ ] => { return Vec . uni ( Vec . sub ( A , B ) ) ; } ; param A param B static dist2 = ( A , B ) : number => { return Vec . len2 ( Vec . sub ( A , B ) ) ; } ; param A param B static dist = ( A , B ) : number => { return Math . hypot ( A [ 1 ] - B [ 1 ] , A [ 0 ] - B [ 0 ] ) ; } ; param A param B returns static fastDist = ( A , B ) : number [ ] => { const V = [ B [ 0 ] - A [ 0 ] , B [ 1 ] - A [ 1 ] ] ; const aV = [ Math . abs ( V [ 0 ] ) , Math . abs ( V [ 1 ] ) ] ; let r = 1 / Math . max ( aV [ 0 ] , aV [ 1 ] ) ; r = r * ( 1.29289 - ( aV [ 0 ] + aV [ 1 ] ) * r * 0.29289 ) ; return [ V [ 0 ] * r , V [ 1 ] * r ] ; } ; param A param B static ang = ( A , B ) : number => { return Math . atan2 ( Vec . cpr ( A , B ) , Vec . dpr ( A , B ) ) ; } ; param A param B static angle = ( A , B ) : number => { return Math . atan2 ( B [ 1 ] - A [ 1 ] , B [ 0 ] - A [ 0 ] ) ; } ; param A param B static med = ( A , B ) : number [ ] => { return Vec . mul ( Vec . add ( A , B ) , 0.5 ) ; } ; param A param r static rot = ( A , r = 0 ) : number [ ] => { return [ A [ 0 ] * Math . cos ( r ) - A [ 1 ] * Math . sin ( r ) , A [ 0 ] * Math . sin ( r ) + A [ 1 ] * Math . cos ( r ) ] ; } ; param A param C param r static rotWith = ( A , C , r = 0 ) : number [ ] => { if ( r === 0 ) return A ; const s = Math . sin ( r ) ; const c = Math . cos ( r ) ; const px = A [ 0 ] - C [ 0 ] ; const py = A [ 1 ] - C [ 1 ] ; const nx = px * c - py * s ; const ny = px * s + py * c ; return [ nx + C [ 0 ] , ny + C [ 1 ] ] ; } ; param A param B static isEqual = ( A , B ) : boolean => { return A [ 0 ] === B [ 0 ] && A [ 1 ] === B [ 1 ] ; } ; param A param B param t static lrp = ( A , B , t ) : number [ ] => { return Vec . add ( A , Vec . mul ( Vec . sub ( B , A ) , t ) ) ; } ; param A param B param from param to param s static int = ( A , B , from , to , s = 1 ) : number [ ] => { const t = ( Vec . clamp ( from , to ) - from ) / ( to - from ) ; return Vec . add ( Vec . mul ( A , 1 - t ) , Vec . mul ( B , s ) ) ; } ; param p1 param pc param p2 static ang3 = ( p1 , pc , p2 ) : number => { const v1 = Vec . vec ( pc , p1 ) ; const v2 = Vec . vec ( pc , p2 ) ; return Vec . ang ( v1 , v2 ) ; } ; param A returns static abs = ( A ) : number [ ] => { return [ Math . abs ( A [ 0 ] ) , Math . abs ( A [ 1 ] ) ] ; } ; static rescale = ( a , n ) : number [ ] => { const l = Vec . len ( a ) ; return [ ( n * a [ 0 ] ) / l , ( n * a [ 1 ] ) / l ] ; } ; param p1 param pc param p2 static isLeft = ( p1 , pc , p2 ) : number => { return ( pc [ 0 ] - p1 [ 0 ] ) * ( p2 [ 1 ] - p1 [ 1 ] ) - ( p2 [ 0 ] - p1 [ 0 ] ) * ( pc [ 1 ] - p1 [ 1 ] ) ; } ; param p1 param pc param p2 static clockwise = ( p1 , pc , p2 ) : boolean => { return Vec . isLeft ( p1 , pc , p2 ) > 0 ; } ; param a param d static toFixed = ( a , d = 2 ) : number [ ] => { return a . map ( ( v ) => + v . toFixed ( d ) ) ; } ; param A param step example static snap ( a , step = 1 ) { return [ Math . round ( a [ 0 ] / step ) * step , Math . round ( a [ 1 ] / step ) * step ] ; } param A param u param P returns static nearestPointOnLineThroughPoint = ( A , u , P ) : number [ ] => { return Vec . add ( A , Vec . mul ( u , Vec . pry ( Vec . sub ( P , A ) , u ) ) ) ; } ; param A param u param P returns static distanceToLineThroughPoint = ( A , u , P ) : number => { return Vec . dist ( P , Vec . nearestPointOnLineThroughPoint ( A , u , P ) ) ; } ; param A param B param P param clamp returns static nearestPointOnLineSegment = ( A , B , P , clamp = true ) : number [ ] => { const u = Vec . uni ( Vec . sub ( B , A ) ) ; const C = Vec . add ( A , Vec . mul ( u , Vec . pry ( Vec . sub ( P , A ) , u ) ) ) ; if ( clamp ) { if ( C [ 0 ] < Math . min ( A [ 0 ] , B [ 0 ] ) ) return A [ 0 ] < B [ 0 ] ? A : B ; if ( C [ 0 ] > Math . max ( A [ 0 ] , B [ 0 ] ) ) return A [ 0 ] > B [ 0 ] ? A : B ; if ( C [ 1 ] < Math . min ( A [ 1 ] , B [ 1 ] ) ) return A [ 1 ] < B [ 1 ] ? A : B ; if ( C [ 1 ] > Math . max ( A [ 1 ] , B [ 1 ] ) ) return A [ 1 ] > B [ 1 ] ? A : B ; } return C ; } ; param A param B param P param clamp returns static distanceToLineSegment = ( A , B , P , clamp = true ) : number => { return Vec . dist ( P , Vec . nearestPointOnLineSegment ( A , B , P , clamp ) ) ; } ; param A param B param d returns static nudge = ( A , B , d ) : number [ ] => { if ( Vec . isEqual ( A , B ) ) return A ; return Vec . add ( A , Vec . mul ( Vec . uni ( Vec . sub ( B , A ) ) , d ) ) ; } ; param A param B param d static nudgeAtAngle = ( A , a , d ) : number [ ] => { return [ Math . cos ( a ) * d + A [ 0 ] , Math . sin ( a ) * d + A [ 1 ] ] ; } ; param a param n static toPrecision = ( a , n = 4 ) : number [ ] => { return [ + a [ 0 ] . toPrecision ( n ) , + a [ 1 ] . toPrecision ( n ) ] ; } ; param A param B param steps static pointsBetween = ( A , B , steps = 6 ) : number [ ] [ ] => { return Array . from ( Array ( steps ) ) . map ( ( _ , i ) => { const t = i / ( steps - 1 ) ; const k = Math . min ( 1 , 0.5 + Math . abs ( 0.5 - t ) ) ; return [ ... Vec . lrp ( A , B , t ) , k ] ; } ) ; } ; param A param B static slope = ( A , B ) => { if ( A [ 0 ] === B [ 0 ] ) return NaN ; return ( A [ 1 ] - B [ 1 ] ) / ( A [ 0 ] - B [ 0 ] ) ; } ; /**
     * Get a vector comprised of the maximum of two or more vectors.
     */ static max = ( ... v ) => { return [ Math . max ( ... v . map ( ( a ) => a [ 0 ] ) ) , Math . max ( ... v . map ( ( a ) => a [ 1 ] ) ) ] ; } ; /**
     * Get a vector comprised of the minimum of two or more vectors.
     */ static min = ( ... v ) => { return [ Math . max ( ... v . map ( ( a ) => a [ 0 ] ) ) , Math . max ( ... v . map ( ( a ) => a [ 1 ] ) ) ] ; } ; } export default Vec ;