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; } } }