/Utilities/Helpers/MathHelper.cs
# · C# · 1153 lines · 639 code · 101 blank · 413 comment · 16 complexity · 06cf255bf32c37245088c5a434cf6eda MD5 · raw file
- using System;
- using Delta.Utilities.Datatypes;
- using NUnit.Framework;
-
- namespace Delta.Utilities.Helpers
- {
- /// <summary>
- /// Math helper class. Provides the same functionality as System.Math, but
- /// instead of using doubles for all the functions here are using floats!
- /// </summary>
- public static class MathHelper
- {
- #region Constants
- /// <summary>
- /// Epsilon is a small comparison offset for NearlyEqual checks.
- /// Note: Other frameworks use float.Epsilon (1.192092896e-07f), but we
- /// work great with this value too, so we should keep it this way.
- /// </summary>
- public const float Epsilon = 0.0001f;
-
- /// <summary>
- /// E constant as a float (2.718282).
- /// </summary>
- public const float E = 2.718282f;
-
- /// <summary>
- /// Pi constants, same as PI (double), but as a float here (less precise),
- /// please note that we usually use degrees and not radians in the engine!
- /// </summary>
- public const float Pi = 3.14159265359f;
-
- /// <summary>
- /// Pi times two for getting around a whole circle (360 degrees).
- /// </summary>
- public const float PiDouble = Pi * 2.0f;
-
- /// <summary>
- /// Pi Half, which represents 90 degrees.
- /// </summary>
- public const float PiHalf = Pi * 0.5f;
-
- /// <summary>
- /// Pi Quarter, which represents 45 degrees.
- /// </summary>
- public const float PiQuarter = PiHalf * 0.5f;
-
- /// <summary>
- /// Represents just the fraction of 1/3 or in decimal 0.333333
- /// </summary>
- public const float OneThird = 1.0f / 3.0f;
-
- /// <summary>
- /// The default value for an invalid index check (-1), very often used to
- /// set invalid and initial values to integer values to make sure that we
- /// initialize them first before using them, e.g. for shader parameters or
- /// for indices in precomputed arrays, but also often used by the .NET
- /// framework, e.g String.IndexOf returns -1 for not found.
- /// </summary>
- public const int InvalidIndex = -1;
-
- /// <summary>
- /// Sinus value of 45 Degree
- /// </summary>
- public const float Sin45 = 0.707106781f;
-
- /// <summary>
- /// Half of the short max. value (32768), which is 16392. This is used
- /// for the calculation of ViewProjection2DViaShorts and in the
- /// MaterialManager to setup compressed vertices.
- /// </summary>
- public const short HalfShortMaxValue = short.MaxValue / 2;
- #endregion
-
- #region NearlyEqual (Static)
- /// <summary>
- /// Compares two floats if they are almost equal, taking an Epsilon offset
- /// (see Math.Epsilon) into account.
- /// </summary>
- /// <param name="value1">first float</param>
- /// <param name="value2">second float</param>
- /// <returns>Bool: True if Nearly Equal</returns>
- public static bool NearlyEqual(this float value1, float value2)
- {
- float difference = Abs(value1 - value2);
- return difference <= Epsilon;
- }
- #endregion
-
- #region InvertScalar (Static)
- /// <summary>
- /// Invert scalar safely.
- /// </summary>
- /// <param name="value">Value</param>
- /// <returns>1.0f</returns>
- public static float InvertScalar(float value)
- {
- if (Abs(value) < Epsilon)
- {
- return float.MaxValue;
- }
- return 1.0f / value;
- }
- #endregion
-
- #region Clamp (Static)
- /// <summary>
- /// Clamps the value between [0, 1].
- /// </summary>
- /// <param name="value">Value</param>
- /// <returns>Clamp Value</returns>
- public static int Clamp(int value)
- {
- return Clamp(value, 0, 1);
- }
-
- /// <summary>
- /// Clamps the value between the given range [minimum, maximum].
- /// </summary>
- /// <param name="max">Max</param>
- /// <param name="min">Min</param>
- /// <param name="value">Value</param>
- /// <returns>value between the given range [minimum, maximum]</returns>
- public static int Clamp(int value, int min, int max)
- {
- return Min(Max(value, min), max);
- }
-
- /// <summary>
- /// Clamps the value between [0.0, 1.0].
- /// </summary>
- /// <param name="value">Value</param>
- /// <returns>value between [0.0, 1.0]</returns>
- public static float Clamp(float value)
- {
- return Clamp(value, 0.0f, 1.0f);
- }
-
- /// <summary>
- /// Clamps the value between the given range [minimum, maximum].
- /// </summary>
- /// <param name="max">Max</param>
- /// <param name="min">Min</param>
- /// <param name="value">Value</param>
- /// <returns>value between the given range [minimum, maximum]</returns>
- public static float Clamp(float value, float min, float max)
- {
- return Min(Max(value, min), max);
- }
- #endregion
-
- #region Wrap (Static)
- /// <summary>
- /// Wrap the value between the given range [minimun, maximum].
- /// </summary>
- /// <param name="max">Max</param>
- /// <param name="min">Min</param>
- /// <param name="value">Value</param>
- /// <returns>value between the given range [minimun, maximum]</returns>
- public static int Wrap(int value, int min, int max)
- {
- int delta = max - min;
- if (value > delta)
- {
- value = value / delta;
- value = value - (int)Math.Floor((double)value);
- value = value * delta;
- }
- return value;
- }
-
- /// <summary>
- /// Wrap the value between the given range [minimun, maximum].
- /// </summary>
- /// <param name="max">Max</param>
- /// <param name="min">Min</param>
- /// <param name="value">Value</param>
- /// <returns>The wrapped Value</returns>
- public static float Wrap(float value, float min, float max)
- {
- float delta = max - min;
- if (value > delta)
- {
- value = value / delta;
- value = value - (float)Math.Floor(value);
- value = value * delta;
- }
- return value;
- }
- #endregion
-
- #region Distance (Static)
- /// <summary>
- /// Distance between two float values.
- /// </summary>
- /// <param name="value1">First float value</param>
- /// <param name="value2">Second float value</param>
- /// <returns>Distance between the two values, always positive</returns>
- public static float Distance(float value1, float value2)
- {
- return Abs(value1 - value2);
- }
- #endregion
-
- #region Min (Static)
- /// <summary>
- /// Returns the smaller of two values.
- /// </summary>
- /// <param name="value1">Value 1</param>
- /// <param name="value2">Value 2</param>
- /// <returns>the smaller of two values</returns>
- public static float Min(float value1, float value2)
- {
- return
- value1 < value2
- ? value1
- : value2;
- }
-
- /// <summary>
- /// Returns the smaller of three values.
- /// </summary>
- /// <param name="value1">Value 1</param>
- /// <param name="value2">Value 2</param>
- /// <param name="value3">Value 3</param>
- /// <returns>Returns the smaller of three values</returns>
- public static float Min(float value1, float value2, float value3)
- {
- return Min(Min(value1, value2), value3);
- }
-
- /// <summary>
- /// Returns the smaller of two values.
- /// </summary>
- /// <param name="value1">Value 1</param>
- /// <param name="value2">Value 2</param>
- /// <returns>Returns the smaller of two values</returns>
- public static int Min(int value1, int value2)
- {
- return
- value1 < value2
- ? value1
- : value2;
- }
-
- /// <summary>
- /// Returns the smaller of three values.
- /// </summary>
- /// <param name="value1">Value1</param>
- /// <param name="value2">Value2</param>
- /// <param name="value3">Value3</param>
- /// <returns>eturns the smaller of three values</returns>
- public static int Min(int value1, int value2, int value3)
- {
- return Min(Min(value1, value2), value3);
- }
- #endregion
-
- #region Max (Static)
- /// <summary>
- /// Returns the bigger one of the two values.
- /// </summary>
- /// <param name="value1">Value 1</param>
- /// <param name="value2">Value 2</param>
- /// <returns>Returns the bigger one of the two values</returns>
- public static int Max(int value1, int value2)
- {
- return
- value1 > value2
- ? value1
- : value2;
- }
-
- /// <summary>
- /// Returns the bigger one of the three values.
- /// </summary>
- /// <param name="value1">Value1</param>
- /// <param name="value2">Value2</param>
- /// <param name="value3">Value3</param>
- /// <returns>Returns the bigger one of the three values</returns>
- public static int Max(int value1, int value2, int value3)
- {
- return Max(Max(value1, value2), value3);
- }
-
- /// <summary>
- /// Returns the bigger one of the two values.
- /// </summary>
- /// <param name="value1">Value1</param>
- /// <param name="value2">Value2</param>
- /// <returns>Returns the bigger one of the two values</returns>
- public static float Max(float value1, float value2)
- {
- return
- value1 > value2
- ? value1
- : value2;
- }
-
- /// <summary>
- /// Returns the bigger one of the three values.
- /// </summary>
- /// <param name="value1">Value1</param>
- /// <param name="value2">Value2</param>
- /// <param name="value3">Value3</param>
- /// <returns>Returns the bigger one of the three values</returns>
- public static float Max(float value1, float value2, float value3)
- {
- return Max(Max(value1, value2), value3);
- }
- #endregion
-
- #region Lerp (Static)
- /// <summary>
- /// Performs a linear interpolation between two values.
- /// </summary>
- /// <param name="minValue">Value at "percentage = 0"</param>
- /// <param name="maxValue">Value at "percentage = 1"</param>
- /// <param name="percentage">Percentage in the range [0,1]</param>
- /// <returns>Float</returns>
- public static float Lerp(float minValue, float maxValue, float percentage)
- {
- return minValue + (maxValue - minValue) * percentage;
- }
-
- /// <summary>
- /// Performs a linear interpolation between two values.
- /// </summary>
- /// <param name="minValue">Value at "percentage = 0"</param>
- /// <param name="maxValue">Value at "percentage = 1"</param>
- /// <param name="percentage">Percentage in the range [0,1]</param>
- /// <returns>Float</returns>
- public static int Lerp(int minValue, int maxValue, float percentage)
- {
- return minValue + Round((maxValue - minValue) * percentage);
- }
-
- /// <summary>
- /// Performs a linear interpolation between two values.
- /// </summary>
- /// <param name="minValue">Value at "percentage = 0"</param>
- /// <param name="maxValue">Value at "percentage = 1"</param>
- /// <param name="percentage">Percentage in the range [0,1]</param>
- /// <returns>Float</returns>
- public static long Lerp(long minValue, long maxValue, float percentage)
- {
- return minValue + Round((maxValue - minValue) * percentage);
- }
- #endregion
-
- #region Sqrt (Static)
- /// <summary>
- /// Sqrt
- /// </summary>
- /// <returns>Float</returns>
- public static float Sqrt(float value)
- {
-
- return (float)Math.Sqrt(value);
- }
- #endregion
-
- #region Round (Static)
- /// <summary>
- /// Rounds a value to a given position after the decimal point
- /// </summary>
- /// <param name="value">Value to round</param>
- /// <param name="decimals">Decimals</param>
- /// <returns>Float</returns>
- public static float Round(float value, int decimals)
- {
- return (float)Math.Round(value, decimals);
- }
-
- /// <summary>
- /// Rounds a value to an int
- /// </summary>
- /// <param name="value">Value to round</param>
- /// <returns>Float</returns>
- public static int Round(float value)
- {
- return (int)Math.Round(value);
- }
- #endregion
-
- #region Ceiling (Static)
- /// <summary>
- /// Ceiling
- /// </summary>
- /// <param name="value">Value</param>
- /// <returns>Ceiling</returns>
- public static int Ceiling(float value)
- {
- return (int)Math.Ceiling(value);
- }
- #endregion
-
- #region Abs (Static)
- /// <summary>
- /// Returns the absolute value of a float
- /// </summary>
- /// <param name="value">Value</param>
- /// <returns>Returns the absolute value of a float</returns>
- public static float Abs(float value)
- {
- return
- value < 0f
- ? -value
- : value;
- }
- #endregion
-
- #region Pow (Static)
- /// <summary>
- /// Pow
- /// </summary>
- /// <param name="power">Power</param>
- /// <param name="value">Value</param>
- /// <returns>Power</returns>
- public static float Pow(float value, float power)
- {
- return (float)Math.Pow(value, power);
- }
- #endregion
-
- #region DegreeToRadians (Static)
- /// <summary>
- /// Degree to radians
- /// </summary>
- /// <param name="degrees">Degrees</param>
- /// <returns>Degree to radians</returns>
- public static float DegreeToRadians(this float degrees)
- {
- return degrees * (Pi / 180.0f); //same: * 0.01745329f;
- }
- #endregion
-
- #region RadiansToDegrees (Static)
- /// <summary>
- /// Radians to degrees
- /// </summary>
- /// <param name="radians">Radians</param>
- /// <returns>radians</returns>
- public static float RadiansToDegrees(this float radians)
- {
- return radians * (180.0f / Pi); //same: * 57.29578f;
- }
- #endregion
-
- #region Sin (Static)
- /// <summary>
- /// Return the sinus of a degreeValue. Note: Most other math libraries use
- /// radians, please provide degrees here (used throughout the engine).
- /// </summary>
- /// <param name="degreeValue">Degree value for the sinus</param>
- /// <returns>Sinus of degreeValue</returns>
- public static float Sin(float degreeValue)
- {
- return (float)Math.Sin(degreeValue * (Pi / 180.0f));
- }
- #endregion
-
- #region Cos (Static)
- /// <summary>
- /// Cosinus of a degreeValue, please use degree values here (not radians)
- /// </summary>
- /// <param name="degreeValue">Degree Value for the cosinus</param>
- /// <returns>Cosinus of degreeValue</returns>
- public static float Cos(float degreeValue)
- {
- return (float)Math.Cos(degreeValue * (Pi / 180.0f));
- }
- #endregion
-
- #region Tan (Static)
- /// <summary>
- /// Get the tangent value, again using degrees, not radians.
- /// </summary>
- /// <param name="degreeValue">Degree value for the tagent</param>
- /// <returns>Tangent of degreeValue</returns>
- public static float Tan(float degreeValue)
- {
- return (float)Math.Tan(DegreeToRadians(degreeValue));
- }
- #endregion
-
- #region Asin (Static)
- /// <summary>
- /// Returns the angle in degrees whose sin value is the specified value.
- /// </summary>
- /// <param name="value">Value for asin</param>
- /// <returns>Asin value in degrees from the value</returns>
- public static float Asin(float value)
- {
- return RadiansToDegrees((float)Math.Asin(value));
- }
- #endregion
-
- #region Acos (Static)
- /// <summary>
- /// Returns the angle in degrees whose cos value is the specified value.
- /// </summary>
- /// <param name="value">Value for acos</param>
- /// <returns>Acos value in degrees from the value</returns>
- public static float Acos(float value)
- {
- return RadiansToDegrees((float)Math.Acos(value));
- }
- #endregion
-
- #region Atan (Static)
- /// <summary>
- /// Returns the angle in degrees whose tangent is the specified number.
- /// Use Atan(x, y) if you do not want to calculate the quotient yourself.
- /// </summary>
- /// <param name="tangent">Tangent</param>
- /// <returns>Atan value in degrees from the tangent value</returns>
- public static float Atan(float tangent)
- {
- return RadiansToDegrees((float)Math.Atan(tangent));
- }
-
- /// <summary>
- /// Returns the angle in degrees whose tangent is the quotient of two
- /// specified numbers. For more help see System.Math.Atan2 (which works in
- /// radians however).
- /// </summary>
- /// <param name="x">X value for atan2</param>
- /// <param name="y">Y value for atan2</param>
- /// <returns>Atan value in degrees from the x and y values</returns>
- public static float Atan(float x, float y)
- {
- return RadiansToDegrees((float)Math.Atan2(x, y));
- }
- #endregion
-
- #region GetNextPowerOfTwo (Static)
- /// <summary>
- /// Get the nearest power of two value that must be bigger or equal to
- /// value. Used for making sure textures are power of two. E.g.
- /// GetNextPowerOfTwo(128) is 128, GetNextPowerOfTwo(129) is 256, etc.
- /// </summary>
- /// <param name="value">Value</param>
- /// <returns>the nearest power of two value</returns>
- public static int GetNextPowerOfTwo(this float value)
- {
- int logValue = (int)Math.Ceiling(Math.Log(value, 2));
- return (int)Math.Pow(2, logValue);
- }
- #endregion
-
- #region IsPowerOfTwo (Static)
- /// <summary>
- /// Is power of two
- /// </summary>
- /// <param name="value">Value</param>
- /// <returns>Is power of two</returns>
- public static bool IsPowerOfTwo(this float value)
- {
- return GetNextPowerOfTwo(value) == value;
- }
- #endregion
-
- #region GetNearestMultiple (Static)
- /// <summary>
- /// Get the nearest multiple of 'multipleValue' from the value.
- /// </summary>
- /// <param name="multipleValue">Multiple Value</param>
- /// <param name="value">Value</param>
- /// <returns>the nearest multiple of 'multipleValue' from the
- /// value</returns>
- public static int GetNearestMultiple(this int value, int multipleValue)
- {
- int min =
- ((int)(value / (float)multipleValue)) * multipleValue;
- int max =
- ((int)(value / (float)multipleValue) + 1) * multipleValue;
-
- return max - value < value - min
- ? max
- : min;
- }
- #endregion
-
- #region Sign (Static)
- /// <summary>
- /// System.Math.Sign method, that crashes on the iPad if the value is not
- /// valid (e.g. NaN). This method will always return -1, 0 or 1.
- /// </summary>
- /// <param name="value">Value</param>
- /// <returns>-1, 0 or 1</returns>
- public static float Sign(float value)
- {
- //2010-05-28: dummy fix for iPad
- if (value == float.NaN)
- {
- return 0;
- }
-
- if (value < 0)
- {
- return -1;
- }
- else if (value > 0)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- #endregion
-
- #region ComputePercentageValue (Static)
- /// <summary>
- /// Computes the percentage value in the range [0 = 0%, 1 = 100%] based on
- /// the given value related to the given value range.
- /// </summary>
- /// <param name="value">
- /// The value we want to calculate the percentage for.
- /// </param>
- /// <param name="minValue">The minimum allowed value.</param>
- /// <param name="maxValue">The maximum allowed value.</param>
- /// <returns>
- /// The percentage value in the range [0 = 0%, 1 = 100%] based on the given
- /// value related to the given value range.
- /// </returns>
- public static float ComputePercentageValue(float value, float minValue,
- float maxValue)
- {
- // Validation
- float realMinValue =
- maxValue > minValue
- ? minValue
- : maxValue;
- float realMaxValue =
- minValue > maxValue
- ? minValue
- : maxValue;
-
- // Absolute difference between max and min value (should not be 0)
- float diff = realMaxValue - realMinValue;
- if (diff <= 0.0f)
- {
- return 0.0f;
- }
-
- // Clamp value to always get a result between 0 and 1.
- float clampedValue = Clamp(value, realMinValue, realMaxValue);
-
- // Difference from min to desired value in 0-1 range!
- return (clampedValue - realMinValue) / diff;
- }
- #endregion
-
- #region ComputeValue (Static)
- /// <summary>
- /// Returns the exact value based on the given percentage related to the
- /// given value range.
- /// </summary>
- /// <param name="percentageValue">Percentage value in the range of [0 = 0%,
- /// 1 = 100%].</param>
- /// <param name="minValue">The minimum allowed value.</param>
- /// <param name="maxValue">The maximum allowed value.</param>
- /// <returns>Float</returns>
- public static float ComputeValue(float percentageValue, float minValue,
- float maxValue)
- {
- // Validation
- float realMinValue = (maxValue > minValue)
- ? minValue
- : maxValue;
- float realMaxValue = (minValue > maxValue)
- ? minValue
- : maxValue;
- // clamp value
- float clampedPercentageValue = Clamp(percentageValue);
-
- // absolute difference between max and min value
- float diff = Abs(realMaxValue - realMinValue) * clampedPercentageValue;
- // return how many percent "diffFromMinToValue" is when diff = 100%
- return realMinValue + diff;
- }
- #endregion
-
- #region LineToLineIntersection (Static)
- /// <summary>
- /// Check if two lines intersect and return the position if occurred.
- /// </summary>
- /// <param name="a">The start point of line one.</param>
- /// <param name="b">The end point of line one.</param>
- /// <param name="c">The start point of line two.</param>
- /// <param name="d">The end point of line two.</param>
- /// <param name="resultX">If they intersect the X value is stored here.
- /// </param>
- /// <param name="resultY">If they intersect the Y value is stored here.
- /// </param>
- /// <returns>True if they intersect, otherwise false.</returns>
- public static bool LineToLineIntersection(Point a, Point b, Point c,
- Point d, out float resultX, out float resultY)
- {
- resultX = 0f;
- resultY = 0f;
-
- float denominator =
- ((d.Y - c.Y) * (b.X - a.X)) - ((d.X - c.X) * (b.Y - a.Y));
-
- float ua = (((d.X - c.X) * (a.Y - c.Y)) - ((d.Y - c.Y) * (a.X - c.X))) /
- denominator;
- float ub = (((b.X - a.X) * (a.Y - c.Y)) - ((b.Y - a.Y) * (a.X - c.X))) /
- denominator;
-
- if (ua >= 0f && ua <= 1f && ub >= 0f &&
- ub <= 1f)
- {
- resultX = a.X + (ua * (b.X - a.X));
- resultY = a.Y + (ua * (b.Y - a.Y));
- return true;
- }
-
- return false;
- }
-
- /// <summary>
- /// Check if two lines intersect and return the position if occurred.
- /// </summary>
- /// <param name="a">The start point of line one.</param>
- /// <param name="b">The end point of line one.</param>
- /// <param name="c">The start point of line two.</param>
- /// <param name="d">The end point of line two.</param>
- /// <returns>True if they intersect, otherwise false.</returns>
- public static bool LineToLineIntersection(Point a, Point b, Point c,
- Point d)
- {
- float denominator =
- ((d.Y - c.Y) * (b.X - a.X)) - ((d.X - c.X) * (b.Y - a.Y));
-
- float ua = (((d.X - c.X) * (a.Y - c.Y)) - ((d.Y - c.Y) * (a.X - c.X))) /
- denominator;
- float ub = (((b.X - a.X) * (a.Y - c.Y)) - ((b.Y - a.Y) * (a.X - c.X))) /
- denominator;
-
- return ua >= 0f && ua <= 1f && ub >= 0f && ub <= 1f;
- }
- #endregion
-
- /// <summary>
- /// Tests
- /// </summary>
- internal class MathHelperTests
- {
- #region NearlyEqual (Static)
- /// <summary>
- /// Nearly equal
- /// </summary>
- [Test]
- public static void NearlyEqual()
- {
- Assert.True(0.0f.NearlyEqual(0.0f));
- Assert.True(0.000001f.NearlyEqual(0.000002f));
- Assert.False(1.0f.NearlyEqual(2.0f));
- Assert.True(1.0f.NearlyEqual(1.0f + (Epsilon * 0.9f)));
- }
- #endregion
-
- #region Clamp (Static)
- /// <summary>
- /// Clamp
- /// </summary>
- [Test]
- public static void Clamp()
- {
- // Int's
- Assert.Equal(1, MathHelper.Clamp(1, 0, 10));
- Assert.Equal(0, MathHelper.Clamp(-1, 0, 10));
- Assert.Equal(10, MathHelper.Clamp(111, 0, 10));
- Assert.Equal(0, MathHelper.Clamp(2598, 0, 0));
-
- // Float's
- Assert.Equal(0.1f, MathHelper.Clamp(0.1f, 0.0f, 1.0f));
- Assert.Equal(0.59f, MathHelper.Clamp(0.64f, 0.53f, 0.59f));
- Assert.Equal(0.64f, MathHelper.Clamp(0.53f, 0.64f, 0.69f));
-
- //Assert.Equal(new Point(-1, -1),
- // MathHelper.Clamp(new Point(-2, -3.5f), new Point(-1, -1),
- // new Point(0, 0)));
- }
- #endregion
-
- #region Min (Static)
- /// <summary>
- /// Minimum
- /// </summary>
- [Test]
- public static void Min()
- {
- Assert.Equal(10, MathHelper.Min(10, 20));
- Assert.Equal(43, MathHelper.Min(134, 43));
- Assert.Equal(-20, MathHelper.Min(-10, -20));
- Assert.Equal(-20, MathHelper.Min(-5, -10, -20));
- }
- #endregion
-
- #region Max (Static)
- /// <summary>
- /// Maximum
- /// </summary>
- [Test]
- public static void Max()
- {
- Assert.Equal(20, MathHelper.Max(10, 20));
- Assert.Equal(134, MathHelper.Max(134, 43));
- Assert.Equal(-10, MathHelper.Max(-10, -20));
- Assert.Equal(-5, MathHelper.Max(-5, -10, -20));
- }
- #endregion
-
- #region Sqrt (Static)
- /// <summary>
- /// Sqrt
- /// </summary>
- [Test]
- public static void Sqrt()
- {
- Assert.Equal(0, MathHelper.Sqrt(0));
- Assert.Equal(2, MathHelper.Sqrt(4));
- Assert.Equal(9, MathHelper.Sqrt(81));
- Assert.NotEqual(1, MathHelper.Sqrt(2));
- }
- #endregion
-
- #region Round (Static)
- /// <summary>
- /// Round
- /// </summary>
- [Test]
- public static void Round()
- {
- Assert.Equal(1, MathHelper.Round(1.25f));
- Assert.Equal(10, MathHelper.Round(9.68f));
- Assert.Equal(1.23f, MathHelper.Round(1.2345f, 2));
- }
- #endregion
-
- #region Abs (Static)
- /// <summary>
- /// Absolute
- /// </summary>
- [Test]
- public static void Abs()
- {
- Assert.Equal(13, MathHelper.Abs(13));
- Assert.Equal(13, MathHelper.Abs(-13));
- Assert.Equal(13.52f, MathHelper.Abs(-13.52f));
- }
- #endregion
-
- #region Pow (Static)
- /// <summary>
- /// Pow
- /// </summary>
- [Test]
- public static void Pow()
- {
- Assert.Equal(25, MathHelper.Pow(5, 2));
- }
- #endregion
-
- #region GetNearestMultiple (Static)
- /// <summary>
- /// Test GetNearestMultiple
- /// </summary>
- [Test]
- public static void GetNearestMultiple()
- {
- int result = 130.GetNearestMultiple(32);
- Assert.Equal(128, result);
- result = 157.GetNearestMultiple(32);
- Assert.Equal(160, result);
-
- result = 17.GetNearestMultiple(4);
- Assert.Equal(16, result);
- result = 19.GetNearestMultiple(4);
- Assert.Equal(20, result);
- }
- #endregion
-
- #region Ceiling
- /// <summary>
- /// Ceiling
- /// </summary>
- [Test]
- public void Ceiling()
- {
- Assert.Equal(MathHelper.Ceiling(0.0f), 0);
- Assert.Equal(MathHelper.Ceiling(4.0f), 4);
- Assert.Equal(MathHelper.Ceiling(-2.0f), -2);
- Assert.Equal(MathHelper.Ceiling(2.3f), 3);
- Assert.Equal(MathHelper.Ceiling(7.8f), 8);
- }
- #endregion
-
- #region DegreeToRadians
- /// <summary>
- /// Degree to radians
- /// </summary>
- [Test]
- public void DegreeToRadians()
- {
- Assert.Equal(0, MathHelper.DegreeToRadians(0));
- Assert.True(Pi.NearlyEqual(MathHelper.DegreeToRadians(180)),
- "180 degrees is converted to radians nearly pi");
- Assert.True(PiHalf.NearlyEqual(MathHelper.DegreeToRadians(90)),
- "90 degrees is converted to radians nearly HalfPi");
- Assert.True(PiDouble.NearlyEqual(MathHelper.DegreeToRadians(360)),
- "360 degrees is converted to radians nearly PiDouble");
- Assert.NotEqual(0, MathHelper.DegreeToRadians(-1));
- }
- #endregion
-
- #region RadiansToDegrees
- /// <summary>
- /// Radians to degrees
- /// </summary>
- [Test]
- public void RadiansToDegrees()
- {
- Assert.Equal(0, MathHelper.RadiansToDegrees(0));
- Assert.True(MathHelper.NearlyEqual(180,
- Pi.RadiansToDegrees()),
- "Pi in radians is converted to degrees nearly 180 degree");
- Assert.True(MathHelper.NearlyEqual(90,
- PiHalf.RadiansToDegrees()),
- "HalfPi in radians is converted to degrees nearly 90 degree");
- Assert.True(MathHelper.NearlyEqual(360,
- PiDouble.RadiansToDegrees()),
- "PiDouble in radians is converted to degrees nearly 360 degree");
- Assert.NotEqual(0, MathHelper.RadiansToDegrees(-1));
- }
- #endregion
-
- #region Lerp
- /// <summary>
- /// Lerp
- /// </summary>
- [Test]
- public void Lerp()
- {
- Assert.Equal(3, MathHelper.Lerp(5, 3, 1));
- }
- #endregion
-
- #region TestIntTruncate
- /// <summary>
- /// Test int truncate
- /// </summary>
- [Test]
- public void TestIntTruncate()
- {
- Assert.Equal(17, (int)17.7f);
- Assert.Equal(17, (int)(17.2f + 0.5f));
- }
- #endregion
-
- #region Sin
- /// <summary>
- /// Sin
- /// </summary>
- [Test]
- public void Sin()
- {
- Assert.Equal(0, MathHelper.Sin(0));
- Assert.Equal(1, MathHelper.Sin(90));
- Assert.True(MathHelper.NearlyEqual(0, MathHelper.Sin(180)),
- "the sin of 180 is nearly zero");
- Assert.True(MathHelper.NearlyEqual(0, MathHelper.Sin(360)),
- "the sin of 360 is nearly zero");
- Assert.NotEqual(0, MathHelper.Sin(32));
- }
- #endregion
-
- #region Cos
- /// <summary>
- /// Sin
- /// </summary>
- [Test]
- public void Cos()
- {
- Assert.Equal(1, MathHelper.Cos(0));
- Assert.True(MathHelper.NearlyEqual(0, MathHelper.Cos(90)),
- "the cos of 90 is nearly zero");
- Assert.True(MathHelper.NearlyEqual(-1, MathHelper.Cos(180)),
- "the cos of 180 is nearly minus one");
- Assert.True(MathHelper.NearlyEqual(1, MathHelper.Cos(360)),
- "the cos of 360 is nearly one");
- Assert.NotEqual(0, MathHelper.Cos(32));
- }
- #endregion
-
- #region Tan
- /// <summary>
- /// Tan
- /// </summary>
- [Test]
- public void Tan()
- {
- Assert.Equal(0, MathHelper.Tan(0));
- Assert.True(MathHelper.NearlyEqual(0, MathHelper.Tan(180)),
- "the tan of 180 is nearly zero");
- Assert.True(1.732051f.NearlyEqual(MathHelper.Tan(60)),
- "the tan of 60 is nearly 1.732051f");
- Assert.True(MathHelper.NearlyEqual(1, MathHelper.Tan(45)),
- "the tan of 45 is nearly one");
- Assert.True(MathHelper.NearlyEqual(-1, MathHelper.Tan(135)),
- "the tan of 135 is nearly minus one");
- Assert.NotEqual(0, MathHelper.Tan(32));
- }
- #endregion
-
- #region Asin
- /// <summary>
- /// Asin
- /// </summary>
- [Test]
- public void Asin()
- {
- Assert.Equal(0, MathHelper.Asin(0));
- Assert.True(MathHelper.NearlyEqual(90, MathHelper.Asin(1)),
- "The Asin of 1 is nearly 90");
- Assert.True(MathHelper.NearlyEqual(30, MathHelper.Asin(0.5f)),
- "The Asin of 0.5 is nearly 30");
- Assert.NotEqual(0, MathHelper.Asin(0.2f));
- }
- #endregion
-
- #region Acos
- /// <summary>
- /// Acos
- /// </summary>
- [Test]
- public void Acos()
- {
- Assert.True(MathHelper.NearlyEqual(90, MathHelper.Acos(0)),
- "The Acos of zero is nearly 90");
- Assert.True(MathHelper.NearlyEqual(0, MathHelper.Acos(1)),
- "The Acos of one is nearly zero");
- Assert.True(MathHelper.NearlyEqual(60, MathHelper.Acos(0.5f)),
- "The Acos of 0.5 is nearly 60");
- Assert.NotEqual(0, MathHelper.Acos(0.2f));
- }
- #endregion
-
- #region Atan
- /// <summary>
- /// Atan
- /// </summary>
- [Test]
- public void Atan()
- {
- Assert.Equal(0, MathHelper.Atan(0));
- Assert.True(MathHelper.NearlyEqual(60, MathHelper.Atan(1.732051f)),
- "The Atan of 1.732051f is nearly 60");
- Assert.NotEqual(0, MathHelper.Atan(0.2f));
- Assert.Equal(0, MathHelper.Atan(0, 0));
- Assert.Equal(0, MathHelper.Atan(0, 1));
- Assert.True(MathHelper.NearlyEqual(90, MathHelper.Atan(1, 0)),
- "The Atan of the tangent(of one and zero) is nearly 90");
- Assert.True(MathHelper.NearlyEqual(45, MathHelper.Atan(1, 1)),
- "The Atan of the tangent(of one and one) is nearly 45");
- Assert.True(MathHelper.NearlyEqual(-90, MathHelper.Atan(-1, 0)),
- "The Atan of the tangent(of minus one and zero) is nearly minus 90");
- // Math.Atan(0, -1));
- // Always works:
- Assert.Equal("180", MathHelper.Atan(0, -1).ToString());
- // Only works if Math.Epsilon for NearlyEqual is not smaller than
- // 0.0001
- Assert.True(MathHelper.NearlyEqual(180, MathHelper.Atan(0, -1)),
- "The Atan of the tangent(of zero and minus one) is nearly 180");
- }
- #endregion
-
- #region GetNextPowerOfTwo
- /// <summary>
- /// Get next power of two
- /// </summary>
- [Test]
- public void GetNextPowerOfTwo()
- {
- Assert.Equal(128, MathHelper.GetNextPowerOfTwo(128));
- Assert.Equal(256, MathHelper.GetNextPowerOfTwo(129));
- Assert.Equal(1024, MathHelper.GetNextPowerOfTwo(529));
- Assert.Equal(2048, MathHelper.GetNextPowerOfTwo(1111));
- Assert.Equal(0, MathHelper.GetNextPowerOfTwo(-1));
- }
- #endregion
-
- #region IsPowerOfTwo
- /// <summary>
- /// IsPowerOfTwo
- /// </summary>
- [Test]
- public void IsPowerOfTwo()
- {
- Assert.True(MathHelper.IsPowerOfTwo(128));
- Assert.False(MathHelper.IsPowerOfTwo(129));
- Assert.False(MathHelper.IsPowerOfTwo(529));
- Assert.False(MathHelper.IsPowerOfTwo(1111));
- Assert.True(MathHelper.IsPowerOfTwo(1024));
- Assert.False(MathHelper.IsPowerOfTwo(-1));
- Assert.True(MathHelper.IsPowerOfTwo(4));
- }
- #endregion
-
- #region ComputeValue
- /// <summary>
- /// Compute value
- /// </summary>
- [Test]
- public void ComputeValue()
- {
- Assert.Equal(MathHelper.ComputeValue(0.5f, 10, 20), 15.0f);
-
- Assert.Equal(MathHelper.ComputeValue(0.5f, 0, 10), 5.0f);
-
- Assert.Equal(MathHelper.ComputeValue(0.5f, -10, 0), -5.0f);
-
- Assert.Equal(MathHelper.ComputeValue(0.5f, -10, 10), 0.0f);
- }
- #endregion
-
- #region ComputePercentageValue
- /// <summary>
- /// Compute percentage value
- /// </summary>
- [Test]
- public void ComputePercentageValue()
- {
- Assert.Equal(MathHelper.ComputePercentageValue(5, 0, 10), 0.5f);
-
- Assert.Equal(MathHelper.ComputePercentageValue(0, -10, 10), 0.5f);
-
- Assert.Equal(MathHelper.ComputePercentageValue(0, -360, 360), 0.5f);
-
- Assert.Equal(MathHelper.ComputePercentageValue(-50, -100, -50), 1.0f);
-
- Assert.Equal(MathHelper.ComputePercentageValue(-100, -100, -50), 0.0f);
-
- Assert.Equal(MathHelper.ComputePercentageValue(0, 1000, -1000), 0.5f);
- }
- #endregion
- }
- }
- }