Blame |
Last modification |
View Log
| RSS feed
#region --- License ---
/* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK Team.
* This notice may not be removed from any source distribution.
* See license.txt for licensing detailed licensing details.
*
* Contributions by Andy Gill, James Talton and Georg Wächter.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenTK
{
/// <summary>
/// Contains common mathematical functions and constants.
/// </summary>
public static class MathHelper
{
#region Fields
/// <summary>
/// Defines the value of Pi as a <see cref="System.Single"/>.
/// </summary>
public const float Pi
= 3
.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930382f
;
/// <summary>
/// Defines the value of Pi divided by two as a <see cref="System.Single"/>.
/// </summary>
public const float PiOver2
= Pi
/ 2;
/// <summary>
/// Defines the value of Pi divided by three as a <see cref="System.Single"/>.
/// </summary>
public const float PiOver3
= Pi
/ 3;
/// <summary>
/// Definesthe value of Pi divided by four as a <see cref="System.Single"/>.
/// </summary>
public const float PiOver4
= Pi
/ 4;
/// <summary>
/// Defines the value of Pi divided by six as a <see cref="System.Single"/>.
/// </summary>
public const float PiOver6
= Pi
/ 6;
/// <summary>
/// Defines the value of Pi multiplied by two as a <see cref="System.Single"/>.
/// </summary>
public const float TwoPi
= 2 * Pi
;
/// <summary>
/// Defines the value of Pi multiplied by 3 and divided by two as a <see cref="System.Single"/>.
/// </summary>
public const float ThreePiOver2
= 3 * Pi
/ 2;
/// <summary>
/// Defines the value of E as a <see cref="System.Single"/>.
/// </summary>
public const float E
= 2
.71828182845904523536f
;
/// <summary>
/// Defines the base-10 logarithm of E.
/// </summary>
public const float Log10E
= 0
.434294482f
;
/// <summary>
/// Defines the base-2 logarithm of E.
/// </summary>
public const float Log2E
= 1
.442695041f
;
#endregion
#region Public Members
#region NextPowerOfTwo
/// <summary>
/// Returns the next power of two that is larger than the specified number.
/// </summary>
/// <param name="n">The specified number.</param>
/// <returns>The next power of two.</returns>
public static long NextPowerOfTwo
(long n
)
{
if (n
< 0) throw new ArgumentOutOfRangeException
("n",
"Must be positive.");
return (long)System.Math.Pow(2,
System.Math.Ceiling(System.Math.Log((double)n,
2)));
}
/// <summary>
/// Returns the next power of two that is larger than the specified number.
/// </summary>
/// <param name="n">The specified number.</param>
/// <returns>The next power of two.</returns>
public static int NextPowerOfTwo
(int n
)
{
if (n
< 0) throw new ArgumentOutOfRangeException
("n",
"Must be positive.");
return (int)System.Math.Pow(2,
System.Math.Ceiling(System.Math.Log((double)n,
2)));
}
/// <summary>
/// Returns the next power of two that is larger than the specified number.
/// </summary>
/// <param name="n">The specified number.</param>
/// <returns>The next power of two.</returns>
public static float NextPowerOfTwo
(float n
)
{
if (n
< 0) throw new ArgumentOutOfRangeException
("n",
"Must be positive.");
return (float)System.Math.Pow(2,
System.Math.Ceiling(System.Math.Log((double)n,
2)));
}
/// <summary>
/// Returns the next power of two that is larger than the specified number.
/// </summary>
/// <param name="n">The specified number.</param>
/// <returns>The next power of two.</returns>
public static double NextPowerOfTwo
(double n
)
{
if (n
< 0) throw new ArgumentOutOfRangeException
("n",
"Must be positive.");
return System.Math.Pow(2,
System.Math.Ceiling(System.Math.Log((double)n,
2)));
}
#endregion
#region Factorial
/// <summary>Calculates the factorial of a given natural number.
/// </summary>
/// <param name="n">The number.</param>
/// <returns>n!</returns>
public static long Factorial
(int n
)
{
long result
= 1;
for (; n
> 1; n
--)
result
*= n
;
return result
;
}
#endregion
#region BinomialCoefficient
/// <summary>
/// Calculates the binomial coefficient <paramref name="n"/> above <paramref name="k"/>.
/// </summary>
/// <param name="n">The n.</param>
/// <param name="k">The k.</param>
/// <returns>n! / (k! * (n - k)!)</returns>
public static long BinomialCoefficient
(int n,
int k
)
{
return Factorial
(n
) / (Factorial
(k
) * Factorial
(n
- k
));
}
#endregion
#region InverseSqrtFast
/// <summary>
/// Returns an approximation of the inverse square root of left number.
/// </summary>
/// <param name="x">A number.</param>
/// <returns>An approximation of the inverse square root of the specified number, with an upper error bound of 0.001</returns>
/// <remarks>
/// This is an improved implementation of the the method known as Carmack's inverse square root
/// which is found in the Quake III source code. This implementation comes from
/// http://www.codemaestro.com/reviews/review00000105.html. For the history of this method, see
/// http://www.beyond3d.com/content/articles/8/
/// </remarks>
public static float InverseSqrtFast
(float x
)
{
unsafe
{
float xhalf
= 0
.5f
* x
;
int i
= *(int*)&x
; // Read bits as integer.
i
= 0x5f375a86
- (i
>> 1); // Make an initial guess for Newton-Raphson approximation
x
= *(float*)&i
; // Convert bits back to float
x
= x
* (1
.5f
- xhalf
* x
* x
); // Perform left single Newton-Raphson step.
return x
;
}
}
/// <summary>
/// Returns an approximation of the inverse square root of left number.
/// </summary>
/// <param name="x">A number.</param>
/// <returns>An approximation of the inverse square root of the specified number, with an upper error bound of 0.001</returns>
/// <remarks>
/// This is an improved implementation of the the method known as Carmack's inverse square root
/// which is found in the Quake III source code. This implementation comes from
/// http://www.codemaestro.com/reviews/review00000105.html. For the history of this method, see
/// http://www.beyond3d.com/content/articles/8/
/// </remarks>
public static double InverseSqrtFast
(double x
)
{
return InverseSqrtFast
((float)x
);
// TODO: The following code is wrong. Fix it, to improve precision.
#if false
unsafe
{
double xhalf
= 0
.5f
* x
;
int i
= *(int*)&x
; // Read bits as integer.
i
= 0x5f375a86
- (i
>> 1); // Make an initial guess for Newton-Raphson approximation
x
= *(float*)&i
; // Convert bits back to float
x
= x
* (1
.5f
- xhalf
* x
* x
); // Perform left single Newton-Raphson step.
return x
;
}
#endif
}
#endregion
#region DegreesToRadians
/// <summary>
/// Convert degrees to radians
/// </summary>
/// <param name="degrees">An angle in degrees</param>
/// <returns>The angle expressed in radians</returns>
public static float DegreesToRadians
(float degrees
)
{
const float degToRad
= (float)System.Math.PI / 180
.0f
;
return degrees
* degToRad
;
}
/// <summary>
/// Convert radians to degrees
/// </summary>
/// <param name="radians">An angle in radians</param>
/// <returns>The angle expressed in degrees</returns>
public static float RadiansToDegrees
(float radians
)
{
const float radToDeg
= 180
.0f
/ (float)System.Math.PI;
return radians
* radToDeg
;
}
#endregion
#region Swap
/// <summary>
/// Swaps two double values.
/// </summary>
/// <param name="a">The first value.</param>
/// <param name="b">The second value.</param>
public static void Swap
(ref double a,
ref double b
)
{
double temp
= a
;
a
= b
;
b
= temp
;
}
/// <summary>
/// Swaps two float values.
/// </summary>
/// <param name="a">The first value.</param>
/// <param name="b">The second value.</param>
public static void Swap
(ref float a,
ref float b
)
{
float temp
= a
;
a
= b
;
b
= temp
;
}
#endregion
#endregion
}
}