PageRenderTime 171ms CodeModel.GetById 61ms app.highlight 66ms RepoModel.GetById 34ms app.codeStats 1ms

/Utilities/Helpers/MathHelper.cs

#
C# | 1153 lines | 639 code | 101 blank | 413 comment | 16 complexity | 06cf255bf32c37245088c5a434cf6eda MD5 | raw file
   1using System;
   2using Delta.Utilities.Datatypes;
   3using NUnit.Framework;
   4
   5namespace Delta.Utilities.Helpers
   6{
   7	/// <summary>
   8	/// Math helper class. Provides the same functionality as System.Math, but
   9	/// instead of using doubles for all the functions here are using floats!
  10	/// </summary>
  11	public static class MathHelper
  12	{
  13		#region Constants
  14		/// <summary>
  15		/// Epsilon is a small comparison offset for NearlyEqual checks.
  16		/// Note: Other frameworks use float.Epsilon (1.192092896e-07f), but we
  17		/// work great with this value too, so we should keep it this way.
  18		/// </summary>
  19		public const float Epsilon = 0.0001f;
  20
  21		/// <summary>
  22		/// E constant as a float (2.718282).
  23		/// </summary>
  24		public const float E = 2.718282f;
  25
  26		/// <summary>
  27		/// Pi constants, same as PI (double), but as a float here (less precise),
  28		/// please note that we usually use degrees and not radians in the engine!
  29		/// </summary>
  30		public const float Pi = 3.14159265359f;
  31
  32		/// <summary>
  33		/// Pi times two for getting around a whole circle (360 degrees).
  34		/// </summary>
  35		public const float PiDouble = Pi * 2.0f;
  36
  37		/// <summary>
  38		/// Pi Half, which represents 90 degrees.
  39		/// </summary>
  40		public const float PiHalf = Pi * 0.5f;
  41
  42		/// <summary>
  43		/// Pi Quarter, which represents 45 degrees.
  44		/// </summary>
  45		public const float PiQuarter = PiHalf * 0.5f;
  46
  47		/// <summary>
  48		/// Represents just the fraction of 1/3 or in decimal 0.333333
  49		/// </summary>
  50		public const float OneThird = 1.0f / 3.0f;
  51
  52		/// <summary>
  53		/// The default value for an invalid index check (-1), very often used to
  54		/// set invalid and initial values to integer values to make sure that we
  55		/// initialize them first before using them, e.g. for shader parameters or
  56		/// for indices in precomputed arrays, but also often used by the .NET
  57		/// framework, e.g String.IndexOf returns -1 for not found.
  58		/// </summary>
  59		public const int InvalidIndex = -1;
  60
  61		/// <summary>
  62		/// Sinus value of 45 Degree
  63		/// </summary>
  64		public const float Sin45 = 0.707106781f;
  65
  66		/// <summary>
  67		/// Half of the short max. value (32768), which is 16392. This is used
  68		/// for the calculation of ViewProjection2DViaShorts and in the
  69		/// MaterialManager to setup compressed vertices.
  70		/// </summary>
  71		public const short HalfShortMaxValue = short.MaxValue / 2;
  72		#endregion
  73
  74		#region NearlyEqual (Static)
  75		/// <summary>
  76		/// Compares two floats if they are almost equal, taking an Epsilon offset
  77		/// (see Math.Epsilon) into account.
  78		/// </summary>
  79		/// <param name="value1">first float</param>
  80		/// <param name="value2">second float</param>
  81		/// <returns>Bool: True if Nearly Equal</returns>
  82		public static bool NearlyEqual(this float value1, float value2)
  83		{
  84			float difference = Abs(value1 - value2);
  85			return difference <= Epsilon;
  86		}
  87		#endregion
  88
  89		#region InvertScalar (Static)
  90		/// <summary>
  91		/// Invert scalar safely.
  92		/// </summary>
  93		/// <param name="value">Value</param>
  94		/// <returns>1.0f</returns>
  95		public static float InvertScalar(float value)
  96		{
  97			if (Abs(value) < Epsilon)
  98			{
  99				return float.MaxValue;
 100			}
 101			return 1.0f / value;
 102		}
 103		#endregion
 104
 105		#region Clamp (Static)
 106		/// <summary>
 107		/// Clamps the value between [0, 1].
 108		/// </summary>
 109		/// <param name="value">Value</param>
 110		/// <returns>Clamp Value</returns>
 111		public static int Clamp(int value)
 112		{
 113			return Clamp(value, 0, 1);
 114		}
 115
 116		/// <summary>
 117		/// Clamps the value between the given range [minimum, maximum].
 118		/// </summary>
 119		/// <param name="max">Max</param>
 120		/// <param name="min">Min</param>
 121		/// <param name="value">Value</param>
 122		/// <returns>value between the given range [minimum, maximum]</returns>
 123		public static int Clamp(int value, int min, int max)
 124		{
 125			return Min(Max(value, min), max);
 126		}
 127
 128		/// <summary>
 129		/// Clamps the value between [0.0, 1.0].
 130		/// </summary>
 131		/// <param name="value">Value</param>
 132		/// <returns>value between [0.0, 1.0]</returns>
 133		public static float Clamp(float value)
 134		{
 135			return Clamp(value, 0.0f, 1.0f);
 136		}
 137
 138		/// <summary>
 139		/// Clamps the value between the given range [minimum, maximum].
 140		/// </summary>
 141		/// <param name="max">Max</param>
 142		/// <param name="min">Min</param>
 143		/// <param name="value">Value</param>
 144		/// <returns>value between the given range [minimum, maximum]</returns>
 145		public static float Clamp(float value, float min, float max)
 146		{
 147			return Min(Max(value, min), max);
 148		}
 149		#endregion
 150
 151		#region Wrap (Static)
 152		/// <summary>
 153		/// Wrap the value between the given range [minimun, maximum].
 154		/// </summary>
 155		/// <param name="max">Max</param>
 156		/// <param name="min">Min</param>
 157		/// <param name="value">Value</param>
 158		/// <returns>value between the given range [minimun, maximum]</returns>
 159		public static int Wrap(int value, int min, int max)
 160		{
 161			int delta = max - min;
 162			if (value > delta)
 163			{
 164				value = value / delta;
 165				value = value - (int)Math.Floor((double)value);
 166				value = value * delta;
 167			}
 168			return value;
 169		}
 170
 171		/// <summary>
 172		/// Wrap the value between the given range [minimun, maximum].
 173		/// </summary>
 174		/// <param name="max">Max</param>
 175		/// <param name="min">Min</param>
 176		/// <param name="value">Value</param>
 177		/// <returns>The wrapped Value</returns>
 178		public static float Wrap(float value, float min, float max)
 179		{
 180			float delta = max - min;
 181			if (value > delta)
 182			{
 183				value = value / delta;
 184				value = value - (float)Math.Floor(value);
 185				value = value * delta;
 186			}
 187			return value;
 188		}
 189		#endregion
 190
 191		#region Distance (Static)
 192		/// <summary>
 193		/// Distance between two float values.
 194		/// </summary>
 195		/// <param name="value1">First float value</param>
 196		/// <param name="value2">Second float value</param>
 197		/// <returns>Distance between the two values, always positive</returns>
 198		public static float Distance(float value1, float value2)
 199		{
 200			return Abs(value1 - value2);
 201		}
 202		#endregion
 203
 204		#region Min (Static)
 205		/// <summary>
 206		/// Returns the smaller of two values.
 207		/// </summary>
 208		/// <param name="value1">Value 1</param>
 209		/// <param name="value2">Value 2</param>
 210		/// <returns>the smaller of two values</returns>
 211		public static float Min(float value1, float value2)
 212		{
 213			return
 214				value1 < value2
 215					? value1
 216					: value2;
 217		}
 218
 219		/// <summary>
 220		/// Returns the smaller of three values.
 221		/// </summary>
 222		/// <param name="value1">Value 1</param>
 223		/// <param name="value2">Value 2</param>
 224		/// <param name="value3">Value 3</param>
 225		/// <returns>Returns the smaller of three values</returns>
 226		public static float Min(float value1, float value2, float value3)
 227		{
 228			return Min(Min(value1, value2), value3);
 229		}
 230
 231		/// <summary>
 232		/// Returns the smaller of two values.
 233		/// </summary>
 234		/// <param name="value1">Value 1</param>
 235		/// <param name="value2">Value 2</param>
 236		/// <returns>Returns the smaller of two values</returns>
 237		public static int Min(int value1, int value2)
 238		{
 239			return
 240				value1 < value2
 241					? value1
 242					: value2;
 243		}
 244
 245		/// <summary>
 246		/// Returns the smaller of three values.
 247		/// </summary>
 248		/// <param name="value1">Value1</param>
 249		/// <param name="value2">Value2</param>
 250		/// <param name="value3">Value3</param>
 251		/// <returns>eturns the smaller of three values</returns>
 252		public static int Min(int value1, int value2, int value3)
 253		{
 254			return Min(Min(value1, value2), value3);
 255		}
 256		#endregion
 257
 258		#region Max (Static)
 259		/// <summary>
 260		/// Returns the bigger one of the two values.
 261		/// </summary>
 262		/// <param name="value1">Value 1</param>
 263		/// <param name="value2">Value 2</param>
 264		/// <returns>Returns the bigger one of the two values</returns>
 265		public static int Max(int value1, int value2)
 266		{
 267			return
 268				value1 > value2
 269					? value1
 270					: value2;
 271		}
 272
 273		/// <summary>
 274		/// Returns the bigger one of the three values.
 275		/// </summary>
 276		/// <param name="value1">Value1</param>
 277		/// <param name="value2">Value2</param>
 278		/// <param name="value3">Value3</param>
 279		/// <returns>Returns the bigger one of the three values</returns>
 280		public static int Max(int value1, int value2, int value3)
 281		{
 282			return Max(Max(value1, value2), value3);
 283		}
 284
 285		/// <summary>
 286		/// Returns the bigger one of the two values.
 287		/// </summary>
 288		/// <param name="value1">Value1</param>
 289		/// <param name="value2">Value2</param>
 290		/// <returns>Returns the bigger one of the two values</returns>
 291		public static float Max(float value1, float value2)
 292		{
 293			return
 294				value1 > value2
 295					? value1
 296					: value2;
 297		}
 298
 299		/// <summary>
 300		/// Returns the bigger one of the three values.
 301		/// </summary>
 302		/// <param name="value1">Value1</param>
 303		/// <param name="value2">Value2</param>
 304		/// <param name="value3">Value3</param>
 305		/// <returns>Returns the bigger one of the three values</returns>
 306		public static float Max(float value1, float value2, float value3)
 307		{
 308			return Max(Max(value1, value2), value3);
 309		}
 310		#endregion
 311
 312		#region Lerp (Static)
 313		/// <summary>
 314		/// Performs a linear interpolation between two values. 
 315		/// </summary>
 316		/// <param name="minValue">Value at "percentage = 0"</param>
 317		/// <param name="maxValue">Value at "percentage = 1"</param>
 318		/// <param name="percentage">Percentage in the range [0,1]</param>
 319		/// <returns>Float</returns>
 320		public static float Lerp(float minValue, float maxValue, float percentage)
 321		{
 322			return minValue + (maxValue - minValue) * percentage;
 323		}
 324
 325		/// <summary>
 326		/// Performs a linear interpolation between two values. 
 327		/// </summary>
 328		/// <param name="minValue">Value at "percentage = 0"</param>
 329		/// <param name="maxValue">Value at "percentage = 1"</param>
 330		/// <param name="percentage">Percentage in the range [0,1]</param>
 331		/// <returns>Float</returns>
 332		public static int Lerp(int minValue, int maxValue, float percentage)
 333		{
 334			return minValue + Round((maxValue - minValue) * percentage);
 335		}
 336
 337		/// <summary>
 338		/// Performs a linear interpolation between two values. 
 339		/// </summary>
 340		/// <param name="minValue">Value at "percentage = 0"</param>
 341		/// <param name="maxValue">Value at "percentage = 1"</param>
 342		/// <param name="percentage">Percentage in the range [0,1]</param>
 343		/// <returns>Float</returns>
 344		public static long Lerp(long minValue, long maxValue, float percentage)
 345		{
 346			return minValue + Round((maxValue - minValue) * percentage);
 347		}
 348		#endregion
 349
 350		#region Sqrt (Static)
 351		/// <summary>
 352		/// Sqrt
 353		/// </summary>
 354		/// <returns>Float</returns>
 355		public static float Sqrt(float value)
 356		{
 357
 358			return (float)Math.Sqrt(value);
 359		}
 360		#endregion
 361
 362		#region Round (Static)
 363		/// <summary>
 364		/// Rounds a value to a given position after the decimal point
 365		/// </summary>
 366		/// <param name="value">Value to round</param>
 367		/// <param name="decimals">Decimals</param>
 368		/// <returns>Float</returns>
 369		public static float Round(float value, int decimals)
 370		{
 371			return (float)Math.Round(value, decimals);
 372		}
 373
 374		/// <summary>
 375		/// Rounds a value to an int
 376		/// </summary>
 377		/// <param name="value">Value to round</param>
 378		/// <returns>Float</returns>
 379		public static int Round(float value)
 380		{
 381			return (int)Math.Round(value);
 382		}
 383		#endregion
 384
 385		#region Ceiling (Static)
 386		/// <summary>
 387		/// Ceiling
 388		/// </summary>
 389		/// <param name="value">Value</param>
 390		/// <returns>Ceiling</returns>
 391		public static int Ceiling(float value)
 392		{
 393			return (int)Math.Ceiling(value);
 394		}
 395		#endregion
 396
 397		#region Abs (Static)
 398		/// <summary>
 399		/// Returns the absolute value of a float
 400		/// </summary>
 401		/// <param name="value">Value</param>
 402		/// <returns>Returns the absolute value of a float</returns>
 403		public static float Abs(float value)
 404		{
 405			return
 406				value < 0f
 407					? -value
 408					: value;
 409		}
 410		#endregion
 411
 412		#region Pow (Static)
 413		/// <summary>
 414		/// Pow
 415		/// </summary>
 416		/// <param name="power">Power</param>
 417		/// <param name="value">Value</param>
 418		/// <returns>Power</returns>
 419		public static float Pow(float value, float power)
 420		{
 421			return (float)Math.Pow(value, power);
 422		}
 423		#endregion
 424
 425		#region DegreeToRadians (Static)
 426		/// <summary>
 427		/// Degree to radians
 428		/// </summary>
 429		/// <param name="degrees">Degrees</param>
 430		/// <returns>Degree to radians</returns>
 431		public static float DegreeToRadians(this float degrees)
 432		{
 433			return degrees * (Pi / 180.0f); //same: * 0.01745329f;
 434		}
 435		#endregion
 436
 437		#region RadiansToDegrees (Static)
 438		/// <summary>
 439		/// Radians to degrees
 440		/// </summary>
 441		/// <param name="radians">Radians</param>
 442		/// <returns>radians</returns>
 443		public static float RadiansToDegrees(this float radians)
 444		{
 445			return radians * (180.0f / Pi); //same: * 57.29578f;
 446		}
 447		#endregion
 448
 449		#region Sin (Static)
 450		/// <summary>
 451		/// Return the sinus of a degreeValue. Note: Most other math libraries use
 452		/// radians, please provide degrees here (used throughout the engine).
 453		/// </summary>
 454		/// <param name="degreeValue">Degree value for the sinus</param>
 455		/// <returns>Sinus of degreeValue</returns>
 456		public static float Sin(float degreeValue)
 457		{
 458			return (float)Math.Sin(degreeValue * (Pi / 180.0f));
 459		}
 460		#endregion
 461
 462		#region Cos (Static)
 463		/// <summary>
 464		/// Cosinus of a degreeValue, please use degree values here (not radians)
 465		/// </summary>
 466		/// <param name="degreeValue">Degree Value for the cosinus</param>
 467		/// <returns>Cosinus of degreeValue</returns>
 468		public static float Cos(float degreeValue)
 469		{
 470			return (float)Math.Cos(degreeValue * (Pi / 180.0f));
 471		}
 472		#endregion
 473
 474		#region Tan (Static)
 475		/// <summary>
 476		/// Get the tangent value, again using degrees, not radians.
 477		/// </summary>
 478		/// <param name="degreeValue">Degree value for the tagent</param>
 479		/// <returns>Tangent of degreeValue</returns>
 480		public static float Tan(float degreeValue)
 481		{
 482			return (float)Math.Tan(DegreeToRadians(degreeValue));
 483		}
 484		#endregion
 485
 486		#region Asin (Static)
 487		/// <summary>
 488		/// Returns the angle in degrees whose sin value is the specified value.
 489		/// </summary>
 490		/// <param name="value">Value for asin</param>
 491		/// <returns>Asin value in degrees from the value</returns>
 492		public static float Asin(float value)
 493		{
 494			return RadiansToDegrees((float)Math.Asin(value));
 495		}
 496		#endregion
 497
 498		#region Acos (Static)
 499		/// <summary>
 500		/// Returns the angle in degrees whose cos value is the specified value.
 501		/// </summary>
 502		/// <param name="value">Value for acos</param>
 503		/// <returns>Acos value in degrees from the value</returns>
 504		public static float Acos(float value)
 505		{
 506			return RadiansToDegrees((float)Math.Acos(value));
 507		}
 508		#endregion
 509
 510		#region Atan (Static)
 511		/// <summary>
 512		/// Returns the angle in degrees whose tangent is the specified number.
 513		/// Use Atan(x, y) if you do not want to calculate the quotient yourself.
 514		/// </summary>
 515		/// <param name="tangent">Tangent</param>
 516		/// <returns>Atan value in degrees from the tangent value</returns>
 517		public static float Atan(float tangent)
 518		{
 519			return RadiansToDegrees((float)Math.Atan(tangent));
 520		}
 521
 522		/// <summary>
 523		/// Returns the angle in degrees whose tangent is the quotient of two
 524		/// specified numbers. For more help see System.Math.Atan2 (which works in
 525		/// radians however).
 526		/// </summary>
 527		/// <param name="x">X value for atan2</param>
 528		/// <param name="y">Y value for atan2</param>
 529		/// <returns>Atan value in degrees from the x and y values</returns>
 530		public static float Atan(float x, float y)
 531		{
 532			return RadiansToDegrees((float)Math.Atan2(x, y));
 533		}
 534		#endregion
 535
 536		#region GetNextPowerOfTwo (Static)
 537		/// <summary>
 538		/// Get the nearest power of two value that must be bigger or equal to
 539		/// value. Used for making sure textures are power of two. E.g.
 540		/// GetNextPowerOfTwo(128) is 128, GetNextPowerOfTwo(129) is 256, etc.
 541		/// </summary>
 542		/// <param name="value">Value</param>
 543		/// <returns>the nearest power of two value</returns>
 544		public static int GetNextPowerOfTwo(this float value)
 545		{
 546			int logValue = (int)Math.Ceiling(Math.Log(value, 2));
 547			return (int)Math.Pow(2, logValue);
 548		}
 549		#endregion
 550
 551		#region IsPowerOfTwo (Static)
 552		/// <summary>
 553		/// Is power of two
 554		/// </summary>
 555		/// <param name="value">Value</param>
 556		/// <returns>Is power of two</returns>
 557		public static bool IsPowerOfTwo(this float value)
 558		{
 559			return GetNextPowerOfTwo(value) == value;
 560		}
 561		#endregion
 562
 563		#region GetNearestMultiple (Static)
 564		/// <summary>
 565		/// Get the nearest multiple of 'multipleValue' from the value.
 566		/// </summary>
 567		/// <param name="multipleValue">Multiple Value</param>
 568		/// <param name="value">Value</param>
 569		/// <returns>the nearest multiple of 'multipleValue' from the 
 570		/// value</returns>
 571		public static int GetNearestMultiple(this int value, int multipleValue)
 572		{
 573			int min =
 574				((int)(value / (float)multipleValue)) * multipleValue;
 575			int max =
 576				((int)(value / (float)multipleValue) + 1) * multipleValue;
 577
 578			return max - value < value - min
 579			       	? max
 580			       	: min;
 581		}
 582		#endregion
 583
 584		#region Sign (Static)
 585		/// <summary>
 586		/// System.Math.Sign method, that crashes on the iPad if the value is not
 587		/// valid (e.g. NaN). This method will always return -1, 0 or 1.
 588		/// </summary>
 589		/// <param name="value">Value</param>
 590		/// <returns>-1, 0 or 1</returns>
 591		public static float Sign(float value)
 592		{
 593			//2010-05-28: dummy fix for iPad
 594			if (value == float.NaN)
 595			{
 596				return 0;
 597			}
 598
 599			if (value < 0)
 600			{
 601				return -1;
 602			}
 603			else if (value > 0)
 604			{
 605				return 1;
 606			}
 607			else
 608			{
 609				return 0;
 610			}
 611		}
 612		#endregion
 613
 614		#region ComputePercentageValue (Static)
 615		/// <summary>
 616		/// Computes the percentage value in the range [0 = 0%, 1 = 100%] based on
 617		/// the given value related to the given value range.
 618		/// </summary>
 619		/// <param name="value">
 620		/// The value we want to calculate the percentage for.
 621		/// </param>
 622		/// <param name="minValue">The minimum allowed value.</param>
 623		/// <param name="maxValue">The maximum allowed value.</param>
 624		/// <returns>
 625		/// The percentage value in the range [0 = 0%, 1 = 100%] based on the given
 626		/// value related to the given value range.
 627		/// </returns>
 628		public static float ComputePercentageValue(float value, float minValue,
 629			float maxValue)
 630		{
 631			// Validation
 632			float realMinValue =
 633				maxValue > minValue
 634					? minValue
 635					: maxValue;
 636			float realMaxValue =
 637				minValue > maxValue
 638					? minValue
 639					: maxValue;
 640			
 641			// Absolute difference between max and min value (should not be 0)
 642			float diff = realMaxValue - realMinValue;
 643			if (diff <= 0.0f)
 644			{
 645				return 0.0f;
 646			}
 647
 648			// Clamp value to always get a result between 0 and 1.
 649			float clampedValue = Clamp(value, realMinValue, realMaxValue);
 650
 651			// Difference from min to desired value in 0-1 range!
 652			return (clampedValue - realMinValue) / diff;
 653		}
 654		#endregion
 655
 656		#region ComputeValue (Static)
 657		/// <summary>
 658		/// Returns the exact value based on the given percentage related to the
 659		/// given value range.
 660		/// </summary>
 661		/// <param name="percentageValue">Percentage value in the range of [0 = 0%,
 662		/// 1 = 100%].</param>
 663		/// <param name="minValue">The minimum allowed value.</param>
 664		/// <param name="maxValue">The maximum allowed value.</param>
 665		/// <returns>Float</returns>
 666		public static float ComputeValue(float percentageValue, float minValue,
 667			float maxValue)
 668		{
 669			// Validation
 670			float realMinValue = (maxValue > minValue)
 671			                     	? minValue
 672			                     	: maxValue;
 673			float realMaxValue = (minValue > maxValue)
 674			                     	? minValue
 675			                     	: maxValue;
 676			// clamp value
 677			float clampedPercentageValue = Clamp(percentageValue);
 678
 679			// absolute difference between max and min value
 680			float diff = Abs(realMaxValue - realMinValue) * clampedPercentageValue;
 681			// return how many percent "diffFromMinToValue" is when diff = 100%
 682			return realMinValue + diff;
 683		}
 684		#endregion
 685
 686		#region LineToLineIntersection (Static)
 687		/// <summary>
 688		/// Check if two lines intersect and return the position if occurred.
 689		/// </summary>
 690		/// <param name="a">The start point of line one.</param>
 691		/// <param name="b">The end point of line one.</param>
 692		/// <param name="c">The start point of line two.</param>
 693		/// <param name="d">The end point of line two.</param>
 694		/// <param name="resultX">If they intersect the X value is stored here.
 695		/// </param>
 696		/// <param name="resultY">If they intersect the Y value is stored here.
 697		/// </param>
 698		/// <returns>True if they intersect, otherwise false.</returns>
 699		public static bool LineToLineIntersection(Point a, Point b, Point c,
 700			Point d, out float resultX, out float resultY)
 701		{
 702			resultX = 0f;
 703			resultY = 0f;
 704
 705			float denominator =
 706				((d.Y - c.Y) * (b.X - a.X)) - ((d.X - c.X) * (b.Y - a.Y));
 707
 708			float ua = (((d.X - c.X) * (a.Y - c.Y)) - ((d.Y - c.Y) * (a.X - c.X))) /
 709			           denominator;
 710			float ub = (((b.X - a.X) * (a.Y - c.Y)) - ((b.Y - a.Y) * (a.X - c.X))) /
 711			           denominator;
 712
 713			if (ua >= 0f && ua <= 1f && ub >= 0f &&
 714			    ub <= 1f)
 715			{
 716				resultX = a.X + (ua * (b.X - a.X));
 717				resultY = a.Y + (ua * (b.Y - a.Y));
 718				return true;
 719			}
 720
 721			return false;
 722		}
 723
 724		/// <summary>
 725		/// Check if two lines intersect and return the position if occurred.
 726		/// </summary>
 727		/// <param name="a">The start point of line one.</param>
 728		/// <param name="b">The end point of line one.</param>
 729		/// <param name="c">The start point of line two.</param>
 730		/// <param name="d">The end point of line two.</param>
 731		/// <returns>True if they intersect, otherwise false.</returns>
 732		public static bool LineToLineIntersection(Point a, Point b, Point c,
 733			Point d)
 734		{
 735			float denominator =
 736				((d.Y - c.Y) * (b.X - a.X)) - ((d.X - c.X) * (b.Y - a.Y));
 737
 738			float ua = (((d.X - c.X) * (a.Y - c.Y)) - ((d.Y - c.Y) * (a.X - c.X))) /
 739			           denominator;
 740			float ub = (((b.X - a.X) * (a.Y - c.Y)) - ((b.Y - a.Y) * (a.X - c.X))) /
 741			           denominator;
 742
 743			return ua >= 0f && ua <= 1f && ub >= 0f && ub <= 1f;
 744		}
 745		#endregion
 746
 747		/// <summary>
 748		/// Tests
 749		/// </summary>
 750		internal class MathHelperTests
 751		{
 752			#region NearlyEqual (Static)
 753			/// <summary>
 754			/// Nearly equal
 755			/// </summary>
 756			[Test]
 757			public static void NearlyEqual()
 758			{
 759				Assert.True(0.0f.NearlyEqual(0.0f));
 760				Assert.True(0.000001f.NearlyEqual(0.000002f));
 761				Assert.False(1.0f.NearlyEqual(2.0f));
 762				Assert.True(1.0f.NearlyEqual(1.0f + (Epsilon * 0.9f)));
 763			}
 764			#endregion
 765
 766			#region Clamp (Static)
 767			/// <summary>
 768			/// Clamp
 769			/// </summary>
 770			[Test]
 771			public static void Clamp()
 772			{
 773				// Int's
 774				Assert.Equal(1, MathHelper.Clamp(1, 0, 10));
 775				Assert.Equal(0, MathHelper.Clamp(-1, 0, 10));
 776				Assert.Equal(10, MathHelper.Clamp(111, 0, 10));
 777				Assert.Equal(0, MathHelper.Clamp(2598, 0, 0));
 778
 779				// Float's
 780				Assert.Equal(0.1f, MathHelper.Clamp(0.1f, 0.0f, 1.0f));
 781				Assert.Equal(0.59f, MathHelper.Clamp(0.64f, 0.53f, 0.59f));
 782				Assert.Equal(0.64f, MathHelper.Clamp(0.53f, 0.64f, 0.69f));
 783
 784				//Assert.Equal(new Point(-1, -1),
 785				//	MathHelper.Clamp(new Point(-2, -3.5f), new Point(-1, -1),
 786				//		new Point(0, 0)));
 787			}
 788			#endregion
 789
 790			#region Min (Static)
 791			/// <summary>
 792			/// Minimum
 793			/// </summary>
 794			[Test]
 795			public static void Min()
 796			{
 797				Assert.Equal(10, MathHelper.Min(10, 20));
 798				Assert.Equal(43, MathHelper.Min(134, 43));
 799				Assert.Equal(-20, MathHelper.Min(-10, -20));
 800				Assert.Equal(-20, MathHelper.Min(-5, -10, -20));
 801			}
 802			#endregion
 803
 804			#region Max (Static)
 805			/// <summary>
 806			/// Maximum
 807			/// </summary>
 808			[Test]
 809			public static void Max()
 810			{
 811				Assert.Equal(20, MathHelper.Max(10, 20));
 812				Assert.Equal(134, MathHelper.Max(134, 43));
 813				Assert.Equal(-10, MathHelper.Max(-10, -20));
 814				Assert.Equal(-5, MathHelper.Max(-5, -10, -20));
 815			}
 816			#endregion
 817
 818			#region Sqrt (Static)
 819			/// <summary>
 820			/// Sqrt
 821			/// </summary>
 822			[Test]
 823			public static void Sqrt()
 824			{
 825				Assert.Equal(0, MathHelper.Sqrt(0));
 826				Assert.Equal(2, MathHelper.Sqrt(4));
 827				Assert.Equal(9, MathHelper.Sqrt(81));
 828				Assert.NotEqual(1, MathHelper.Sqrt(2));
 829			}
 830			#endregion
 831
 832			#region Round (Static)
 833			/// <summary>
 834			/// Round
 835			/// </summary>
 836			[Test]
 837			public static void Round()
 838			{
 839				Assert.Equal(1, MathHelper.Round(1.25f));
 840				Assert.Equal(10, MathHelper.Round(9.68f));
 841				Assert.Equal(1.23f, MathHelper.Round(1.2345f, 2));
 842			}
 843			#endregion
 844
 845			#region Abs (Static)
 846			/// <summary>
 847			/// Absolute
 848			/// </summary>
 849			[Test]
 850			public static void Abs()
 851			{
 852				Assert.Equal(13, MathHelper.Abs(13));
 853				Assert.Equal(13, MathHelper.Abs(-13));
 854				Assert.Equal(13.52f, MathHelper.Abs(-13.52f));
 855			}
 856			#endregion
 857
 858			#region Pow (Static)
 859			/// <summary>
 860			/// Pow
 861			/// </summary>
 862			[Test]
 863			public static void Pow()
 864			{
 865				Assert.Equal(25, MathHelper.Pow(5, 2));
 866			}
 867			#endregion
 868
 869			#region GetNearestMultiple (Static)
 870			/// <summary>
 871			/// Test GetNearestMultiple
 872			/// </summary>
 873			[Test]
 874			public static void GetNearestMultiple()
 875			{
 876				int result = 130.GetNearestMultiple(32);
 877				Assert.Equal(128, result);
 878				result = 157.GetNearestMultiple(32);
 879				Assert.Equal(160, result);
 880
 881				result = 17.GetNearestMultiple(4);
 882				Assert.Equal(16, result);
 883				result = 19.GetNearestMultiple(4);
 884				Assert.Equal(20, result);
 885			}
 886			#endregion
 887
 888			#region Ceiling
 889			/// <summary>
 890			/// Ceiling
 891			/// </summary>
 892			[Test]
 893			public void Ceiling()
 894			{
 895				Assert.Equal(MathHelper.Ceiling(0.0f), 0);
 896				Assert.Equal(MathHelper.Ceiling(4.0f), 4);
 897				Assert.Equal(MathHelper.Ceiling(-2.0f), -2);
 898				Assert.Equal(MathHelper.Ceiling(2.3f), 3);
 899				Assert.Equal(MathHelper.Ceiling(7.8f), 8);
 900			}
 901			#endregion
 902
 903			#region DegreeToRadians
 904			/// <summary>
 905			/// Degree to radians
 906			/// </summary>
 907			[Test]
 908			public void DegreeToRadians()
 909			{
 910				Assert.Equal(0, MathHelper.DegreeToRadians(0));
 911				Assert.True(Pi.NearlyEqual(MathHelper.DegreeToRadians(180)),
 912					"180 degrees is converted to radians nearly pi");
 913				Assert.True(PiHalf.NearlyEqual(MathHelper.DegreeToRadians(90)),
 914					"90 degrees is converted to radians nearly HalfPi");
 915				Assert.True(PiDouble.NearlyEqual(MathHelper.DegreeToRadians(360)),
 916					"360 degrees is converted to radians nearly PiDouble");
 917				Assert.NotEqual(0, MathHelper.DegreeToRadians(-1));
 918			}
 919			#endregion
 920
 921			#region RadiansToDegrees
 922			/// <summary>
 923			/// Radians to degrees
 924			/// </summary>
 925			[Test]
 926			public void RadiansToDegrees()
 927			{
 928				Assert.Equal(0, MathHelper.RadiansToDegrees(0));
 929				Assert.True(MathHelper.NearlyEqual(180,
 930					Pi.RadiansToDegrees()),
 931					"Pi in radians is converted to degrees nearly 180 degree");
 932				Assert.True(MathHelper.NearlyEqual(90,
 933					PiHalf.RadiansToDegrees()),
 934					"HalfPi in radians is converted to degrees nearly 90 degree");
 935				Assert.True(MathHelper.NearlyEqual(360,
 936					PiDouble.RadiansToDegrees()),
 937					"PiDouble in radians is converted to degrees nearly 360 degree");
 938				Assert.NotEqual(0, MathHelper.RadiansToDegrees(-1));
 939			}
 940			#endregion
 941
 942			#region Lerp
 943			/// <summary>
 944			/// Lerp
 945			/// </summary>
 946			[Test]
 947			public void Lerp()
 948			{
 949				Assert.Equal(3, MathHelper.Lerp(5, 3, 1));
 950			}
 951			#endregion
 952
 953			#region TestIntTruncate
 954			/// <summary>
 955			/// Test int truncate
 956			/// </summary>
 957			[Test]
 958			public void TestIntTruncate()
 959			{
 960				Assert.Equal(17, (int)17.7f);
 961				Assert.Equal(17, (int)(17.2f + 0.5f));
 962			}
 963			#endregion
 964
 965			#region Sin
 966			/// <summary>
 967			/// Sin
 968			/// </summary>
 969			[Test]
 970			public void Sin()
 971			{
 972				Assert.Equal(0, MathHelper.Sin(0));
 973				Assert.Equal(1, MathHelper.Sin(90));
 974				Assert.True(MathHelper.NearlyEqual(0, MathHelper.Sin(180)),
 975					"the sin of 180 is nearly zero");
 976				Assert.True(MathHelper.NearlyEqual(0, MathHelper.Sin(360)),
 977					"the sin of 360 is nearly zero");
 978				Assert.NotEqual(0, MathHelper.Sin(32));
 979			}
 980			#endregion
 981
 982			#region Cos
 983			/// <summary>
 984			/// Sin
 985			/// </summary>
 986			[Test]
 987			public void Cos()
 988			{
 989				Assert.Equal(1, MathHelper.Cos(0));
 990				Assert.True(MathHelper.NearlyEqual(0, MathHelper.Cos(90)),
 991					"the cos of 90 is nearly zero");
 992				Assert.True(MathHelper.NearlyEqual(-1, MathHelper.Cos(180)),
 993					"the cos of 180 is nearly minus one");
 994				Assert.True(MathHelper.NearlyEqual(1, MathHelper.Cos(360)),
 995					"the cos of 360 is nearly one");
 996				Assert.NotEqual(0, MathHelper.Cos(32));
 997			}
 998			#endregion
 999
1000			#region Tan
1001			/// <summary>
1002			/// Tan
1003			/// </summary>
1004			[Test]
1005			public void Tan()
1006			{
1007				Assert.Equal(0, MathHelper.Tan(0));
1008				Assert.True(MathHelper.NearlyEqual(0, MathHelper.Tan(180)),
1009					"the tan of 180 is nearly zero");
1010				Assert.True(1.732051f.NearlyEqual(MathHelper.Tan(60)),
1011					"the tan of 60 is nearly 1.732051f");
1012				Assert.True(MathHelper.NearlyEqual(1, MathHelper.Tan(45)),
1013					"the tan of 45 is nearly one");
1014				Assert.True(MathHelper.NearlyEqual(-1, MathHelper.Tan(135)),
1015					"the tan of 135 is nearly minus one");
1016				Assert.NotEqual(0, MathHelper.Tan(32));
1017			}
1018			#endregion
1019
1020			#region Asin
1021			/// <summary>
1022			/// Asin
1023			/// </summary>
1024			[Test]
1025			public void Asin()
1026			{
1027				Assert.Equal(0, MathHelper.Asin(0));
1028				Assert.True(MathHelper.NearlyEqual(90, MathHelper.Asin(1)),
1029					"The Asin of 1 is nearly 90");
1030				Assert.True(MathHelper.NearlyEqual(30, MathHelper.Asin(0.5f)),
1031					"The Asin of 0.5 is nearly 30");
1032				Assert.NotEqual(0, MathHelper.Asin(0.2f));
1033			}
1034			#endregion
1035
1036			#region Acos
1037			/// <summary>
1038			/// Acos
1039			/// </summary>
1040			[Test]
1041			public void Acos()
1042			{
1043				Assert.True(MathHelper.NearlyEqual(90, MathHelper.Acos(0)),
1044					"The Acos of zero is nearly 90");
1045				Assert.True(MathHelper.NearlyEqual(0, MathHelper.Acos(1)),
1046					"The Acos of one is nearly zero");
1047				Assert.True(MathHelper.NearlyEqual(60, MathHelper.Acos(0.5f)),
1048					"The Acos of 0.5 is nearly 60");
1049				Assert.NotEqual(0, MathHelper.Acos(0.2f));
1050			}
1051			#endregion
1052
1053			#region Atan
1054			/// <summary>
1055			/// Atan
1056			/// </summary>
1057			[Test]
1058			public void Atan()
1059			{
1060				Assert.Equal(0, MathHelper.Atan(0));
1061				Assert.True(MathHelper.NearlyEqual(60, MathHelper.Atan(1.732051f)),
1062					"The Atan of 1.732051f is nearly 60");
1063				Assert.NotEqual(0, MathHelper.Atan(0.2f));
1064				Assert.Equal(0, MathHelper.Atan(0, 0));
1065				Assert.Equal(0, MathHelper.Atan(0, 1));
1066				Assert.True(MathHelper.NearlyEqual(90, MathHelper.Atan(1, 0)),
1067					"The Atan of the tangent(of one and zero) is nearly 90");
1068				Assert.True(MathHelper.NearlyEqual(45, MathHelper.Atan(1, 1)),
1069					"The Atan of the tangent(of one and one) is nearly 45");
1070				Assert.True(MathHelper.NearlyEqual(-90, MathHelper.Atan(-1, 0)),
1071					"The Atan of the tangent(of minus one and zero) is nearly minus 90");
1072				//  Math.Atan(0, -1));
1073				// Always works:
1074				Assert.Equal("180", MathHelper.Atan(0, -1).ToString());
1075				// Only works if Math.Epsilon for NearlyEqual is not smaller than
1076				// 0.0001
1077				Assert.True(MathHelper.NearlyEqual(180, MathHelper.Atan(0, -1)),
1078					"The Atan of the tangent(of zero and minus one) is nearly 180");
1079			}
1080			#endregion
1081
1082			#region GetNextPowerOfTwo
1083			/// <summary>
1084			/// Get next power of two
1085			/// </summary>
1086			[Test]
1087			public void GetNextPowerOfTwo()
1088			{
1089				Assert.Equal(128, MathHelper.GetNextPowerOfTwo(128));
1090				Assert.Equal(256, MathHelper.GetNextPowerOfTwo(129));
1091				Assert.Equal(1024, MathHelper.GetNextPowerOfTwo(529));
1092				Assert.Equal(2048, MathHelper.GetNextPowerOfTwo(1111));
1093				Assert.Equal(0, MathHelper.GetNextPowerOfTwo(-1));
1094			}
1095			#endregion
1096
1097			#region IsPowerOfTwo
1098			/// <summary>
1099			/// IsPowerOfTwo
1100			/// </summary>
1101			[Test]
1102			public void IsPowerOfTwo()
1103			{
1104				Assert.True(MathHelper.IsPowerOfTwo(128));
1105				Assert.False(MathHelper.IsPowerOfTwo(129));
1106				Assert.False(MathHelper.IsPowerOfTwo(529));
1107				Assert.False(MathHelper.IsPowerOfTwo(1111));
1108				Assert.True(MathHelper.IsPowerOfTwo(1024));
1109				Assert.False(MathHelper.IsPowerOfTwo(-1));
1110				Assert.True(MathHelper.IsPowerOfTwo(4));
1111			}
1112			#endregion
1113
1114			#region ComputeValue
1115			/// <summary>
1116			/// Compute value
1117			/// </summary>
1118			[Test]
1119			public void ComputeValue()
1120			{
1121				Assert.Equal(MathHelper.ComputeValue(0.5f, 10, 20), 15.0f);
1122
1123				Assert.Equal(MathHelper.ComputeValue(0.5f, 0, 10), 5.0f);
1124
1125				Assert.Equal(MathHelper.ComputeValue(0.5f, -10, 0), -5.0f);
1126
1127				Assert.Equal(MathHelper.ComputeValue(0.5f, -10, 10), 0.0f);
1128			}
1129			#endregion
1130
1131			#region ComputePercentageValue
1132			/// <summary>
1133			/// Compute percentage value
1134			/// </summary>
1135			[Test]
1136			public void ComputePercentageValue()
1137			{
1138				Assert.Equal(MathHelper.ComputePercentageValue(5, 0, 10), 0.5f);
1139
1140				Assert.Equal(MathHelper.ComputePercentageValue(0, -10, 10), 0.5f);
1141
1142				Assert.Equal(MathHelper.ComputePercentageValue(0, -360, 360), 0.5f);
1143
1144				Assert.Equal(MathHelper.ComputePercentageValue(-50, -100, -50), 1.0f);
1145
1146				Assert.Equal(MathHelper.ComputePercentageValue(-100, -100, -50), 0.0f);
1147
1148				Assert.Equal(MathHelper.ComputePercentageValue(0, 1000, -1000), 0.5f);
1149			}
1150			#endregion
1151		}
1152	}
1153}