Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1452 | chris | 1 | #region --- License --- |
| 2 | /* Licensed under the MIT/X11 license. |
||
| 3 | * Copyright (c) 2006-2008 the OpenTK Team. |
||
| 4 | * This notice may not be removed from any source distribution. |
||
| 5 | * See license.txt for licensing detailed licensing details. |
||
| 6 | * |
||
| 7 | * Contributions by Andy Gill, James Talton and Georg Wächter. |
||
| 8 | */ |
||
| 9 | #endregion |
||
| 10 | |||
| 11 | using System; |
||
| 12 | using System.Collections.Generic; |
||
| 13 | using System.Text; |
||
| 14 | |||
| 15 | namespace OpenTK |
||
| 16 | { |
||
| 17 | /// <summary> |
||
| 18 | /// Contains common mathematical functions and constants. |
||
| 19 | /// </summary> |
||
| 20 | public static class MathHelper |
||
| 21 | { |
||
| 22 | #region Fields |
||
| 23 | |||
| 24 | /// <summary> |
||
| 25 | /// Defines the value of Pi as a <see cref="System.Single"/>. |
||
| 26 | /// </summary> |
||
| 27 | public const float Pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930382f; |
||
| 28 | |||
| 29 | /// <summary> |
||
| 30 | /// Defines the value of Pi divided by two as a <see cref="System.Single"/>. |
||
| 31 | /// </summary> |
||
| 32 | public const float PiOver2 = Pi / 2; |
||
| 33 | |||
| 34 | /// <summary> |
||
| 35 | /// Defines the value of Pi divided by three as a <see cref="System.Single"/>. |
||
| 36 | /// </summary> |
||
| 37 | public const float PiOver3 = Pi / 3; |
||
| 38 | |||
| 39 | /// <summary> |
||
| 40 | /// Definesthe value of Pi divided by four as a <see cref="System.Single"/>. |
||
| 41 | /// </summary> |
||
| 42 | public const float PiOver4 = Pi / 4; |
||
| 43 | |||
| 44 | /// <summary> |
||
| 45 | /// Defines the value of Pi divided by six as a <see cref="System.Single"/>. |
||
| 46 | /// </summary> |
||
| 47 | public const float PiOver6 = Pi / 6; |
||
| 48 | |||
| 49 | /// <summary> |
||
| 50 | /// Defines the value of Pi multiplied by two as a <see cref="System.Single"/>. |
||
| 51 | /// </summary> |
||
| 52 | public const float TwoPi = 2 * Pi; |
||
| 53 | |||
| 54 | /// <summary> |
||
| 55 | /// Defines the value of Pi multiplied by 3 and divided by two as a <see cref="System.Single"/>. |
||
| 56 | /// </summary> |
||
| 57 | public const float ThreePiOver2 = 3 * Pi / 2; |
||
| 58 | |||
| 59 | /// <summary> |
||
| 60 | /// Defines the value of E as a <see cref="System.Single"/>. |
||
| 61 | /// </summary> |
||
| 62 | public const float E = 2.71828182845904523536f; |
||
| 63 | |||
| 64 | /// <summary> |
||
| 65 | /// Defines the base-10 logarithm of E. |
||
| 66 | /// </summary> |
||
| 67 | public const float Log10E = 0.434294482f; |
||
| 68 | |||
| 69 | /// <summary> |
||
| 70 | /// Defines the base-2 logarithm of E. |
||
| 71 | /// </summary> |
||
| 72 | public const float Log2E = 1.442695041f; |
||
| 73 | |||
| 74 | #endregion |
||
| 75 | |||
| 76 | #region Public Members |
||
| 77 | |||
| 78 | #region NextPowerOfTwo |
||
| 79 | |||
| 80 | /// <summary> |
||
| 81 | /// Returns the next power of two that is larger than the specified number. |
||
| 82 | /// </summary> |
||
| 83 | /// <param name="n">The specified number.</param> |
||
| 84 | /// <returns>The next power of two.</returns> |
||
| 85 | public static long NextPowerOfTwo(long n) |
||
| 86 | { |
||
| 87 | if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive."); |
||
| 88 | return (long)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2))); |
||
| 89 | } |
||
| 90 | |||
| 91 | /// <summary> |
||
| 92 | /// Returns the next power of two that is larger than the specified number. |
||
| 93 | /// </summary> |
||
| 94 | /// <param name="n">The specified number.</param> |
||
| 95 | /// <returns>The next power of two.</returns> |
||
| 96 | public static int NextPowerOfTwo(int n) |
||
| 97 | { |
||
| 98 | if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive."); |
||
| 99 | return (int)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2))); |
||
| 100 | } |
||
| 101 | |||
| 102 | /// <summary> |
||
| 103 | /// Returns the next power of two that is larger than the specified number. |
||
| 104 | /// </summary> |
||
| 105 | /// <param name="n">The specified number.</param> |
||
| 106 | /// <returns>The next power of two.</returns> |
||
| 107 | public static float NextPowerOfTwo(float n) |
||
| 108 | { |
||
| 109 | if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive."); |
||
| 110 | return (float)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2))); |
||
| 111 | } |
||
| 112 | |||
| 113 | /// <summary> |
||
| 114 | /// Returns the next power of two that is larger than the specified number. |
||
| 115 | /// </summary> |
||
| 116 | /// <param name="n">The specified number.</param> |
||
| 117 | /// <returns>The next power of two.</returns> |
||
| 118 | public static double NextPowerOfTwo(double n) |
||
| 119 | { |
||
| 120 | if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive."); |
||
| 121 | return System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2))); |
||
| 122 | } |
||
| 123 | |||
| 124 | #endregion |
||
| 125 | |||
| 126 | #region Factorial |
||
| 127 | |||
| 128 | /// <summary>Calculates the factorial of a given natural number. |
||
| 129 | /// </summary> |
||
| 130 | /// <param name="n">The number.</param> |
||
| 131 | /// <returns>n!</returns> |
||
| 132 | public static long Factorial(int n) |
||
| 133 | { |
||
| 134 | long result = 1; |
||
| 135 | |||
| 136 | for (; n > 1; n--) |
||
| 137 | result *= n; |
||
| 138 | |||
| 139 | return result; |
||
| 140 | } |
||
| 141 | |||
| 142 | #endregion |
||
| 143 | |||
| 144 | #region BinomialCoefficient |
||
| 145 | |||
| 146 | /// <summary> |
||
| 147 | /// Calculates the binomial coefficient <paramref name="n"/> above <paramref name="k"/>. |
||
| 148 | /// </summary> |
||
| 149 | /// <param name="n">The n.</param> |
||
| 150 | /// <param name="k">The k.</param> |
||
| 151 | /// <returns>n! / (k! * (n - k)!)</returns> |
||
| 152 | public static long BinomialCoefficient(int n, int k) |
||
| 153 | { |
||
| 154 | return Factorial(n) / (Factorial(k) * Factorial(n - k)); |
||
| 155 | } |
||
| 156 | |||
| 157 | #endregion |
||
| 158 | |||
| 159 | #region InverseSqrtFast |
||
| 160 | |||
| 161 | /// <summary> |
||
| 162 | /// Returns an approximation of the inverse square root of left number. |
||
| 163 | /// </summary> |
||
| 164 | /// <param name="x">A number.</param> |
||
| 165 | /// <returns>An approximation of the inverse square root of the specified number, with an upper error bound of 0.001</returns> |
||
| 166 | /// <remarks> |
||
| 167 | /// This is an improved implementation of the the method known as Carmack's inverse square root |
||
| 168 | /// which is found in the Quake III source code. This implementation comes from |
||
| 169 | /// http://www.codemaestro.com/reviews/review00000105.html. For the history of this method, see |
||
| 170 | /// http://www.beyond3d.com/content/articles/8/ |
||
| 171 | /// </remarks> |
||
| 172 | public static float InverseSqrtFast(float x) |
||
| 173 | { |
||
| 174 | unsafe |
||
| 175 | { |
||
| 176 | float xhalf = 0.5f * x; |
||
| 177 | int i = *(int*)&x; // Read bits as integer. |
||
| 178 | i = 0x5f375a86 - (i >> 1); // Make an initial guess for Newton-Raphson approximation |
||
| 179 | x = *(float*)&i; // Convert bits back to float |
||
| 180 | x = x * (1.5f - xhalf * x * x); // Perform left single Newton-Raphson step. |
||
| 181 | return x; |
||
| 182 | } |
||
| 183 | } |
||
| 184 | |||
| 185 | /// <summary> |
||
| 186 | /// Returns an approximation of the inverse square root of left number. |
||
| 187 | /// </summary> |
||
| 188 | /// <param name="x">A number.</param> |
||
| 189 | /// <returns>An approximation of the inverse square root of the specified number, with an upper error bound of 0.001</returns> |
||
| 190 | /// <remarks> |
||
| 191 | /// This is an improved implementation of the the method known as Carmack's inverse square root |
||
| 192 | /// which is found in the Quake III source code. This implementation comes from |
||
| 193 | /// http://www.codemaestro.com/reviews/review00000105.html. For the history of this method, see |
||
| 194 | /// http://www.beyond3d.com/content/articles/8/ |
||
| 195 | /// </remarks> |
||
| 196 | public static double InverseSqrtFast(double x) |
||
| 197 | { |
||
| 198 | return InverseSqrtFast((float)x); |
||
| 199 | // TODO: The following code is wrong. Fix it, to improve precision. |
||
| 200 | #if false |
||
| 201 | unsafe |
||
| 202 | { |
||
| 203 | double xhalf = 0.5f * x; |
||
| 204 | int i = *(int*)&x; // Read bits as integer. |
||
| 205 | i = 0x5f375a86 - (i >> 1); // Make an initial guess for Newton-Raphson approximation |
||
| 206 | x = *(float*)&i; // Convert bits back to float |
||
| 207 | x = x * (1.5f - xhalf * x * x); // Perform left single Newton-Raphson step. |
||
| 208 | return x; |
||
| 209 | } |
||
| 210 | #endif |
||
| 211 | } |
||
| 212 | |||
| 213 | #endregion |
||
| 214 | |||
| 215 | #region DegreesToRadians |
||
| 216 | |||
| 217 | /// <summary> |
||
| 218 | /// Convert degrees to radians |
||
| 219 | /// </summary> |
||
| 220 | /// <param name="degrees">An angle in degrees</param> |
||
| 221 | /// <returns>The angle expressed in radians</returns> |
||
| 222 | public static float DegreesToRadians(float degrees) |
||
| 223 | { |
||
| 224 | const float degToRad = (float)System.Math.PI / 180.0f; |
||
| 225 | return degrees * degToRad; |
||
| 226 | } |
||
| 227 | |||
| 228 | /// <summary> |
||
| 229 | /// Convert radians to degrees |
||
| 230 | /// </summary> |
||
| 231 | /// <param name="radians">An angle in radians</param> |
||
| 232 | /// <returns>The angle expressed in degrees</returns> |
||
| 233 | public static float RadiansToDegrees(float radians) |
||
| 234 | { |
||
| 235 | const float radToDeg = 180.0f / (float)System.Math.PI; |
||
| 236 | return radians * radToDeg; |
||
| 237 | } |
||
| 238 | |||
| 239 | #endregion |
||
| 240 | |||
| 241 | #region Swap |
||
| 242 | |||
| 243 | /// <summary> |
||
| 244 | /// Swaps two double values. |
||
| 245 | /// </summary> |
||
| 246 | /// <param name="a">The first value.</param> |
||
| 247 | /// <param name="b">The second value.</param> |
||
| 248 | public static void Swap(ref double a, ref double b) |
||
| 249 | { |
||
| 250 | double temp = a; |
||
| 251 | a = b; |
||
| 252 | b = temp; |
||
| 253 | } |
||
| 254 | |||
| 255 | /// <summary> |
||
| 256 | /// Swaps two float values. |
||
| 257 | /// </summary> |
||
| 258 | /// <param name="a">The first value.</param> |
||
| 259 | /// <param name="b">The second value.</param> |
||
| 260 | public static void Swap(ref float a, ref float b) |
||
| 261 | { |
||
| 262 | float temp = a; |
||
| 263 | a = b; |
||
| 264 | b = temp; |
||
| 265 | } |
||
| 266 | |||
| 267 | #endregion |
||
| 268 | |||
| 269 | #endregion |
||
| 270 | } |
||
| 271 | } |