Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/archive/animated_space_boundaries/src/libraries/util/Math.h @ 12373

Last change on this file since 12373 was 8615, checked in by landauf, 14 years ago

turns out the mod(x,y) function was fucked up all the time. we need unit tests! also there was a small bug in the shell history. fixed both.

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