FIFE
2008.0
|
00001 /*************************************************************************** 00002 * Copyright (C) 2005-2010 by the FIFE team * 00003 * http://www.fifengine.net * 00004 * This file is part of FIFE. * 00005 * * 00006 * FIFE is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU Lesser General Public * 00008 * License as published by the Free Software Foundation; either * 00009 * version 2.1 of the License, or (at your option) any later version. * 00010 * * 00011 * This library is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00014 * Lesser General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Lesser General Public * 00017 * License along with this library; if not, write to the * 00018 * Free Software Foundation, Inc., * 00019 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 00020 ***************************************************************************/ 00021 00022 #ifndef FIFE_UTIL_FIFE_MATH_H 00023 #define FIFE_UTIL_FIFE_MATH_H 00024 00025 // Standard C++ library includes 00026 #include <cassert> 00027 #include <cmath> 00028 #include <limits> 00029 00030 // Platform specific includes 00031 00032 // 3rd party library includes 00033 00034 // FIFE includes 00035 // These includes are split up in two parts, separated by one empty line 00036 // First block: files included from the FIFE root src directory 00037 // Second block: files included from the same folder 00038 00039 #ifndef ABS 00040 #define ABS(x) ((x)<0?-(x):(x)) 00041 00042 #endif 00043 00044 // Sort out the missing round function in MSVC: 00045 #if defined( WIN32 ) && defined( _MSC_VER ) 00046 inline double round(const double x) { 00047 return x < 0.0 ? ceil(x - 0.5) : floor(x + 0.5); 00048 } 00049 #endif 00050 00051 namespace FIFE { 00052 00053 static const float FLT_STD_EPSILON = std::numeric_limits<float>::epsilon(); 00054 static const float FLT_STD_MAX = std::numeric_limits<float>::max(); 00055 static const float FLT_ZERO_TOLERANCE = 1e-06f; 00056 static const float FLT_PI = 4.0f*std::atan(1.0f); 00057 static const float FLT_TWO_PI = 2.0f*FLT_PI; 00058 static const float FLT_HALF_PI = 0.5f*FLT_PI; 00059 static const float FLT_INVERSE_PI = 1.0f/FLT_PI; 00060 static const float FLT_INVERSE_TWO_PI = 1.0f/FLT_TWO_PI; 00061 static const float FLT_DEG_TO_RAD = FLT_PI/180.0f; 00062 static const float FLT_RAD_TO_DEG = 180.0f/FLT_PI; 00063 static const float FLT_LOG_2 = std::log(2.0f); 00064 static const float FLT_LOG_10 = std::log(10.0f); 00065 static const float FLT_INV_LOG_2 = 1.0f/std::log(2.0f); 00066 static const float FLT_INV_LOG_10 = 1.0f/std::log(10.0f); 00067 00068 static const double DBL_STD_EPSILON = std::numeric_limits<double>::epsilon(); 00069 static const double DBL_STD_MAX = std::numeric_limits<double>::max(); 00070 static const double DBL_ZERO_TOLERANCE = 1e-08; 00071 static const double DBL_PI = 4.0*std::atan(1.0); 00072 static const double DBL_TWO_PI = 2.0*DBL_PI; 00073 static const double DBL_HALF_PI = 0.5*DBL_PI; 00074 static const double DBL_INVERSE_PI = 1.0/DBL_PI; 00075 static const double DBL_INVERSE_TWO_PI = 1.0/DBL_TWO_PI; 00076 static const double DBL_DEG_TO_RAD = DBL_PI/180.0; 00077 static const double DBL_RAD_TO_DEG = 180.0f/DBL_PI; 00078 static const double DBL_LOG_2 = std::log(2.0); 00079 static const double DBL_LOG_10 = std::log(10.0); 00080 static const double DBL_INV_LOG_2 = 1.0/std::log(2.0); 00081 static const double DBL_INV_LOG_10 = 1.0/std::log(10.0); 00082 00083 template <class numT> 00084 struct float_traits { }; 00085 00086 template <> 00087 struct float_traits<float> { 00088 typedef float float_type; 00089 static inline float_type epsilon() { return FLT_STD_EPSILON; } 00090 static inline float_type zeroTolerance() { return FLT_ZERO_TOLERANCE; } 00091 static inline float_type max() { return FLT_STD_MAX; } 00092 static inline float_type pi() { return FLT_PI; } 00093 static inline float_type twoPi() { return FLT_TWO_PI; } 00094 static inline float_type halfPi() { return FLT_HALF_PI; } 00095 static inline float_type inversePi() { return FLT_INVERSE_PI; } 00096 static inline float_type inverseTwoPi() { return FLT_INVERSE_TWO_PI; } 00097 static inline float_type degToRad() { return FLT_DEG_TO_RAD; } 00098 static inline float_type radToDeg() { return FLT_RAD_TO_DEG; } 00099 static inline float_type log2() { return FLT_LOG_2; } 00100 static inline float_type log10() { return FLT_LOG_10; } 00101 static inline float_type invLog2() { return FLT_INV_LOG_2; } 00102 static inline float_type invLog10() { return FLT_INV_LOG_10; } 00103 }; 00104 00105 template <> 00106 struct float_traits<double> { 00107 typedef double float_type; 00108 static inline float_type epsilon() { return DBL_STD_EPSILON; } 00109 static inline float_type zeroTolerance() { return DBL_ZERO_TOLERANCE; } 00110 static inline float_type max() { return DBL_STD_MAX; } 00111 static inline float_type pi() { return DBL_PI; } 00112 static inline float_type twoPi() { return DBL_TWO_PI; } 00113 static inline float_type halfPi() { return DBL_HALF_PI; } 00114 static inline float_type inversePi() { return DBL_INVERSE_PI; } 00115 static inline float_type inverseTwoPi() { return DBL_INVERSE_TWO_PI; } 00116 static inline float_type degToRad() { return DBL_DEG_TO_RAD; } 00117 static inline float_type radToDeg() { return DBL_RAD_TO_DEG; } 00118 static inline float_type log2() { return DBL_LOG_2; } 00119 static inline float_type log10() { return DBL_LOG_10; } 00120 static inline float_type invLog2() { return DBL_INV_LOG_2; } 00121 static inline float_type invLog10() { return DBL_INV_LOG_10; } 00122 }; 00123 00124 template <typename T> 00125 class Math { 00126 public: 00127 typedef T num_type; 00128 typedef float_traits<num_type> traits_type; 00129 00130 static inline num_type epsilon() { return traits_type::epsilon(); } 00131 static inline num_type zeroTolerance() { return traits_type::zeroTolerance(); } 00132 static inline num_type max() { return traits_type::max(); } 00133 static inline num_type pi() { return traits_type::pi(); } 00134 static inline num_type twoPi() { return traits_type::twoPi(); } 00135 static inline num_type halfPi() { return traits_type::halfPi(); } 00136 static inline num_type inversePi() { return traits_type::inversePi(); } 00137 static inline num_type inverseTwoPi() { return traits_type::inverseTwoPi(); } 00138 static inline num_type degToRad() { return traits_type::degToRad(); } 00139 static inline num_type radToDeg() { return traits_type::radToDeg(); } 00140 static inline num_type log2() { return traits_type::log2(); } 00141 static inline num_type log10() { return traits_type::log10(); } 00142 static inline num_type invLog2() { return traits_type::invLog2(); } 00143 static inline num_type invLog10() { return traits_type::invLog10(); } 00144 00145 static T ACos(T _val); 00146 static T ASin(T _val); 00147 static T ATan(T _val); 00148 static T ATan2(T _x, T _y); 00149 static T Ceil(T _val); 00150 static T Cos(T _val); 00151 static T Exp(T _val); 00152 static T FAbs(T _val); 00153 static T Floor(T _val); 00154 static T FMod (T _x, T _y); 00155 static T InvSqrt(T _val); 00156 static T Log(T _val); 00157 static T Log2(T _val); 00158 static T Log10(T _val); 00159 static T Pow(T _base, T _exponent); 00160 static T Sin(T _val); 00161 static T Sqr(T _val); 00162 static T Sqrt(T _val); 00163 static T Tan(T _val); 00164 }; 00165 00166 typedef Math<float> Mathf; 00167 typedef Math<double> Mathd; 00168 00169 template<typename T> 00170 inline T Math<T>::ACos(T _val) { 00171 if (-static_cast<T>(1) < _val) { 00172 if (_val < static_cast<T>(1)) { 00173 return static_cast<T>(std::acos(_val)); 00174 } 00175 else { 00176 return static_cast<T>(0); 00177 } 00178 } 00179 else { 00180 return pi(); 00181 } 00182 } 00183 00184 template <class T> 00185 inline T Math<T>::ASin(T _val) { 00186 if (-static_cast<T>(1) < _val) { 00187 if (_val < static_cast<T>(1)) { 00188 return static_cast<T>(std::asin(_val)); 00189 } 00190 else { 00191 return halfPi(); 00192 } 00193 } 00194 else { 00195 return -halfPi(); 00196 } 00197 } 00198 00199 template <class T> 00200 inline T Math<T>::ATan(T _val) { 00201 return static_cast<T>(std::atan(_val)); 00202 } 00203 00204 template <class T> 00205 inline T Math<T>::ATan2(T _x, T _y) { 00206 return static_cast<T>(std::atan2(_x, _y)); 00207 } 00208 00209 template <class T> 00210 inline T Math<T>::Ceil(T _val) { 00211 return static_cast<T>(std::ceil(_val)); 00212 } 00213 00214 template <class T> 00215 inline T Math<T>::Cos(T _val) { 00216 return static_cast<T>(std::cos(_val)); 00217 } 00218 00219 template <class T> 00220 inline T Math<T>::Exp(T _val){ 00221 return static_cast<T>(std::exp(_val)); 00222 } 00223 00224 template <class T> 00225 inline T Math<T>::FAbs(T _val) { 00226 return static_cast<T>(std::fabs(_val)); 00227 } 00228 00229 template <class T> 00230 inline T Math<T>::Floor(T _val) { 00231 return static_cast<T>(std::floor(_val)); 00232 } 00233 00234 template <class T> 00235 inline T Math<T>::FMod(T _x, T _y) { 00236 return static_cast<T>(std::fmod(_x, _y)); 00237 } 00238 00239 template <class T> 00240 inline T Math<T>::InvSqrt(T _val) { 00241 return static_cast<T>(1/std::sqrt(_val)); 00242 } 00243 00244 template <class T> 00245 inline T Math<T>::Log(T _val) { 00246 return static_cast<T>(std::log(_val)); 00247 } 00248 00249 template <class T> 00250 inline T Math<T>::Log2(T _val) { 00251 return invLog2() * static_cast<T>(std::log(_val)); 00252 } 00253 template <class T> 00254 inline T Math<T>::Log10(T _val) { 00255 00256 return invLog10() * static_cast<T>(std::log(_val)); 00257 } 00258 00259 template <class T> 00260 inline T Math<T>::Pow(T _base, T _exponent) { 00261 return static_cast<T>(std::pow(_base, _exponent)); 00262 } 00263 00264 template <class T> 00265 inline T Math<T>::Sin(T _val) { 00266 return static_cast<T>(std::sin(_val)); 00267 } 00268 00269 template <class T> 00270 inline T Math<T>::Sqr(T _val) { 00271 return _val*_val; 00272 } 00273 00274 template <class T> 00275 inline T Math<T>::Sqrt(T _val) { 00276 return static_cast<T>(std::sqrt(_val)); 00277 } 00278 00279 template <class T> 00280 inline T Math<T>::Tan(T _val) { 00281 return static_cast<T>(std::tan(_val)); 00282 } 00283 00286 inline unsigned nextPow2(unsigned x) 00287 { 00288 --x; 00289 x |= x >> 1; 00290 x |= x >> 2; 00291 x |= x >> 4; 00292 x |= x >> 8; 00293 x |= x >> 16; 00294 return ++x; 00295 } 00296 } //FIFE 00297 00298 #endif // FIFE_UTIL_FIFE_MATH_H