FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
fife_math.h
1 /***************************************************************************
2  * Copyright (C) 2005-2010 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 #ifndef FIFE_UTIL_FIFE_MATH_H
23 #define FIFE_UTIL_FIFE_MATH_H
24 
25 // Standard C++ library includes
26 #include <cassert>
27 #include <cmath>
28 #include <limits>
29 
30 // Platform specific includes
31 
32 // 3rd party library includes
33 
34 // FIFE includes
35 // These includes are split up in two parts, separated by one empty line
36 // First block: files included from the FIFE root src directory
37 // Second block: files included from the same folder
38 
39 #ifndef ABS
40 #define ABS(x) ((x)<0?-(x):(x))
41 
42 #endif
43 
44 // Sort out the missing round function in MSVC:
45 #if defined( WIN32 ) && defined( _MSC_VER )
46 inline double round(const double x) {
47  return x < 0.0 ? ceil(x - 0.5) : floor(x + 0.5);
48 }
49 #endif
50 
51 namespace FIFE {
52 
53  static const float FLT_STD_EPSILON = std::numeric_limits<float>::epsilon();
54  static const float FLT_STD_MAX = std::numeric_limits<float>::max();
55  static const float FLT_ZERO_TOLERANCE = 1e-06f;
56  static const float FLT_PI = 4.0f*std::atan(1.0f);
57  static const float FLT_TWO_PI = 2.0f*FLT_PI;
58  static const float FLT_HALF_PI = 0.5f*FLT_PI;
59  static const float FLT_INVERSE_PI = 1.0f/FLT_PI;
60  static const float FLT_INVERSE_TWO_PI = 1.0f/FLT_TWO_PI;
61  static const float FLT_DEG_TO_RAD = FLT_PI/180.0f;
62  static const float FLT_RAD_TO_DEG = 180.0f/FLT_PI;
63  static const float FLT_LOG_2 = std::log(2.0f);
64  static const float FLT_LOG_10 = std::log(10.0f);
65  static const float FLT_INV_LOG_2 = 1.0f/std::log(2.0f);
66  static const float FLT_INV_LOG_10 = 1.0f/std::log(10.0f);
67 
68  static const double DBL_STD_EPSILON = std::numeric_limits<double>::epsilon();
69  static const double DBL_STD_MAX = std::numeric_limits<double>::max();
70  static const double DBL_ZERO_TOLERANCE = 1e-08;
71  static const double DBL_PI = 4.0*std::atan(1.0);
72  static const double DBL_TWO_PI = 2.0*DBL_PI;
73  static const double DBL_HALF_PI = 0.5*DBL_PI;
74  static const double DBL_INVERSE_PI = 1.0/DBL_PI;
75  static const double DBL_INVERSE_TWO_PI = 1.0/DBL_TWO_PI;
76  static const double DBL_DEG_TO_RAD = DBL_PI/180.0;
77  static const double DBL_RAD_TO_DEG = 180.0f/DBL_PI;
78  static const double DBL_LOG_2 = std::log(2.0);
79  static const double DBL_LOG_10 = std::log(10.0);
80  static const double DBL_INV_LOG_2 = 1.0/std::log(2.0);
81  static const double DBL_INV_LOG_10 = 1.0/std::log(10.0);
82 
83  template <class numT>
84  struct float_traits { };
85 
86  template <>
87  struct float_traits<float> {
88  typedef float float_type;
89  static inline float_type epsilon() { return FLT_STD_EPSILON; }
90  static inline float_type zeroTolerance() { return FLT_ZERO_TOLERANCE; }
91  static inline float_type max() { return FLT_STD_MAX; }
92  static inline float_type pi() { return FLT_PI; }
93  static inline float_type twoPi() { return FLT_TWO_PI; }
94  static inline float_type halfPi() { return FLT_HALF_PI; }
95  static inline float_type inversePi() { return FLT_INVERSE_PI; }
96  static inline float_type inverseTwoPi() { return FLT_INVERSE_TWO_PI; }
97  static inline float_type degToRad() { return FLT_DEG_TO_RAD; }
98  static inline float_type radToDeg() { return FLT_RAD_TO_DEG; }
99  static inline float_type log2() { return FLT_LOG_2; }
100  static inline float_type log10() { return FLT_LOG_10; }
101  static inline float_type invLog2() { return FLT_INV_LOG_2; }
102  static inline float_type invLog10() { return FLT_INV_LOG_10; }
103  };
104 
105  template <>
106  struct float_traits<double> {
107  typedef double float_type;
108  static inline float_type epsilon() { return DBL_STD_EPSILON; }
109  static inline float_type zeroTolerance() { return DBL_ZERO_TOLERANCE; }
110  static inline float_type max() { return DBL_STD_MAX; }
111  static inline float_type pi() { return DBL_PI; }
112  static inline float_type twoPi() { return DBL_TWO_PI; }
113  static inline float_type halfPi() { return DBL_HALF_PI; }
114  static inline float_type inversePi() { return DBL_INVERSE_PI; }
115  static inline float_type inverseTwoPi() { return DBL_INVERSE_TWO_PI; }
116  static inline float_type degToRad() { return DBL_DEG_TO_RAD; }
117  static inline float_type radToDeg() { return DBL_RAD_TO_DEG; }
118  static inline float_type log2() { return DBL_LOG_2; }
119  static inline float_type log10() { return DBL_LOG_10; }
120  static inline float_type invLog2() { return DBL_INV_LOG_2; }
121  static inline float_type invLog10() { return DBL_INV_LOG_10; }
122  };
123 
124  template <typename T>
125  class Math {
126  public:
127  typedef T num_type;
128  typedef float_traits<num_type> traits_type;
129 
130  static inline num_type epsilon() { return traits_type::epsilon(); }
131  static inline num_type zeroTolerance() { return traits_type::zeroTolerance(); }
132  static inline num_type max() { return traits_type::max(); }
133  static inline num_type pi() { return traits_type::pi(); }
134  static inline num_type twoPi() { return traits_type::twoPi(); }
135  static inline num_type halfPi() { return traits_type::halfPi(); }
136  static inline num_type inversePi() { return traits_type::inversePi(); }
137  static inline num_type inverseTwoPi() { return traits_type::inverseTwoPi(); }
138  static inline num_type degToRad() { return traits_type::degToRad(); }
139  static inline num_type radToDeg() { return traits_type::radToDeg(); }
140  static inline num_type log2() { return traits_type::log2(); }
141  static inline num_type log10() { return traits_type::log10(); }
142  static inline num_type invLog2() { return traits_type::invLog2(); }
143  static inline num_type invLog10() { return traits_type::invLog10(); }
144 
145  static T ACos(T _val);
146  static T ASin(T _val);
147  static T ATan(T _val);
148  static T ATan2(T _x, T _y);
149  static T Ceil(T _val);
150  static T Cos(T _val);
151  static T Exp(T _val);
152  static T FAbs(T _val);
153  static T Floor(T _val);
154  static T FMod (T _x, T _y);
155  static T InvSqrt(T _val);
156  static T Log(T _val);
157  static T Log2(T _val);
158  static T Log10(T _val);
159  static T Pow(T _base, T _exponent);
160  static T Sin(T _val);
161  static T Sqr(T _val);
162  static T Sqrt(T _val);
163  static T Tan(T _val);
164  static bool Equal(T _val1, T _val2);
165  };
166 
167  typedef Math<float> Mathf;
168  typedef Math<double> Mathd;
169 
170  template<typename T>
171  inline T Math<T>::ACos(T _val) {
172  if (-static_cast<T>(1) < _val) {
173  if (_val < static_cast<T>(1)) {
174  return static_cast<T>(std::acos(_val));
175  }
176  else {
177  return static_cast<T>(0);
178  }
179  }
180  else {
181  return pi();
182  }
183  }
184 
185  template <class T>
186  inline T Math<T>::ASin(T _val) {
187  if (-static_cast<T>(1) < _val) {
188  if (_val < static_cast<T>(1)) {
189  return static_cast<T>(std::asin(_val));
190  }
191  else {
192  return halfPi();
193  }
194  }
195  else {
196  return -halfPi();
197  }
198  }
199 
200  template <class T>
201  inline T Math<T>::ATan(T _val) {
202  return static_cast<T>(std::atan(_val));
203  }
204 
205  template <class T>
206  inline T Math<T>::ATan2(T _x, T _y) {
207  return static_cast<T>(std::atan2(_x, _y));
208  }
209 
210  template <class T>
211  inline T Math<T>::Ceil(T _val) {
212  return static_cast<T>(std::ceil(_val));
213  }
214 
215  template <class T>
216  inline T Math<T>::Cos(T _val) {
217  return static_cast<T>(std::cos(_val));
218  }
219 
220  template <class T>
221  inline T Math<T>::Exp(T _val){
222  return static_cast<T>(std::exp(_val));
223  }
224 
225  template <class T>
226  inline T Math<T>::FAbs(T _val) {
227  return static_cast<T>(std::fabs(_val));
228  }
229 
230  template <class T>
231  inline T Math<T>::Floor(T _val) {
232  return static_cast<T>(std::floor(_val));
233  }
234 
235  template <class T>
236  inline T Math<T>::FMod(T _x, T _y) {
237  return static_cast<T>(std::fmod(_x, _y));
238  }
239 
240  template <class T>
241  inline T Math<T>::InvSqrt(T _val) {
242  return static_cast<T>(1/std::sqrt(_val));
243  }
244 
245  template <class T>
246  inline T Math<T>::Log(T _val) {
247  return static_cast<T>(std::log(_val));
248  }
249 
250  template <class T>
251  inline T Math<T>::Log2(T _val) {
252  return invLog2() * static_cast<T>(std::log(_val));
253  }
254  template <class T>
255  inline T Math<T>::Log10(T _val) {
256 
257  return invLog10() * static_cast<T>(std::log(_val));
258  }
259 
260  template <class T>
261  inline T Math<T>::Pow(T _base, T _exponent) {
262  return static_cast<T>(std::pow(_base, _exponent));
263  }
264 
265  template <class T>
266  inline T Math<T>::Sin(T _val) {
267  return static_cast<T>(std::sin(_val));
268  }
269 
270  template <class T>
271  inline T Math<T>::Sqr(T _val) {
272  return _val*_val;
273  }
274 
275  template <class T>
276  inline T Math<T>::Sqrt(T _val) {
277  return static_cast<T>(std::sqrt(_val));
278  }
279 
280  template <class T>
281  inline T Math<T>::Tan(T _val) {
282  return static_cast<T>(std::tan(_val));
283  }
284 
285  template <class T>
286  inline bool Math<T>::Equal(T _val1, T _val2) {
287  return std::fabs(_val1 - _val2) < epsilon();
288  }
289 
292  inline unsigned nextPow2(unsigned x)
293  {
294  --x;
295  x |= x >> 1;
296  x |= x >> 2;
297  x |= x >> 4;
298  x |= x >> 8;
299  x |= x >> 16;
300  return ++x;
301  }
302 } //FIFE
303 
304 #endif // FIFE_UTIL_FIFE_MATH_H