00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef FIFE_UTIL_FIFE_MATH_H
00023 #define FIFE_UTIL_FIFE_MATH_H
00024
00025
00026 #include <cassert>
00027 #include <cmath>
00028 #include <limits>
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef ABS
00040 #define ABS(x) ((x)<0?-(x):(x))
00041
00042 #endif
00043
00044
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 static bool Equal(T _val1, T _val2);
00165 };
00166
00167 typedef Math<float> Mathf;
00168 typedef Math<double> Mathd;
00169
00170 template<typename T>
00171 inline T Math<T>::ACos(T _val) {
00172 if (-static_cast<T>(1) < _val) {
00173 if (_val < static_cast<T>(1)) {
00174 return static_cast<T>(std::acos(_val));
00175 }
00176 else {
00177 return static_cast<T>(0);
00178 }
00179 }
00180 else {
00181 return pi();
00182 }
00183 }
00184
00185 template <class T>
00186 inline T Math<T>::ASin(T _val) {
00187 if (-static_cast<T>(1) < _val) {
00188 if (_val < static_cast<T>(1)) {
00189 return static_cast<T>(std::asin(_val));
00190 }
00191 else {
00192 return halfPi();
00193 }
00194 }
00195 else {
00196 return -halfPi();
00197 }
00198 }
00199
00200 template <class T>
00201 inline T Math<T>::ATan(T _val) {
00202 return static_cast<T>(std::atan(_val));
00203 }
00204
00205 template <class T>
00206 inline T Math<T>::ATan2(T _x, T _y) {
00207 return static_cast<T>(std::atan2(_x, _y));
00208 }
00209
00210 template <class T>
00211 inline T Math<T>::Ceil(T _val) {
00212 return static_cast<T>(std::ceil(_val));
00213 }
00214
00215 template <class T>
00216 inline T Math<T>::Cos(T _val) {
00217 return static_cast<T>(std::cos(_val));
00218 }
00219
00220 template <class T>
00221 inline T Math<T>::Exp(T _val){
00222 return static_cast<T>(std::exp(_val));
00223 }
00224
00225 template <class T>
00226 inline T Math<T>::FAbs(T _val) {
00227 return static_cast<T>(std::fabs(_val));
00228 }
00229
00230 template <class T>
00231 inline T Math<T>::Floor(T _val) {
00232 return static_cast<T>(std::floor(_val));
00233 }
00234
00235 template <class T>
00236 inline T Math<T>::FMod(T _x, T _y) {
00237 return static_cast<T>(std::fmod(_x, _y));
00238 }
00239
00240 template <class T>
00241 inline T Math<T>::InvSqrt(T _val) {
00242 return static_cast<T>(1/std::sqrt(_val));
00243 }
00244
00245 template <class T>
00246 inline T Math<T>::Log(T _val) {
00247 return static_cast<T>(std::log(_val));
00248 }
00249
00250 template <class T>
00251 inline T Math<T>::Log2(T _val) {
00252 return invLog2() * static_cast<T>(std::log(_val));
00253 }
00254 template <class T>
00255 inline T Math<T>::Log10(T _val) {
00256
00257 return invLog10() * static_cast<T>(std::log(_val));
00258 }
00259
00260 template <class T>
00261 inline T Math<T>::Pow(T _base, T _exponent) {
00262 return static_cast<T>(std::pow(_base, _exponent));
00263 }
00264
00265 template <class T>
00266 inline T Math<T>::Sin(T _val) {
00267 return static_cast<T>(std::sin(_val));
00268 }
00269
00270 template <class T>
00271 inline T Math<T>::Sqr(T _val) {
00272 return _val*_val;
00273 }
00274
00275 template <class T>
00276 inline T Math<T>::Sqrt(T _val) {
00277 return static_cast<T>(std::sqrt(_val));
00278 }
00279
00280 template <class T>
00281 inline T Math<T>::Tan(T _val) {
00282 return static_cast<T>(std::tan(_val));
00283 }
00284
00285 template <class T>
00286 inline bool Math<T>::Equal(T _val1, T _val2) {
00287 return std::fabs(_val1 - _val2) < epsilon();
00288 }
00289
00292 inline unsigned nextPow2(unsigned x)
00293 {
00294 --x;
00295 x |= x >> 1;
00296 x |= x >> 2;
00297 x |= x >> 4;
00298 x |= x >> 8;
00299 x |= x >> 16;
00300 return ++x;
00301 }
00302 }
00303
00304 #endif // FIFE_UTIL_FIFE_MATH_H