Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v2/src/libraries/util/Math.h @ 10742

Last change on this file since 10742 was 10742, checked in by landauf, 9 years ago

use constexpr for some math functions and constants

  • Property svn:eol-style set to native
File size: 11.5 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 *      Wolfgang Roenninger
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        constexpr float twoPi   = 6.283185482025146484375f;     ///< PI * 2
76        constexpr float pi      = 3.1415927410125732421875f;    ///< PI
77        constexpr float pi_2    = 1.57079637050628662109375f;   ///< PI / 2
78        constexpr float pi_4    = 0.785398185253143310546875f;  ///< PI / 4
79        constexpr float e       = 2.718281269073486328125f;     ///< e
80        constexpr float sqrt2   = 1.41421353816986083984375f;   ///< sqrt(2)
81        constexpr 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::Vector2 get3DProjection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition, const float mapangle, const float detectionlimit);
95    _UtilExport bool isObjectHigherThanShipOnMap(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition, const float mapangle);
96    _UtilExport int determineMap3DZOrder(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition, const float detectionlimit);
97    _UtilExport orxonox::Vector3 getTransformedVector(const orxonox::Vector3& distance, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& myside);
98    _UtilExport orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity);
99
100    /**
101        @brief Returns the sign of the given value.
102        @param x The value
103        @return 1 if the value is positive or zero, -1 if the value is negative
104    */
105    template <typename T>
106    constexpr inline T sgn(T x)
107    {
108        return (x >= 0) ? (T)1 : (T)-1;
109    }
110
111    /**
112        @brief Keeps a value between a lower and an upper limit. Values beyond these limits are limited to either @a min or @a max.
113        @param x The value
114        @param min The lower limit
115        @param max The upper limit
116    */
117    template <typename T>
118    constexpr inline T clamp(T x, T min, T max)
119    {
120        return x < min ? min : (x > max ? max : x);
121    }
122
123    /**
124        @brief Returns the squared value (x^2).
125    */
126    template <typename T>
127    constexpr inline T square(T x)
128    {
129        return x*x;
130    }
131
132    /**
133        @brief Returns the cubed value (x^3).
134    */
135    template <typename T>
136    constexpr inline T cube(T x)
137    {
138        return x*x*x;
139    }
140
141    /**
142        @brief The modulo operation, enhanced to work properly with negative values.
143        @param x The value
144        @param max The operand
145
146        The built in modulo operator % yields a strange behavior with negative values.
147        This function corrects this - the result is guaranteed to lie always between
148        zero and (max-1).
149
150        Example:
151        @code
152        int var = 11 % 10;      //  1
153        int var = -1 % 10;      // -1
154
155        int var = mod(11, 10);  //  1
156        int var = mod(-1, 10);  //  9
157        @endcode
158    */
159    template <typename T>
160    inline int mod(T x, int max)
161    {
162        if (x >= 0)
163            return (x % max);
164        else
165        {
166            T temp = x % max;
167            return (temp < 0) ? (temp + max) : temp;
168        }
169    }
170
171    /**
172        @brief Returns a "zero" value for the given type.
173        @note This is the default template of the zeroise() function. The template is spezialized for each supported type.
174
175        The exact return value of the function depends on the type. For @c int this is 0,
176        for @c float it's 0.0f. For a @c std::string the function returns "" and for
177        @c Vector3 you get <tt>Vector3(0, 0, 0)</tt>.
178    */
179    template <typename T>
180    inline T zeroise()
181    {
182        // Default, raise a compiler error without including large boost header cascade.
183        T temp();
184        *********temp; // If you reach this code, you abused zeroise()!
185        return temp;
186    }
187
188    template <> inline char                 zeroise<char>()                 { return 0; }
189    template <> inline unsigned char        zeroise<unsigned char>()        { return 0; }
190    template <> inline short                zeroise<short>()                { return 0; }
191    template <> inline unsigned short       zeroise<unsigned short>()       { return 0; }
192    template <> inline int                  zeroise<int>()                  { return 0; }
193    template <> inline unsigned int         zeroise<unsigned int>()         { return 0; }
194    template <> inline long                 zeroise<long>()                 { return 0; }
195    template <> inline unsigned long        zeroise<unsigned long>()        { return 0; }
196    template <> inline long long            zeroise<long long>()            { return 0; }
197    template <> inline unsigned long long   zeroise<unsigned long long>()   { return 0; }
198    template <> inline float                zeroise<float>()                { return 0; }
199    template <> inline double               zeroise<double>()               { return 0; }
200    template <> inline long double          zeroise<long double>()          { return 0; }
201    template <> inline bool                 zeroise<bool>()                 { return 0; }
202    template <> inline void*                zeroise<void*>()                { return 0; }
203    template <> inline std::string          zeroise<std::string>()          { return std::string(); }
204    template <> inline orxonox::Radian      zeroise<orxonox::Radian>()      { return orxonox::Radian(0.0f); }
205    template <> inline orxonox::Degree      zeroise<orxonox::Degree>()      { return orxonox::Degree(0.0f); }
206    template <> inline orxonox::Vector2     zeroise<orxonox::Vector2>()     { return orxonox::Vector2    (0, 0)      ; }
207    template <> inline orxonox::Vector3     zeroise<orxonox::Vector3>()     { return orxonox::Vector3    (0, 0, 0)   ; }
208    template <> inline orxonox::Vector4     zeroise<orxonox::Vector4>()     { return orxonox::Vector4    (0, 0, 0, 0); }
209    template <> inline orxonox::ColourValue zeroise<orxonox::ColourValue>() { return orxonox::ColourValue(0, 0, 0, 0); }
210    template <> inline orxonox::Quaternion  zeroise<orxonox::Quaternion>()  { return orxonox::Quaternion (0, 0, 0, 0); }
211
212    /**
213        @brief Provides zero value symbols that can be returned as reference
214        @see zeroise()
215    */
216    template <typename T>
217    struct NilValue
218    {
219        inline operator const T&() const
220        {
221            return value;
222        }
223        static T value;
224    };
225    template <typename T>
226    T NilValue<T>::value = zeroise<T>();
227
228    /**
229        @brief Interpolates between two values for a time between 0 and 1.
230        @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.
231        @param start The value at @a time = 0
232        @param end The value at @a time = 1
233        @return The interpolated value at a given time
234    */
235    template <typename T>
236    inline T interpolate(float time, const T& start, const T& end)
237    {
238        return static_cast<T>(time * (end - start) + start);
239    }
240
241    /**
242        @brief Interpolates smoothly between two values for a time between 0 and 1. The function starts slowly, increases faster and stops slowly again.
243        @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.
244        @param start The value at @a time = 0
245        @param end The value at @a time = 1
246        @return The interpolated value at a given time
247    */
248    template <typename T>
249    inline T interpolateSmooth(float time, const T& start, const T& end)
250    {
251        return static_cast<T>((-2 * (end - start) * cube(time)) + (3 * (end - start) * square(time)) + start);
252    }
253
254    /**
255        @brief Returns a random number between 0 and almost 1: <tt>0 <= rnd < 1</tt>.
256    */
257    inline float rnd()
258    {
259        return rand() / (RAND_MAX + 1.0f);
260    }
261
262    /**
263        @brief Returns a random number between 0 and almost @a max: <tt>0 <= rnd < max</tt>.
264        @param max The maximum
265    */
266    inline float rnd(float max)
267    {
268        return rnd() * max;
269    }
270
271    /**
272        @brief Returns a random number between @a min and almost @a max: <tt>min <= rnd < max</tt>.
273        @param min The minimum
274        @param max The maximum
275    */
276    inline float rnd(float min, float max)
277    {
278        return rnd(max - min) + min;
279    }
280
281    /**
282        @brief Returns randomly 1 or -1 with equal probability.
283    */
284    inline float rndsgn()
285    {
286        return static_cast<float>((rand() & 0x2) - 1); // rand() & 0x2 is either 2 or 0
287    }
288
289    _UtilExport unsigned long getUniqueNumber();
290}
291
292#endif /* _Util_Math_H__ */
Note: See TracBrowser for help on using the repository browser.