00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __SP_MATH_CORE_H__
00009 #define __SP_MATH_CORE_H__
00010
00011
00012 #include "Base/spStandard.hpp"
00013
00014 #include <cmath>
00015
00016
00017 namespace sp
00018 {
00019 namespace math
00020 {
00021
00022
00023
00024
00025
00026
00027 static const f64 ROUNDING_ERROR64 = 0.00000001;
00028 static const f32 ROUNDING_ERROR = 0.000001f;
00029
00030 static const f32 OMEGA = 999999.f;
00031
00032 static const f64 PI64 = 3.1415926535897932384626433832795028841971693993751;
00033 static const f32 PI = 3.14159265359f;
00034
00035 const f32 DEG = PI / 180.0f;
00036 const f32 RAD = 180.0f / PI;
00037 const f64 DEG64 = PI64 / 180.0;
00038 const f64 RAD64 = 180.0 / PI64;
00039
00040 const f64 SQRT2 = sqrt(2.0);
00041 const f32 SQRT2F = sqrtf(2.0f);
00042
00043 const f64 STDASPECT = 4.0 / 3.0;
00044
00045
00047 template <typename T> inline T Abs(const T &Value)
00048 {
00049 return Value < 0 ? -Value : Value;
00050 }
00051
00053 template <typename T> inline T Max(const T &A, const T &B)
00054 {
00055 return A > B ? A : B;
00056 }
00058 template <typename T> inline T Min(const T &A, const T &B)
00059 {
00060 return A < B ? A : B;
00061 }
00062
00064 template <typename T> inline T Max(const T &A, const T &B, const T &C)
00065 {
00066 return ( A >= B && A >= C ? A : ( B >= A && B >= C ? B : C ) );
00067 }
00069 template <typename T> inline T Min(const T &A, const T &B, const T &C)
00070 {
00071 return ( A <= B && A <= C ? A : ( B <= A && B <= C ? B : C ) );
00072 }
00073
00075 template <typename T> inline void Increase(T &Value, const T &PotNewValue)
00076 {
00077 if (PotNewValue > Value)
00078 Value = PotNewValue;
00079 }
00081 template <typename T> inline void Decrease(T &Value, const T &PotNewValue)
00082 {
00083 if (PotNewValue < Value)
00084 Value = PotNewValue;
00085 }
00086
00088 template <typename T> inline T MinMax(const T &Value, const T &Min, const T &Max)
00089 {
00090 if (Value > Max)
00091 return Max;
00092 else if (Value < Min)
00093 return Min;
00094 return Value;
00095 }
00097 template <typename T> inline void Clamp(T &Value, const T &Min, const T &Max)
00098 {
00099 if (Value > Max)
00100 Value = Max;
00101 else if (Value < Min)
00102 Value = Min;
00103 }
00104
00106 template <typename T> inline void Swap(T &A, T &B)
00107 {
00108 const T Temp(A);
00109 A = B;
00110 B = Temp;
00111 }
00112
00114 template <typename T> inline T Sgn(const T &Value)
00115 {
00116 return (Value > 0) ? T(1) : (Value < 0) ? T(-1) : T(0);
00117 }
00118
00120 template <typename T> inline T Round(const T &Value, s32 Precision)
00121 {
00122 s32 exp = static_cast<s32>(pow(10, Precision));
00123 return static_cast<T>(static_cast<s32>(Value*exp)) / exp;
00124 }
00125
00127 template <typename T> inline T Pow2(const T &Value)
00128 {
00129 return Value*Value;
00130 }
00131
00133 template <typename T> inline T Sin(const T &Value)
00134 {
00135 return static_cast<T>(sin(DEG64*Value));
00136 }
00138 template <typename T> inline T Cos(const T &Value)
00139 {
00140 return static_cast<T>(cos(DEG64*Value));
00141 }
00143 template <typename T> inline T Tan(const T &Value)
00144 {
00145 return static_cast<T>(tan(DEG64*Value));
00146 }
00147
00149 template <typename T> inline T ASin(const T &Value)
00150 {
00151 return static_cast<T>(asin(Value)*RAD64);
00152 }
00154 template <typename T> inline T ACos(const T &Value)
00155 {
00156 return static_cast<T>(acos(Value)*RAD64);
00157 }
00159 template <typename T> inline T ATan(const T &Value)
00160 {
00161 return static_cast<T>(atan(Value)*RAD64);
00162 }
00163
00165 template <typename T> inline T Log(const T &Value, const T &Base = T(10))
00166 {
00167 return log(Value) / log(Base);
00168 }
00169
00181 template <typename T, typename I> inline void Lerp(T &Result, const T &From, const T &To, const I &Factor)
00182 {
00183 Result = To;
00184 Result -= From;
00185 Result *= Factor;
00186 Result += From;
00187 }
00188
00190 template <typename T, typename I> inline T Lerp(const T &From, const T &To, const I &Factor)
00191 {
00192 T Result;
00193 Lerp<T, I>(Result, From, To, Factor);
00194 return Result;
00195 }
00196
00198 template <typename T, typename I> inline T LerpParabolic(const T &From, const T &To, const I &Factor)
00199 {
00200 return Lerp(From, To, Factor*Factor);
00201 }
00202
00204 template <typename T, typename I> inline T LerpSin(const T &From, const T &To, const I &Factor)
00205 {
00206 return Lerp(From, To, Sin(Factor*I(90)));
00207 }
00208
00210 inline s32 Round(f32 Value)
00211 {
00212 return static_cast<s32>(Value + 0.5f);
00213 }
00214
00216 inline s32 RoundPow2(s32 Value)
00217 {
00218 s32 i;
00219
00220 for (i = 1; i < Value; i <<= 1);
00221
00222 if (i - Value <= Value - i/2)
00223 return i;
00224
00225 return i/2;
00226 }
00227
00229 inline bool Equal(f32 A, f32 B, f32 Tolerance = ROUNDING_ERROR)
00230 {
00231 return (A + Tolerance >= B) && (A - Tolerance <= B);
00232 }
00237 inline bool Equal(s32 A, s32 B, s32 Tolerance = 0)
00238 {
00239 return A == B;
00240 }
00241
00243 inline bool getBitR2L(u32 Integer, s32 Pos)
00244 {
00245 return ((Integer >> Pos) & 0x00000001) != 0;
00246 }
00248 inline void setBitR2L(u32 &Integer, s32 Pos, bool Enable)
00249 {
00250 if (Enable)
00251 Integer |= (0x00000001 << Pos);
00252 else
00253 Integer &= ((0xFFFFFFFE << Pos) + (0x7FFFFFFF << (Pos - 31)));
00254 }
00255
00257 inline bool getBitL2R(u32 Integer, s32 Pos)
00258 {
00259 return ((Integer << Pos) & 0x80000000) != 0;
00260 }
00262 inline void setBitL2R(u32 &Integer, s32 Pos, bool Enable)
00263 {
00264 if (Enable)
00265 Integer |= (0x80000000 >> Pos);
00266 else
00267 Integer &= ((0x7FFFFFFF >> Pos) + (0xFFFFFFFE >> (Pos - 31)));
00268 }
00269
00271 inline bool getBitR2L(u8 Integer, s32 Pos)
00272 {
00273 return ((Integer >> Pos) & 0x01) != 0;
00274 }
00276 inline void setBitR2L(u8 &Integer, s32 Pos, bool Enable)
00277 {
00278 if (Enable)
00279 Integer |= (0x01 << Pos);
00280 else
00281 Integer &= ((0xFE << Pos) + (0x7F << (Pos - 31)));
00282 }
00283
00285 inline bool getBitL2R(u8 Integer, s32 Pos)
00286 {
00287 return ((Integer << Pos) & 0x80) != 0;
00288 }
00290 inline void setBitL2R(u8 &Integer, s32 Pos, bool Enable)
00291 {
00292 if (Enable)
00293 Integer |= (0x80 >> Pos);
00294 else
00295 Integer &= ((0x7F >> Pos) + (0xFE >> (Pos - 31)));
00296 }
00297
00302 template <typename T> inline T getTriangleArea2D(
00303 const T &x1, const T &y1, const T &x2, const T &y2, const T &x3, const T &y3)
00304 {
00305 return (x1 - x2)*(y2 - y3) - (x2 - x3)*(y1 - y2);
00306 }
00307
00309 template <typename T> T getBezierValue(const f32 t, const T &Pos1, const T &Pos2, const T &Radial1, const T &Radial2)
00310 {
00311 const f32 invt = 1.0f - t;
00312 const f32 invt2 = invt*invt;
00313 const f32 invt3 = invt2*invt;
00314 const f32 t2 = t*t;
00315 const f32 t3 = t*t*t;
00316
00317 return Pos1*invt3 + Radial1*3*t*invt2 + Radial2*3*t2*invt + Pos2*t3;
00318 }
00319
00321 template <typename T> T getBernsteinValue(const f32 t, const T Points[4])
00322 {
00323 const f32 invt = 1.0f - t;
00324
00325 return
00326 Points[0] * pow(t, 3) +
00327 Points[1] * (T(3) * pow(t, 2) * invt) +
00328 Points[2] * (T(3) * pow(invt, 2) * t) +
00329 Points[3] * pow(invt, 3);
00330 }
00331
00333 template <typename T> T getGaussianValue(const T &X, const T &Mean, const T &StdDeviation)
00334 {
00335 return (
00336 ( T(1) / sqrt( T(2) * static_cast<T>(math::PI) * StdDeviation * StdDeviation ) )
00337 * exp( ( -( ( X - Mean ) * ( X - Mean ) ) ) / ( T(2) * StdDeviation * StdDeviation ) )
00338 );
00339 }
00340
00348 template <typename T> T getHaltonSequence(s32 Index, s32 Base)
00349 {
00350 T Result = T(0);
00351
00352 T f = T(1) / Base;
00353
00354 while (Index > 0)
00355 {
00356 Result += f * (Index % Base);
00357 Index /= Base;
00358 f /= Base;
00359 }
00360
00361 return Result;
00362 }
00363
00372 template <typename T> T ModularPow(T Base, T Exp, const T &Modulus)
00373 {
00374 T Result = T(1);
00375
00376 while (Exp > T(0))
00377 {
00378 if (Exp % 2 == 1)
00379 {
00380 Result *= Base;
00381 Result %= Modulus;
00382 }
00383 Exp >>= 1;
00384 Base *= Base;
00385 Base %= Modulus;
00386 }
00387
00388 return Result;
00389 }
00390
00391
00392 }
00393
00394 }
00395
00396
00397 #endif
00398
00399
00400
00401