using System;
namespace BansheeEngine
{
///
/// Values that represent in which order are euler angles applied when used in transformations.
///
public enum EulerAngleOrder
{
XYZ,
XZY,
YXZ,
YZX,
ZXY,
ZYX
};
///
/// Utility class providing common scalar math operations.
///
class MathEx
{
///
/// Pi constant.
///
public const float Pi = 3.141593f;
///
/// Two times pi constant.
///
public const float TwoPi = (2.0f * Pi);
///
/// Half of pi constant.
///
public const float HalfPi = (0.5f * Pi);
///
/// Constant that converts degrees to radians.
///
public const float Deg2Rad = Pi / 180.0f;
///
/// Constant that converts radians to degrees.
///
public const float Rad2Deg = 180.0f / Pi;
///
/// Returns the minimum value of the two provided.
///
/// First value to compare.
/// Second value to compare.
/// Minimum of the two values.
public static float Min(float a, float b)
{
if (a < b)
return a;
return b;
}
///
/// Returns the minimum value of all the values provided.
///
/// Values to compare.
/// Minimum of all the values.
public static float Min(params float[] values)
{
int length = values.Length;
if (length == 0)
return 0.0f;
float min = values[0];
for (int i = 1; i < length; i++)
{
if (values[i] < min)
min = values[i];
}
return min;
}
///
/// Returns the minimum value of the two provided.
///
/// First value to compare.
/// Second value to compare.
/// Minimum of the two values.
public static int Min(int a, int b)
{
if (a < b)
return a;
return b;
}
///
/// Returns the minimum value of all the values provided.
///
/// Values to compare.
/// Minimum of all the values.
public static int Min(params int[] values)
{
int length = values.Length;
if (length == 0)
return 0;
int min = values[0];
for (int i = 1; i < length; i++)
{
if (values[i] < min)
min = values[i];
}
return min;
}
///
/// Returns the maximum value of the two provided.
///
/// First value to compare.
/// Second value to compare.
/// Maximum of the two values.
public static float Max(float a, float b)
{
if (a > b)
return a;
return b;
}
///
/// Returns the maximum value of all the values provided.
///
/// Values to compare.
/// Maximum of all the values.
public static float Max(params float[] values)
{
int length = values.Length;
if (length == 0)
return 0.0f;
float max = values[0];
for (int i = 1; i < length; i++)
{
if (values[i] > max)
max = values[i];
}
return max;
}
///
/// Returns the maximum value of the two provided.
///
/// First value to compare.
/// Second value to compare.
/// Maximum of the two values.
public static int Max(int a, int b)
{
if (a > b)
return a;
else
return b;
}
///
/// Returns the maximum value of all the values provided.
///
/// Values to compare.
/// Maximum of all the values.
public static int Max(params int[] values)
{
int length = values.Length;
if (length == 0)
return 0;
int max = values[0];
for (int i = 1; i < length; ++i)
{
if (values[i] > max)
max = values[i];
}
return max;
}
///
/// Returns the absolute value of the provided parameter.
///
/// Parameter to take absolute value of.
/// Absolute value of .
public static float Abs(float f)
{
return Math.Abs(f);
}
///
/// Returns the absolute value of the provided parameter.
///
/// Parameter to take absolute value of.
/// Absolute value of .
public static int Abs(int value)
{
return Math.Abs(value);
}
///
/// Raises to the power of .
///
/// Value to raise to a power.
/// Power to raise the value to.
/// raised to the power of .
public static float Pow(float f, float p)
{
return (float)Math.Pow(f, p);
}
///
/// Raises e to the power of .
///
/// Power to raise e to.
/// e raised to the power of .
public static float Exp(float power)
{
return (float)Math.Exp(power);
}
///
/// Returns the logarithm of a number in a specified base.
///
/// Value to get the logarithm of.
/// Base of the logarithm
/// Logarithm of a number in the specified base.
public static float Log(float f, float p)
{
return (float)Math.Log(f, p);
}
///
/// Returns the natural logarithm (base e).
///
/// Value to get the logarithm of.
/// Natural logarithm of a number.
public static float Log(float f)
{
return (float)Math.Log(f);
}
///
/// Returns the logarithm of a number in base 10.
///
/// Value to get the logarithm of.
/// Logarithm of a number in base 10.
public static float Log10(float f)
{
return (float)Math.Log10(f);
}
///
/// Returns the smallest integral value that is greater than or equal to the provided value.
///
/// Value to round.
/// Smallest integral value that is greater than or equal to the provided value.
public static float Ceil(float f)
{
return (float)Math.Ceiling(f);
}
///
/// Returns the largest integral value that is lesser than or equal to the provided value.
///
/// Value to round.
/// Largest integral value that is lessert than or equal to the provided value.
public static float Floor(float f)
{
return (float)Math.Floor(f);
}
///
/// Rounds the provided value to the nearest integral.
///
/// Value to round.
/// Value rounded to the nearest integral.
public static float Round(float f)
{
return (float)Math.Round(f);
}
///
/// Returns the smallest integral value that is greater than or equal to the provided value.
///
/// Value to round.
/// Smallest integral value that is greater than or equal to the provided value.
public static int CeilToInt(float f)
{
return (int)Math.Ceiling(f);
}
///
/// Returns the largest integral value that is lesser than or equal to the provided value.
///
/// Value to round.
/// Largest integral value that is lessert than or equal to the provided value.
public static int FloorToInt(float f)
{
return (int)Math.Floor(f);
}
///
/// Rounds the provided value to the nearest integral.
///
/// Value to round.
/// Value rounded to the nearest integral.
public static int RoundToInt(float f)
{
return (int)Math.Round(f);
}
///
/// Returns the sign of the provided value (positive or negative).
///
/// Value to get the sign of.
/// -1.0f if negative or 1.0f if positive.
public static float Sign(float f)
{
return f >= 0.0f ? 1.0f : -1.0f;
}
///
/// Returns the sine of the provided value.
///
/// Angle in radians.
/// Sine of the angle.
public static float Sin(float f)
{
return (float)Math.Sin(f);
}
///
/// Returns the cosine of the provided value.
///
/// Angle in radians.
/// Cosine of the angle.
public static float Cos(float f)
{
return (float)Math.Cos(f);
}
///
/// Returns the tangent of the provided value.
///
/// Angle in radians.
/// Tangent of the angle.
public static float Tan(float f)
{
return (float)Math.Tan(f);
}
///
/// Returns the angle whose sine is the specified number.
///
/// Sine of an angle.
/// Angle in radians.
public static float Asin(float f)
{
return (float)Math.Asin(f);
}
///
/// Returns the angle whose cosine is the specified number.
///
/// Cosine of an angle.
/// Angle in radians.
public static float Acos(float f)
{
return (float)Math.Acos(f);
}
///
/// Returns the angle whose tangent is the specified number.
///
/// Tangent of an angle.
/// Angle in radians.
public static float Atan(float f)
{
return (float)Math.Atan(f);
}
///
/// Returns an angle of a point.
///
/// Y coordinate of the point.
/// X coordinate of the point.
/// Angle in radians in range [Pi, -Pi].
public static float Atan2(float y, float x)
{
return (float)Math.Atan2(y, x);
}
///
/// Returns the sine of the provided value.
///
/// Angle in radians.
/// Sine of the angle.
public static float Sin(Radian f)
{
return (float)Math.Sin(f.Radians);
}
///
/// Returns the cosine of the provided value.
///
/// Angle in radians.
/// Cosine of the angle.
public static float Cos(Radian f)
{
return (float)Math.Cos(f.Radians);
}
///
/// Returns the tangent of the provided value.
///
/// Angle in radians.
/// Tangent of the angle.
public static float Tan(Radian f)
{
return (float)Math.Tan(f.Radians);
}
///
/// Returns the angle whose sine is the specified number.
///
/// Sine of an angle.
/// Angle in radians.
public static float Asin(Radian f)
{
return (float)Math.Asin(f.Radians);
}
///
/// Returns the angle whose cosine is the specified number.
///
/// Cosine of an angle.
/// Angle in radians.
public static float Acos(Radian f)
{
return (float)Math.Acos(f.Radians);
}
///
/// Returns the angle whose tangent is the specified number.
///
/// Tangent of an angle.
/// Angle in radians.
public static float Atan(Radian f)
{
return (float)Math.Atan(f.Radians);
}
///
/// Returns an angle of a point.
///
/// Y coordinate of the point.
/// X coordinate of the point.
/// Angle in radians in range [Pi, -Pi].
public static float Atan2(Radian y, Radian x)
{
return (float)Math.Atan2(y.Radians, x.Radians);
}
///
/// Returns a square root of the provided value.
///
/// Value to take the square root of. Must not be negative.
/// Square root of the provided value.
public static float Sqrt(float f)
{
return (float)Math.Sqrt(f);
}
///
/// Returns an inverse square root (1/sqrt(x)) of the provided value.
///
/// Value to take the inverse square root of. Must not be negative or zero.
/// Inverse square root of the provided value.
public static float InvSqrt(float f)
{
return 1.0f/(float) Math.Sqrt(f);
}
///
/// Clamps a value between two other values.
///
/// Value to clamp.
/// Minimum value of the range to clamp. Must be lower than
/// Maximum value of the range to clamp. Must be higher than
/// Returns unchanged value if it is in valid range, otherwise returns value clamped to the range
/// extremes.
public static float Clamp(float value, float min, float max)
{
if (value < min)
value = min;
else if (value > max)
value = max;
return value;
}
///
/// Clamps a value between two other values.
///
/// Value to clamp.
/// Minimum value of the range to clamp. Must be lower than
/// Maximum value of the range to clamp. Must be higher than
/// Returns unchanged value if it is in valid range, otherwise returns value clamped to the range
/// extremes.
public static int Clamp(int value, int min, int max)
{
if (value < min)
value = min;
else if (value > max)
value = max;
return value;
}
///
/// Clamps a value between zero and one.
///
/// Value to clamp.
/// Returns unchanged value if it is in [0, 1] range, otherwise returns value clamped to the range.
///
public static float Clamp01(float value)
{
if (value < 0.0)
return 0.0f;
if (value > 1.0)
return 1f;
return value;
}
///
/// Wraps an angle in [0, 360) range. Values lower than zero, or higher or equal to 360
/// will get wrapped around back into [0, 360) range.
///
/// Angle to wrap.
/// Angle in [0, 360) range.
public static Degree WrapAngle(Degree angle)
{
const float inv360 = 1.0f/360.0f;
float angleVal = angle.Degrees;
float wrapCount = (float)MathEx.Floor(MathEx.Abs(angleVal * inv360));
if (angleVal > 0.0f)
angleVal -= 360.0f * wrapCount;
else
angleVal += 360.0f * wrapCount;
return new Degree(angleVal);
}
///
/// Compares two floating point numbers with an error margin.
///
/// First number to compare.
/// Second number to compare.
/// Error margin within which the numbers should be considered equal.
/// True if equal, false otherwise.
public static bool ApproxEquals(float a, float b, float epsilon = 1.192092896e-07F)
{
return Abs(b - a) <= epsilon;
}
}
}