www.pudn.com > ZFXMath-latest.zip > BasicMath.h
/// \file /// /// \if DE /// @brief Basis-Mathefunktionen und Konstanten. /// \else /// @brief Basic math functions and constants. /// \endif #ifndef _ZFXMATH_INCLUDE_BASICMATH_H_ #define _ZFXMATH_INCLUDE_BASICMATH_H_ #include/// \if DE /// @brief Hauptnamespace /// \else /// @brief main namespace /// \endif namespace ZFXMath { #undef DELTA #undef E #undef LOG2_E #undef LOG10_E #undef LOGE_2 #undef LOGE_10 #undef PI #undef SQRT_2 /// \if DE /// @brief Genauigkeit /// \else /// @brief accuracy /// \endif const double EPSILON = 0.00001; /// \if DE /// @brief Eulersche Zahl E /// \else /// @brief mathematical constant e /// \endif const double E = 2.71828182845904523536; /// \if DE /// @brief Logarithmus von E zur Basis 2 /// \else /// @brief logarithm of e to the base 2 /// \endif const double LOG2_E = 1.44269504088896340736; /// \if DE /// @brief Logarithmus von E zur Basis 10 /// \else /// @brief logarithm of e to the base 10 /// \endif const double LOG10_E = 0.434294481903251827651; /// \if DE /// @brief Logarithmus von 2 zur Basis E /// \else /// @brief logarithm of 2 to the base e /// \endif const double LOGE_2 = 0.693147180559945309417; /// \if DE /// @brief Logarithmus von 10 zur Basis E /// \else /// @brief logarithm of 10 to the base e /// \endif const double LOGE_10 = 2.30258509299404568402; /// \if DE /// @brief Kreiszahl pi /// \else /// @brief mathematical constant pi /// \endif const double PI = 3.14159265358979323846; /// \if DE /// @brief Wurzel aus 2 /// \else /// @brief quareroot of 2 /// \endif const double SQRT_2 = 1.41421356237309504880; /// \if DE /// @brief Konvertierung von Radian in Grad /// \else /// @brief conversion from radian to degree /// \endif template inline T RadToDeg(T& rad) { // rad * 180° / pi return rad * 57.295779513082320876798154814105; } /// \if DE /// @brief Konvertierung von Grad in Radian /// \else /// @brief conversion from degree to radian /// \endif template inline T DegToRad(T& degree) { // degree * pi / 180° return degree * 0.017453292519943295769236907684886; } /// \if DE /// @brief Sinus /// \else /// @brief sine /// \endif template inline T Sin(const T& rad) { return ::sin(rad); } /// \if DE /// @brief Kosinus /// \else /// @brief cosine /// \endif template inline T Cos(const T& rad) { return ::cos(rad); } /// \if DE /// @brief Sinus und Kosinus /// \else /// @brief sine and cosine /// \endif template inline void SinCos( const T& rad, T& retSin, T& retCos ) { retSin = Sin( rad ); retCos = Cos( rad ); } /// \if DE /// @brief Tangens /// \else /// @brief tangent /// \endif template inline T Tan(const T& rad) { return ::tan(rad); } /// \if DE /// @brief Arcus Sinus /// \else /// @brief arcsine /// \endif template inline T ASin(const T& value) { return ::asin(value); } /// \if DE /// @brief Arcus Kosinus /// \else /// @brief arcsine /// \endif template inline T ACos(const T& value) { return ::acos(value); } /// \if DE /// @brief Arcus Tangens /// \else /// @brief arctangent /// \endif template inline T ATan(const T& value) { return ::atan(value); } /// \if DE /// @brief Quadratwurzel /// \else /// @brief squareroot /// \endif template inline T Sqrt(const T& value) { return ::sqrt(value); } /// \if DE /// @brief Quadrat /// \else /// @brief square /// \endif template inline T Pow2(const T& base) { return base*base; } /// \if DE /// @brief Potenz /// \else /// @brief exponentiation /// \endif template inline T Pow(const T& base, const T& exp) { return ::pow(base,exp); } /// \if DE /// @brief Berechnet value1 % value2 /// \else /// @brief calculates value1 % value2 /// \endif template inline T Mod(const T& value1, const T& value2) { return ::fmod(value1,value2); //return ( value1 - RoundDown(value1 / value2) * value2 ); } /// \if DE /// @brief Berechnet |value| /// \else /// @brief calculates |value| /// \endif template inline T Abs(const T& value) { return ((value < 0) ? -value : value); } /// \if DE /// @brief Logarithmus von 'num' zur Basis E /// \else /// @brief logarithm of 'num' to the base e /// \endif template inline T LogE(T& num) { return ::log(num); } /// \if DE /// @brief Logarithmus von 'num' zur Basis 10 /// \else /// @brief logarithm of 'num' to the base 10 /// \endif template inline T Log10(T& num) { return ::log10(num); } /// \if DE /// @brief Logarithmus von 'num' zur Basis 'base' /// \else /// @brief logarithm of 'num' to the base 'base' /// \endif template inline T Log(T& base, T& num) { return ( ::log(num) / ::log(base) ); } /// \if DE /// @brief Runden /// \else /// @brief round to nearest integer /// \endif template inline int Round(T& value) { return (int)(d<0 ? d-0.5 : d+0.5); } /// \if DE /// @brief Runden auf bestimmte Stellen /// Wenn 'digit' negativ, wird auf 'digit' Stellen nach dem Komma gerundet. /// Wenn 'digit' positiv, wird auf 'digit' Stellen vor dem Komma gerundet. /// 'digit' darf maximal den Wert 20 und minimal den Wert -20 haben. /// \else /// @brief round to an number of digits /// /// \endif template inline T Round(T& value, int digits) { assert(digits >= -20 && digits <= 20); T v[] = { -1e20, -1e19, -1e18, -1e17, -1e16, -1e15, -1e14, -1e13, -1e12, -1e11, -1e10, -1e9, -1e8, -1e7, -1e6, -1e5, -1e4, -1e3, -1e2, -10, 1, 10, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20 }; return RoundDown(value / v[digits+20] + 0.5) * v[digits+20]; } /// \if DE /// @brief Aufrunden /// \else /// @brief round up /// \endif template inline int RoundUp(T& value) { //if(value - RoundDown(value) == 0) // return (int)value; //else return (int)(value+1); return (int)::ceil(value); } /// \if DE /// @brief Abrunden /// \else /// @brief round down /// \endif template inline T RoundDown(T& value) { return (int)value; } /// \if DE /// @brief Testet ob die Zahl gerade oder Ungerade ist /// \else /// @brief test if number is even or not /// \endif template inline const bool IsEven(const T& value) { return (!(value&1)); } /// \if DE /// @brief kleinere Zahl von und /// \else /// @brief less number of and /// \endif template inline const T& Min(const T& value1, const T& value2) { return ( (value1 < value2) ? value1 : value2 ); } /// \if DE /// @brief größere Zahl von und /// \else /// @brief bigger number of and /// \endif template inline const T& Max(const T& value1, const T& value2) { return ( (value1 > value2) ? value1 : value2 ); } /// \if DE /// @brief auf und begrenzen /// \else /// @brief clamp to and /// \endif template inline const T& Clamp(const T& value, const T& min, const T& max) { return ( (value < min) ? min : ( (value > max) ? max : value) ); } /// \if DE /// @brief Wert ist nahe einem Anderen /// \else /// @brief value is near to another /// \endif template inline bool NearTo( const T& value, const T& nearto ) { return Abs( nearto - value ) <= EPSILON; } /// \if DE /// @brief Wenn t<0, dann -1, wenn t>0, dann 1, ansonsten 0 /// \else /// @brief if t<0, than -1, if t>0, than 1, else 0 /// \endif template inline T Sign(const T& value) { return (T)((t < 0) ? (-1) : (t > 0 ? 1 : 0)); } /// \if DE /// @brief interpoliert linear zwischen zwei werten /// \else /// @brief interpolates linearly between two values /// \endif template inline T1 Interpolate( const T1& v1, const T1& v2, const T2& lerp ) { return v1 + ( v2 - v1 ) * lerp; } /// \if DE /// @brief berechnet Fakultät /// \else /// @brief computes factorial /// \endif template T Fac( T value ) { assert( value >= 0 ); T res = 1; while( value > 1 ) { res *= value; value--; } return res; } /// \if DE /// @brief berechnet Nachkommastellen /// \else /// @brief computes fraction /// \endif template T Frac( T value ) { return value - RoundDown( value ); } /// \if DE /// @brief 1D-Perlin Noise Funktion /// \else /// @brief 1D-Perlin Noise function /// \endif double Noise( unsigned int x ) { x = ( x << 13 ) ^ x; return ( 1.0 - ( ( x * ( x * x * 15731 + 789221 ) + 1376312589) & 0x7FFFFFFF ) / 1073741824.0 ); } /// \if DE /// @brief 2D-Perlin Noise Funktion /// \else /// @brief 2D-Perlin Noise function /// \endif double Noise( unsigned int x, unsigned int y ) { unsigned int n = x + y * 57; n = ( n << 13 ) ^ n; unsigned int result = ( ( n * ( n * n * 15731 + 789221 ) + 1376312589 ) & 0x7FFFFFFF); return ( 1.0 - double(result) / 1073741824.0 ); } /// \if DE /// @brief Weiches 1D-Noise (Gausssche Verteilung) /// \else /// @brief Smooth 1D-Noise (Gaussian Distribution) /// \endif double SmoothNoise( unsigned int x ) { double sides = ( Noise( x - 1 ) + Noise( x + 1 ) ) / 4.0; double center = Noise( x ) / 2.0; return sides + center; } /// \if DE /// @brief Weiches 2D-Noise (Gausssche Verteilung) /// \else /// @brief Smooth 2D-Noise (Gaussian Distribution) /// \endif double SmoothNoise( unsigned int x, unsigned int y ) { double corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16.0; double sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8.0; double center = Noise(x, y) / 4.0; return corners + sides + center; } /// \if DE /// @brief 2D-Noise basierend auf Fließkommazahlparameter /// \else /// @brief 2D-Noise based on floatingpoint parameters /// \endif double InterpolatedNoise( double x, double y ) { int integer_X = int(x); double fractional_X = x - integer_X; int integer_Y = int(y); double fractional_Y = y - integer_Y; double v1 = Noise( integer_X, integer_Y ); double v2 = Noise( integer_X + 1, integer_Y); double v3 = Noise( integer_X, integer_Y + 1 ); double v4 = Noise( integer_X + 1, integer_Y + 1 ); double i1 = Interpolate( v1, v2, fractional_X ); double i2 = Interpolate( v3, v4, fractional_X ); return Interpolate( i1, i2, fractional_Y ); } /// \if DE /// @brief Weiches 2D-Noise basierend auf Fließkommazahlparameter /// \else /// @brief Smooth 2D-Noise based on floatingpoint parameters /// \endif double SmoothInterpolatedNoise( double x, double y ) { int integer_X = int(x); double fractional_X = x - integer_X; int integer_Y = int(y); double fractional_Y = y - integer_Y; double v1 = SmoothNoise( integer_X, integer_Y ); double v2 = SmoothNoise( integer_X + 1, integer_Y); double v3 = SmoothNoise( integer_X, integer_Y + 1 ); double v4 = SmoothNoise( integer_X + 1, integer_Y + 1 ); double i1 = Interpolate( v1, v2, fractional_X ); double i2 = Interpolate( v3, v4, fractional_X ); return Interpolate( i1, i2, fractional_Y ); } struct ARGB { union { unsigned long argb; struct { #ifdef LITTLE_ENDIAN unsigned char B : 8; unsigned char G : 8; unsigned char R : 8; unsigned char A : 8; #else unsigned char A : 8; unsigned char R : 8; unsigned char G : 8; unsigned char B : 8; #endif }; }; ARGB() {} template ARGB( const T& r, const T& g, const T& b, const T& a ) { R = (unsigned char) ( r * 255.0 ); G = (unsigned char) ( g * 255.0 ); B = (unsigned char) ( b * 255.0 ); A = (unsigned char) ( a * 255.0 ); } ARGB( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) { R = r; G = g; B = b; A = a; } operator unsigned long () { return argb; } operator const unsigned long () const { return argb; } }; } #endif //_ZFXMATH_INCLUDE_BASICMATH_H_