export type Vector2 < V extends number = number > = { x : V ; y : V ; } ; export function v2 < V extends number > ( x ? , y ? ) { return { x : x || 0 as V , y : y || 0 as V } ; } export const copy = ( out , a ) => { out . x = a . x ; out . y = a . y ; return out ; } ; export const set = < V extends number > ( out , x , y ) => { out . x = x ; out . y = y ; return out ; } ; export const add = < V extends number > ( out , a , b ) => { out . x = a . x + b . x as V ; out . y = a . y + b . y as V ; return out ; } ; export const sub = < V extends number > ( out , a , b ) => { out . x = a . x - b . x as V ; out . y = a . y - b . y as V ; return out ; } ; export const dot = < V extends number > ( a , b ) => a . x * b . x + a . y * b . y ; export const scale = < V extends number > ( out , a , factor ) => { out . x = a . x * factor as V ; out . y = a . y * factor as V ; return out ; } ; export const distance = < V extends number > ( v1 , v2 ) => { const x = v1 . x - v2 . x ; const y = v1 . y - v2 . y ; return Math . sqrt ( x * x + y * y ) ; } ; export const distance2 = < V extends number > ( v1 , v2 ) => { const x = v1 . x - v2 . x ; const y = v1 . y - v2 . y ; return x * x + y * y ; } ; export const magnitude = < V extends number > ( v1 ) => { const x = v1 . x ; const y = v1 . y ; return Math . sqrt ( x * x + y * y ) ; } ; export const normalize = < V extends number > ( out , a ) => { const x = a . x ; const y = a . y ; let len = x * x + y * y ; if ( len > 0 ) { len = 1 / Math . sqrt ( len ) ; out . x = a . x * len as V ; out . y = a . y * len as V ; } return out ; } ; /**
 * Compute the normal pointing away perpendicular from two vectors.
 * Given v1(0,0) -> v2(10, 0), the normal will be (0, 1)
 * */ export const normal = < V extends number > ( out , v1 , v2 ) => { out . y = v2 . x - v1 . x as V ; out . x = v1 . y - v2 . y as V ; return normalize ( out , out ) ; } ; export const perpDot = < V extends number > ( v1 , v2 ) => { return v1 . x * v2 . y - v1 . y * v2 . x ; } ; param by param vN export const translate = < V extends number > ( by , ... vN ) => { for ( let i = 0 ; i < vN . length ; i ++ ) { const v = vN [ i ] ; add ( v , v , by ) ; } } ; param v export function vd ( v ) { return `(${ v . x }, ${ v . y })` ; } /**
 * Rotate a vector around another point. Taken nearly verbatim from gl-matrix
 */ export const rotate2d = < V extends Vector2 > ( out , target , origin , rad ) => { const p0 = target . x - origin . x ; const p1 = target . y - origin . y ; const sinC = Math . sin ( rad ) ; const cosC = Math . cos ( rad ) ; out . x = p0 * cosC - p1 * sinC + origin . x ; out . y = p0 * sinC + p1 * cosC + origin . y ; return out ; } ; /**
 * Compute the Theta angle between a vector and the origin.
 */ export function angleOf ( v ) { return Math . atan2 ( v . y , v . x ) ; }