Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8121 was 7427, checked in by rgrieder, 14 years ago

Applied fixes from sandbox_qt 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#include <cstdlib>
48
49#include <OgreMath.h>
50#include <OgreVector2.h>
51#include <OgreVector3.h>
52#include <OgreVector4.h>
53#include <OgreQuaternion.h>
54#include <OgreColourValue.h>
55
56// Certain headers might define unwanted macros...
57#undef max
58#undef min
59#undef sgn
60#undef clamp
61#undef sqrt
62#undef square
63#undef mod
64#undef rnd
65
66namespace orxonox
67{
68    // C++ doesn't define any constants for pi, e, etc.
69    namespace math
70    {
71        const float pi      = 3.14159265f;      ///< PI
72        const float pi_2    = 1.57079633f;      ///< PI / 2
73        const float pi_4    = 7.85398163e-1f;   ///< PI / 4
74        const float e       = 2.71828183f;      ///< e
75        const float sqrt2   = 1.41421356f;      ///< sqrt(2)
76        const float sqrt2_2 = 7.07106781e-1f;   ///< sqrt(2) / 2
77
78        const double pi_d      = 3.14159265358979324;       ///< PI (double)
79        const double pi_2_d    = 1.57079632679489662;       ///< PI / 2 (double)
80        const double pi_4_d    = 7.85398163397448310e-1;    ///< PI / 4 (double)
81        const double e_d       = 2.71828182845904524;       ///< e (double)
82        const double sqrt2_d   = 1.41421356237309505;       ///< sqrt(2) (double)
83        const double sqrt2_2_d = 7.07106781186547524e-1;    ///< sqrt(2) / 2 (double)
84    }
85
86#if OGRE_VERSION < 0x010603
87    _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian);
88    _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree);
89#endif
90    _UtilExport std::istream& operator>>(std::istream& in, orxonox::Radian& radian);
91    _UtilExport std::istream& operator>>(std::istream& in, orxonox::Degree& degree);
92
93    _UtilExport float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition);
94    _UtilExport orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);
95    _UtilExport orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);
96    _UtilExport orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity);
97
98    /**
99        @brief Returns the sign of the given value.
100        @param x The value
101        @return 1 if the value is positive or zero, -1 if the value is negative
102    */
103    template <typename T>
104    inline T sgn(T x)
105    {
106        return (x >= 0) ? (T)1 : (T)-1;
107    }
108
109    /**
110        @brief Keeps a value between a lower and an upper limit. Values beyond these limits are limited to either @a min or @a max.
111        @param x The value
112        @param min The lower limit
113        @param max The upper limit
114    */
115    template <typename T>
116    inline T clamp(T x, T min, T max)
117    {
118        if (x < min)
119            return min;
120
121        if (x > max)
122            return max;
123
124        return x;
125    }
126
127    /**
128        @brief Returns the squared value (x^2).
129    */
130    template <typename T>
131    inline T square(T x)
132    {
133        return x*x;
134    }
135
136    /**
137        @brief Returns the cubed value (x^3).
138    */
139    template <typename T>
140    inline T cube(T x)
141    {
142        return x*x*x;
143    }
144
145    /**
146        @brief Rounds the value to the nearest integer.
147    */
148    template <typename T>
149    inline int round(T x)
150    {
151        return static_cast<int>(x + 0.5);
152    }
153
154    /**
155        @brief The modulo operation, enhanced to work properly with negative values.
156        @param x The value
157        @param max The operand
158
159        The built in modulo operator % yields a strange behavior with negative values.
160        This function corrects this - the result is guaranteed to lie always between
161        zero and (max-1).
162
163        Example:
164        @code
165        int var = 11 % 10;      //  1
166        int var = -1 % 10;      // -1
167
168        int var = mod(11, 10);  //  1
169        int var = mod(-1, 10);  //  9
170        @endcode
171    */
172    template <typename T>
173    inline int mod(T x, int max)
174    {
175        if (x >= 0)
176            return (x % max);
177        else
178            return ((x % max) + max);
179    }
180
181    /**
182        @brief Returns a "zero" value for the given type.
183        @note This is the default template of the zeroise() function. The template is spezialized for each supported type.
184
185        The exact return value of the function depends on the type. For @c int this is 0,
186        for @c float it's 0.0f. For a @c std::string the function returns "" and for
187        @c Vector3 you get <tt>Vector3(0, 0, 0)</tt>.
188    */
189    template <typename T>
190    inline T zeroise()
191    {
192        // Default, raise a compiler error without including large boost header cascade.
193        T temp();
194        *********temp; // If you reach this code, you abused zeroise()!
195        return temp;
196    }
197
198    template <> inline char                 zeroise<char>()                 { return 0; }
199    template <> inline unsigned char        zeroise<unsigned char>()        { return 0; }
200    template <> inline short                zeroise<short>()                { return 0; }
201    template <> inline unsigned short       zeroise<unsigned short>()       { return 0; }
202    template <> inline int                  zeroise<int>()                  { return 0; }
203    template <> inline unsigned int         zeroise<unsigned int>()         { return 0; }
204    template <> inline long                 zeroise<long>()                 { return 0; }
205    template <> inline unsigned long        zeroise<unsigned long>()        { return 0; }
206    template <> inline long long            zeroise<long long>()            { return 0; }
207    template <> inline unsigned long long   zeroise<unsigned long long>()   { return 0; }
208    template <> inline float                zeroise<float>()                { return 0; }
209    template <> inline double               zeroise<double>()               { return 0; }
210    template <> inline long double          zeroise<long double>()          { return 0; }
211    template <> inline bool                 zeroise<bool>()                 { return 0; }
212    template <> inline void*                zeroise<void*>()                { return 0; }
213    template <> inline std::string          zeroise<std::string>()          { return std::string(); }
214    template <> inline orxonox::Radian      zeroise<orxonox::Radian>()      { return orxonox::Radian(0.0f); }
215    template <> inline orxonox::Degree      zeroise<orxonox::Degree>()      { return orxonox::Degree(0.0f); }
216    template <> inline orxonox::Vector2     zeroise<orxonox::Vector2>()     { return orxonox::Vector2    (0, 0)      ; }
217    template <> inline orxonox::Vector3     zeroise<orxonox::Vector3>()     { return orxonox::Vector3    (0, 0, 0)   ; }
218    template <> inline orxonox::Vector4     zeroise<orxonox::Vector4>()     { return orxonox::Vector4    (0, 0, 0, 0); }
219    template <> inline orxonox::ColourValue zeroise<orxonox::ColourValue>() { return orxonox::ColourValue(0, 0, 0, 0); }
220    template <> inline orxonox::Quaternion  zeroise<orxonox::Quaternion>()  { return orxonox::Quaternion (0, 0, 0, 0); }
221
222    /**
223        @brief Provides zero value symbols that can be returned as reference
224        @see zeroise()
225    */
226    template <typename T>
227    struct NilValue
228    {
229        inline operator const T&() const
230        {
231            return value;
232        }
233        static T value;
234    };
235    template <typename T>
236    T NilValue<T>::value = zeroise<T>();
237
238    /**
239        @brief Interpolates between two values for a time between 0 and 1.
240        @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.
241        @param start The value at @a time = 0
242        @param end The value at @a time = 1
243        @return The interpolated value at a given time
244    */
245    template <typename T>
246    inline T interpolate(float time, const T& start, const T& end)
247    {
248        return time * (end - start) + start;
249    }
250
251    /**
252        @brief Interpolates smoothly between two values for a time between 0 and 1. The function starts slowly, increases faster and stops slowly again.
253        @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.
254        @param start The value at @a time = 0
255        @param end The value at @a time = 1
256        @return The interpolated value at a given time
257    */
258    template <typename T>
259    inline T interpolateSmooth(float time, const T& start, const T& end)
260    {
261        return (-2 * (end - start) * cube(time)) + (3 * (end - start) * square(time)) + start;
262    }
263
264    /**
265        @brief Returns a random number between 0 and almost 1: <tt>0 <= rnd < 1</tt>.
266    */
267    inline float rnd()
268    {
269        return rand() / (RAND_MAX + 1.0f);
270    }
271
272    /**
273        @brief Returns a random number between 0 and almost @a max: <tt>0 <= rnd < max</tt>.
274        @param max The maximum
275    */
276    inline float rnd(float max)
277    {
278        return rnd() * max;
279    }
280
281    /**
282        @brief Returns a random number between @a min and almost @a max: <tt>min <= rnd < max</tt>.
283        @param min The minimum
284        @param max The maximum
285    */
286    inline float rnd(float min, float max)
287    {
288        return rnd(max - min) + min;
289    }
290
291    /**
292        @brief Returns randomly 1 or -1 with equal probability.
293    */
294    inline float rndsgn()
295    {
296        return static_cast<float>((rand() & 0x2) - 1); // rand() & 0x2 is either 2 or 0
297    }
298
299    _UtilExport unsigned long getUniqueNumber();
300
301    /**
302        @brief A Vector class containing two integers @a x and @a y.
303    */
304    class IntVector2
305    {
306    public:
307        IntVector2() : x(0), y(0) { }
308        IntVector2(int _x, int _y) : x(_x), y(_y) { }
309        int x;
310        int y;
311    };
312
313    /**
314        @brief A Vector class containing three integers @a x, @a y, and @a z.
315    */
316    class IntVector3
317    {
318    public:
319        IntVector3() : x(0), y(0), z(0) { }
320        IntVector3(int _x, int _y, int _z) : x(_x), y(_y), z(_z) { }
321        int x;
322        int y;
323        int z;
324    };
325}
326
327#endif /* _Util_Math_H__ */
Note: See TracBrowser for help on using the repository browser.