fife_math.h
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 };
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 }
00297
00298 #endif // FIFE_UTIL_FIFE_MATH_H