1
0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-06-26 14:38:30 +02:00
VVVVVV/mobile_version/src/starling/utils/MathUtil.as

124 lines
4.8 KiB
ActionScript
Raw Normal View History

// =================================================================================================
//
// Starling Framework
// Copyright Gamua GmbH. All Rights Reserved.
//
// This program is free software. You can redistribute and/or modify it
// in accordance with the terms of the accompanying license agreement.
//
// =================================================================================================
package starling.utils
{
import flash.geom.Point;
import flash.geom.Vector3D;
import starling.errors.AbstractClassError;
/** A utility class containing methods you might need for math problems. */
public class MathUtil
{
private static const TWO_PI:Number = Math.PI * 2.0;
/** @private */
public function MathUtil() { throw new AbstractClassError(); }
/** Calculates the intersection point between the xy-plane and an infinite line
* that is defined by two 3D points in the same coordinate system. */
public static function intersectLineWithXYPlane(pointA:Vector3D, pointB:Vector3D,
out:Point=null):Point
{
if (out == null) out = new Point();
var vectorX:Number = pointB.x - pointA.x;
var vectorY:Number = pointB.y - pointA.y;
var vectorZ:Number = pointB.z - pointA.z;
var lambda:Number = -pointA.z / vectorZ;
out.x = pointA.x + lambda * vectorX;
out.y = pointA.y + lambda * vectorY;
return out;
}
/** Calculates if the point <code>p</code> is inside the triangle <code>a-b-c</code>. */
public static function isPointInTriangle(p:Point, a:Point, b:Point, c:Point):Boolean
{
// This algorithm is described well in this article:
// http://www.blackpawn.com/texts/pointinpoly/default.html
var v0x:Number = c.x - a.x;
var v0y:Number = c.y - a.y;
var v1x:Number = b.x - a.x;
var v1y:Number = b.y - a.y;
var v2x:Number = p.x - a.x;
var v2y:Number = p.y - a.y;
var dot00:Number = v0x * v0x + v0y * v0y;
var dot01:Number = v0x * v1x + v0y * v1y;
var dot02:Number = v0x * v2x + v0y * v2y;
var dot11:Number = v1x * v1x + v1y * v1y;
var dot12:Number = v1x * v2x + v1y * v2y;
var invDen:Number = 1.0 / (dot00 * dot11 - dot01 * dot01);
var u:Number = (dot11 * dot02 - dot01 * dot12) * invDen;
var v:Number = (dot00 * dot12 - dot01 * dot02) * invDen;
return (u >= 0) && (v >= 0) && (u + v < 1);
}
/** Moves a radian angle into the range [-PI, +PI], while keeping the direction intact. */
public static function normalizeAngle(angle:Number):Number
{
// move to equivalent value in range [0 deg, 360 deg] without a loop
angle = angle % TWO_PI;
// move to [-180 deg, +180 deg]
if (angle < -Math.PI) angle += TWO_PI;
if (angle > Math.PI) angle -= TWO_PI;
return angle;
}
/** Returns the next power of two that is equal to or bigger than the specified number. */
public static function getNextPowerOfTwo(number:Number):int
{
if (number is int && number > 0 && (number & (number - 1)) == 0) // see: http://goo.gl/D9kPj
return number;
else
{
var result:int = 1;
number -= 0.000000001; // avoid floating point rounding errors
while (result < number) result <<= 1;
return result;
}
}
/** Indicates if two float (Number) values are equal, give or take <code>epsilon</code>. */
public static function isEquivalent(a:Number, b:Number, epsilon:Number=0.0001):Boolean
{
return (a - epsilon < b) && (a + epsilon > b);
}
/** Returns the larger of the two values. Different to the native <code>Math.max</code>,
* this doesn't create any temporary objects when using the AOT compiler. */
public static function max(a:Number, b:Number):Number
{
return a > b ? a : b;
}
/** Returns the smaller of the two values. Different to the native <code>Math.min</code>,
* this doesn't create any temporary objects when using the AOT compiler. */
public static function min(a:Number, b:Number):Number
{
return a < b ? a : b;
}
/** Moves <code>value</code> into the range between <code>min</code> and <code>max</code>. */
public static function clamp(value:Number, min:Number, max:Number):Number
{
return value < min ? min : (value > max ? max : value);
}
}
}