Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/util/Math.h @ 7404

Last change on this file since 7404 was 7401, checked in by landauf, 14 years ago

merged doc branch back to trunk

  • Property svn:eol-style set to native
File size: 11.4 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @defgroup Math Mathematical functions
31    @ingroup Util
32*/
33
34/**
35    @file
36    @ingroup Math
37    @brief Declaration and implementation of several math-functions, typedefs of some Ogre::Math classes to the orxonox namespace.
38*/
39
40#ifndef _Util_Math_H__
41#define _Util_Math_H__
42
43#include "UtilPrereqs.h"
44
45#include <string>
46#include <cmath>
47
48#include <OgreMath.h>
49#include <OgreVector2.h>
50#include <OgreVector3.h>
51#include <OgreVector4.h>
52#include <OgreQuaternion.h>
53#include <OgreColourValue.h>
54
55// Certain headers might define unwanted macros...
56#undef max
57#undef min
58#undef sgn
59#undef clamp
60#undef sqrt
61#undef square
62#undef mod
63#undef rnd
64
65namespace orxonox
66{
67    // C++ doesn't define any constants for pi, e, etc.
68    namespace math
69    {
70        const float pi      = 3.14159265f;      ///< PI
71        const float pi_2    = 1.57079633f;      ///< PI / 2
72        const float pi_4    = 7.85398163e-1f;   ///< PI / 4
73        const float e       = 2.71828183f;      ///< e
74        const float sqrt2   = 1.41421356f;      ///< sqrt(2)
75        const float sqrt2_2 = 7.07106781e-1f;   ///< sqrt(2) / 2
76
77        const double pi_d      = 3.14159265358979324;       ///< PI (double)
78        const double pi_2_d    = 1.57079632679489662;       ///< PI / 2 (double)
79        const double pi_4_d    = 7.85398163397448310e-1;    ///< PI / 4 (double)
80        const double e_d       = 2.71828182845904524;       ///< e (double)
81        const double sqrt2_d   = 1.41421356237309505;       ///< sqrt(2) (double)
82        const double sqrt2_2_d = 7.07106781186547524e-1;    ///< sqrt(2) / 2 (double)
83    }
84
85#if OGRE_VERSION < 0x010603
86    _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian);
87    _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree);
88#endif
89    _UtilExport std::istream& operator>>(std::istream& in, orxonox::Radian& radian);
90    _UtilExport std::istream& operator>>(std::istream& in, orxonox::Degree& degree);
91
92    _UtilExport float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition);
93    _UtilExport orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);
94    _UtilExport orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);
95    _UtilExport orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity);
96
97    /**
98        @brief Returns the sign of the given value.
99        @param x The value
100        @return 1 if the value is positive or zero, -1 if the value is negative
101    */
102    template <typename T>
103    inline T sgn(T x)
104    {
105        return (x >= 0) ? (T)1 : (T)-1;
106    }
107
108    /**
109        @brief Keeps a value between a lower and an upper limit. Values beyond these limits are limited to either @a min or @a max.
110        @param x The value
111        @param min The lower limit
112        @param max The upper limit
113    */
114    template <typename T>
115    inline T clamp(T x, T min, T max)
116    {
117        if (x < min)
118            return min;
119
120        if (x > max)
121            return max;
122
123        return x;
124    }
125
126    /**
127        @brief Returns the squared value (x^2).
128    */
129    template <typename T>
130    inline T square(T x)
131    {
132        return x*x;
133    }
134
135    /**
136        @brief Returns the cubed value (x^3).
137    */
138    template <typename T>
139    inline T cube(T x)
140    {
141        return x*x*x;
142    }
143
144    /**
145        @brief Rounds the value to the nearest integer.
146    */
147    template <typename T>
148    inline int round(T x)
149    {
150        return static_cast<int>(x + 0.5);
151    }
152
153    /**
154        @brief The modulo operation, enhanced to work properly with negative values.
155        @param x The value
156        @param max The operand
157
158        The built in modulo operator % yields a strange behavior with negative values.
159        This function corrects this - the result is guaranteed to lie always between
160        zero and (max-1).
161
162        Example:
163        @code
164        int var = 11 % 10;      //  1
165        int var = -1 % 10;      // -1
166
167        int var = mod(11, 10);  //  1
168        int var = mod(-1, 10);  //  9
169        @endcode
170    */
171    template <typename T>
172    inline int mod(T x, int max)
173    {
174        if (x >= 0)
175            return (x % max);
176        else
177            return ((x % max) + max);
178    }
179
180    /**
181        @brief Returns a "zero" value for the given type.
182        @note This is the default template of the zeroise() function. The template is spezialized for each supported type.
183
184        The exact return value of the function depends on the type. For @c int this is 0,
185        for @c float it's 0.0f. For a @c std::string the function returns "" and for
186        @c Vector3 you get <tt>Vector3(0, 0, 0)</tt>.
187    */
188    template <typename T>
189    inline T zeroise()
190    {
191        // Default, raise a compiler error without including large boost header cascade.
192        T temp();
193        *********temp; // If you reach this code, you abused zeroise()!
194        return temp;
195    }
196
197    template <> inline char                 zeroise<char>()                 { return 0; }
198    template <> inline unsigned char        zeroise<unsigned char>()        { return 0; }
199    template <> inline short                zeroise<short>()                { return 0; }
200    template <> inline unsigned short       zeroise<unsigned short>()       { return 0; }
201    template <> inline int                  zeroise<int>()                  { return 0; }
202    template <> inline unsigned int         zeroise<unsigned int>()         { return 0; }
203    template <> inline long                 zeroise<long>()                 { return 0; }
204    template <> inline unsigned long        zeroise<unsigned long>()        { return 0; }
205    template <> inline long long            zeroise<long long>()            { return 0; }
206    template <> inline unsigned long long   zeroise<unsigned long long>()   { return 0; }
207    template <> inline float                zeroise<float>()                { return 0; }
208    template <> inline double               zeroise<double>()               { return 0; }
209    template <> inline long double          zeroise<long double>()          { return 0; }
210    template <> inline bool                 zeroise<bool>()                 { return 0; }
211    template <> inline void*                zeroise<void*>()                { return 0; }
212    template <> inline std::string          zeroise<std::string>()          { return std::string(); }
213    template <> inline orxonox::Radian      zeroise<orxonox::Radian>()      { return orxonox::Radian(0.0f); }
214    template <> inline orxonox::Degree      zeroise<orxonox::Degree>()      { return orxonox::Degree(0.0f); }
215    template <> inline orxonox::Vector2     zeroise<orxonox::Vector2>()     { return orxonox::Vector2    (0, 0)      ; }
216    template <> inline orxonox::Vector3     zeroise<orxonox::Vector3>()     { return orxonox::Vector3    (0, 0, 0)   ; }
217    template <> inline orxonox::Vector4     zeroise<orxonox::Vector4>()     { return orxonox::Vector4    (0, 0, 0, 0); }
218    template <> inline orxonox::ColourValue zeroise<orxonox::ColourValue>() { return orxonox::ColourValue(0, 0, 0, 0); }
219    template <> inline orxonox::Quaternion  zeroise<orxonox::Quaternion>()  { return orxonox::Quaternion (0, 0, 0, 0); }
220
221    /**
222        @brief Provides zero value symbols that can be returned as reference
223        @see zeroise()
224    */
225    template <typename T>
226    struct NilValue
227    {
228        inline operator const T&() const
229        {
230            return value;
231        }
232        static T value;
233    };
234    template <typename T>
235    T NilValue<T>::value = zeroise<T>();
236
237    /**
238        @brief Interpolates between two values for a time between 0 and 1.
239        @param time The time is a value between 0 and 1 - the function returns @a start if @a time is 0, @a end if @a time is 1, and interpolates if @a time is between 0 and 1.
240        @param start The value at @a time = 0
241        @param end The value at @a time = 1
242        @return The interpolated value at a given time
243    */
244    template <typename T>
245    inline T interpolate(float time, const T& start, const T& end)
246    {
247        return time * (end - start) + start;
248    }
249
250    /**
251        @brief Interpolates smoothly between two values for a time between 0 and 1. The function starts slowly, increases faster and stops slowly again.
252        @param time The time is a value between 0 and 1 - the function returns @a start if @a time is 0, @a end if @a time is 1, and interpolates if @a time is between 0 and 1.
253        @param start The value at @a time = 0
254        @param end The value at @a time = 1
255        @return The interpolated value at a given time
256    */
257    template <typename T>
258    inline T interpolateSmooth(float time, const T& start, const T& end)
259    {
260        return (-2 * (end - start) * cube(time)) + (3 * (end - start) * square(time)) + start;
261    }
262
263    /**
264        @brief Returns a random number between 0 and almost 1: <tt>0 <= rnd < 1</tt>.
265    */
266    inline float rnd()
267    {
268        return rand() / (RAND_MAX + 1.0f);
269    }
270
271    /**
272        @brief Returns a random number between 0 and almost @a max: <tt>0 <= rnd < max</tt>.
273        @param max The maximum
274    */
275    inline float rnd(float max)
276    {
277        return rnd() * max;
278    }
279
280    /**
281        @brief Returns a random number between @a min and almost @a max: <tt>min <= rnd < max</tt>.
282        @param min The minimum
283        @param max The maximum
284    */
285    inline float rnd(float min, float max)
286    {
287        return rnd(max - min) + min;
288    }
289
290    /**
291        @brief Returns randomly 1 or -1 with equal probability.
292    */
293    inline float rndsgn()
294    {
295        return static_cast<float>((rand() & 0x2) - 1); // rand() & 0x2 is either 2 or 0
296    }
297
298    _UtilExport unsigned long getUniqueNumber();
299
300    /**
301        @brief A Vector class containing two integers @a x and @a y.
302    */
303    class IntVector2
304    {
305    public:
306        IntVector2() : x(0), y(0) { }
307        IntVector2(int _x, int _y) : x(_x), y(_y) { }
308        int x;
309        int y;
310    };
311
312    /**
313        @brief A Vector class containing three integers @a x, @a y, and @a z.
314    */
315    class IntVector3
316    {
317    public:
318        IntVector3() : x(0), y(0), z(0) { }
319        IntVector3(int _x, int _y, int _z) : x(_x), y(_y), z(_z) { }
320        int x;
321        int y;
322        int z;
323    };
324}
325
326#endif /* _Util_Math_H__ */
Note: See TracBrowser for help on using the repository browser.