import { Vector3 } from "./Vector3" ; hidden namespace Private { export namespace getClosestPointOnLine { export const vc = new Vector3 ( ) ; export const vd = new Vector3 ( ) ; } } export class MathEx { static PI2 = Math . PI * 2 ; static EPSILON = .000001 ; static degreesToRadians = 0.017453288 ; static radiansToDegrees = 57.29579143 ; static toRadians ( angleDegrees ) { return angleDegrees * MathEx . degreesToRadians ; } static toDegrees ( angleRadians ) { return angleRadians * MathEx . radiansToDegrees ; } static clamp ( value , min , max ) { return value < min ? min : ( value > max ? max : value ) ; } static isZero ( value ) { return value > - MathEx . EPSILON && value < MathEx . EPSILON ; } static isEqual ( a , b ) { return MathEx . isZero ( Math . abs ( a - b ) ) ; } static lerp ( src , dest , factor ) { return src + ( dest - src ) * factor ; } static ceilPowerOfTwo ( value ) { return Math . pow ( 2 , Math . ceil ( Math . log ( value ) / Math . LN2 ) ) ; } static sphericalToCartesian ( radius , azimuth , inclination , result ) { result . x = radius * Math . cos ( azimuth ) * Math . sin ( inclination ) ; result . y = radius * Math . sin ( azimuth ) * Math . sin ( inclination ) ; result . z = radius * Math . cos ( inclination ) ; return result ; } static getClosestPointOnLine ( p , a , b , out ) { let { vc , vd } = Private . getClosestPointOnLine ; vc . substractVectors ( p , a ) ; vd . substractVectors ( b , a ) ; let length = vd . length ; vd . multiply ( 1 / length ) ; let t = vd . dot ( vc ) ; if ( t < 0 ) { return a ; } else if ( t > length ) { return b ; } return out . copy ( vd ) . multiply ( t ) . add ( a ) ; } static getNextPow2 ( i ) { -- i ; i |= i >> 1 ; i |= i >> 2 ; i |= i >> 4 ; i |= i >> 8 ; i |= i >> 16 ; ++ i ; return i ; } static isPowerOf2 ( value ) { return ( value & ( value - 1 ) ) === 0 ; } static euclideanModulo ( n , m ) { return ( ( n % m ) + m ) % m ; } }