Subversion Repositories AndroidProjects

Rev

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
}