UNPKG

leapmotion-ts

Version:

TypeScript framework for Leap Motion.

251 lines (220 loc) 8.13 kB
/// <reference path="./../Vector3.ts"/> /// <reference path="./../Matrix.ts"/> /** * LeapUtil is a collection of static utility functions. * */ export class LeapUtil { /** The constant pi as a single precision floating point number. */ public static PI:number = 3.1415926536; /** * The constant ratio to convert an angle measure from degrees to radians. * Multiply a value in degrees by this constant to convert to radians. */ public static DEG_TO_RAD:number = 0.0174532925; /** * The constant ratio to convert an angle measure from radians to degrees. * Multiply a value in radians by this constant to convert to degrees. */ public static RAD_TO_DEG:number = 57.295779513; /** * Pi &#42; 2. */ public static TWO_PI:number = Math.PI + Math.PI; /** * Pi &#42; 0.5. */ public static HALF_PI:number = Math.PI * 0.5; /** * Represents the smallest positive single value greater than zero. */ public static EPSILON:number = 0.00001; constructor() { } /** * Convert an angle measure from radians to degrees. * * @param radians * @return The value, in degrees. * */ public static toDegrees( radians:number ):number { return radians * 180 / Math.PI; } /** * Determines if a value is equal to or less than 0.00001. * * @return True, if equal to or less than 0.00001; false otherwise. */ public static isNearZero( value:number ):boolean { return Math.abs( value ) <= LeapUtil.EPSILON; } /** * Determines if all Vector3 components is equal to or less than 0.00001. * * @return True, if equal to or less than 0.00001; false otherwise. */ public static vectorIsNearZero( inVector:Vector3 ):boolean { return this.isNearZero( inVector.x ) && this.isNearZero( inVector.y ) && this.isNearZero( inVector.z ); } /** * Create a new matrix with just the rotation block from the argument matrix */ public static extractRotation( mtxTransform:Matrix ):Matrix { return new Matrix( mtxTransform.xBasis, mtxTransform.yBasis, mtxTransform.zBasis ); } /** * Returns a matrix representing the inverse rotation by simple transposition of the rotation block. */ public static rotationInverse( mtxRot:Matrix ):Matrix { return new Matrix( new Vector3( mtxRot.xBasis.x, mtxRot.yBasis.x, mtxRot.zBasis.x ), new Vector3( mtxRot.xBasis.y, mtxRot.yBasis.y, mtxRot.zBasis.y ), new Vector3( mtxRot.xBasis.z, mtxRot.yBasis.z, mtxRot.zBasis.z ) ); } /** * Returns a matrix that is the orthonormal inverse of the argument matrix. * This is only valid if the input matrix is orthonormal * (the basis vectors are mutually perpendicular and of length 1) */ public static rigidInverse( mtxTransform:Matrix ):Matrix { var rigidInverse:Matrix = this.rotationInverse( mtxTransform ); rigidInverse.origin = rigidInverse.transformDirection( mtxTransform.origin.opposite() ); return rigidInverse; } public static componentWiseMin( vLHS:Vector3, vRHS:Vector3 ):Vector3 { return new Vector3( Math.min( vLHS.x, vRHS.x ), Math.min( vLHS.y, vRHS.y ), Math.min( vLHS.z, vRHS.z ) ); } public static componentWiseMax( vLHS:Vector3, vRHS:Vector3 ):Vector3 { return new Vector3( Math.max( vLHS.x, vRHS.x ), Math.max( vLHS.y, vRHS.y ), Math.max( vLHS.z, vRHS.z ) ); } public static componentWiseScale( vLHS:Vector3, vRHS:Vector3 ):Vector3 { return new Vector3( vLHS.x * vRHS.x, vLHS.y * vRHS.y, vLHS.z * vRHS.z ); } public static componentWiseReciprocal( inVector:Vector3 ):Vector3 { return new Vector3( 1.0 / inVector.x, 1.0 / inVector.y, 1.0 / inVector.z ); } public static minComponent( inVector:Vector3 ):number { return Math.min( inVector.x, Math.min( inVector.y, inVector.z ) ); } public static maxComponent( inVector:Vector3 ):number { return Math.max( inVector.x, Math.max( inVector.y, inVector.z ) ); } /** * Compute the polar/spherical heading of a vector direction in z/x plane */ public static heading( inVector:Vector3 ):number { return Math.atan2( inVector.z, inVector.x ); } /** * Compute the spherical elevation of a vector direction in y above the z/x plane */ public static elevation( inVector:Vector3 ):number { return Math.atan2( inVector.y, Math.sqrt( inVector.z * inVector.z + inVector.x * inVector.x ) ); } /** * Set magnitude to 1 and bring heading to [-Pi,Pi], elevation into [-Pi/2, Pi/2] * * @param vSpherical The Vector3 to convert. * @return The normalized spherical Vector3. * */ public static normalizeSpherical( vSpherical:Vector3 ):Vector3 { var fHeading:number = vSpherical.y; var fElevation:number = vSpherical.z; while ( fElevation <= -Math.PI ) fElevation += LeapUtil.TWO_PI; while ( fElevation > Math.PI ) fElevation -= LeapUtil.TWO_PI; if ( Math.abs( fElevation ) > LeapUtil.HALF_PI ) { fHeading += Math.PI; fElevation = fElevation > 0 ? ( Math.PI - fElevation ) : -( Math.PI + fElevation ); } while ( fHeading <= -Math.PI ) fHeading += LeapUtil.TWO_PI; while ( fHeading > Math.PI ) fHeading -= LeapUtil.TWO_PI; return new Vector3( 1, fHeading, fElevation ); } /** * Convert from Cartesian (rectangular) coordinates to spherical coordinates * (magnitude, heading, elevation). * * @param vCartesian The Vector3 to convert. * @return The cartesian Vector3 converted to spherical. * */ public static cartesianToSpherical( vCartesian:Vector3 ):Vector3 { return new Vector3( vCartesian.magnitude(), this.heading( vCartesian ), this.elevation( vCartesian ) ); } /** * Convert from spherical coordinates (magnitude, heading, elevation) to * Cartesian (rectangular) coordinates. * * @param vSpherical The Vector3 to convert. * @return The spherical Vector3 converted to cartesian. * */ public static sphericalToCartesian( vSpherical:Vector3 ):Vector3 { var fMagnitude:number = vSpherical.x; var fCosHeading:number = Math.cos( vSpherical.y ); var fSinHeading:number = Math.sin( vSpherical.y ); var fCosElevation:number = Math.cos( vSpherical.z ); var fSinElevation:number = Math.sin( vSpherical.z ); return new Vector3( fCosHeading * fCosElevation * fMagnitude, fSinElevation * fMagnitude, fSinHeading * fCosElevation * fMagnitude); } /** * Clamps a value between a minimum Number and maximum Number value. * * @param inVal The number to clamp. * @param minVal The minimum value. * @param maxVal The maximum value. * @return The value clamped between minVal and maxVal. * */ public static clamp( inVal:number, minVal:number, maxVal:number ):number { return ( inVal < minVal ) ? minVal : (( inVal > maxVal ) ? maxVal : inVal ); } /** * Linearly interpolates between two Numbers. * * @param a A number. * @param b A number. * @param coefficient The interpolation coefficient [0-1]. * @return The interpolated number. * */ public static lerp( a:number, b:number, coefficient:number ):number { return a + ( ( b - a ) * coefficient ); } /** * Linearly interpolates between two Vector3 objects. * * @param vec1 A Vector3 object. * @param vec2 A Vector3 object. * @param coefficient The interpolation coefficient [0-1]. * @return A new interpolated Vector3 object. * */ public static lerpVector( vec1:Vector3, vec2:Vector3, coefficient:number ):Vector3 { return vec1.plus( vec2.minus( vec1 ).multiply( coefficient ) ); } }