leapmotion-ts
Version:
TypeScript framework for Leap Motion.
251 lines (220 loc) • 8.13 kB
text/typescript
/// <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 * 2.
*/
public static TWO_PI:number = Math.PI + Math.PI;
/**
* Pi * 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 ) );
}
}