Browse Source

tan, cos, sin und acos approximationsfunktionen hinzugefügt

Zur beseitigung von asynchronitätsproblemen zwischen linux und windows wo die buildinfunktionen unterschiedliche ergebnisse erzielen
kolja 5 years ago
parent
commit
643c9f3024
7 changed files with 170 additions and 45 deletions
  1. 7 7
      Bild.cpp
  2. 82 24
      FrameworkMath.h
  3. 2 2
      Mat3.h
  4. 6 6
      Mat4.h
  5. 48 2
      Text.cpp
  6. 21 0
      Text.h
  7. 4 4
      Vec2.h

+ 7 - 7
Bild.cpp

@@ -743,7 +743,7 @@ void Bild::drawLinieBordered( Punkt a, Punkt b, int bc, int fc )
         else
             yf = yf < 0 ? -1 : 1;
         double x = (double)a.x, y = (double)a.y;
-        int maxP = (int)( sqrt( xlen * xlen + ylen * ylen ) + 0.5 );
+        int maxP = (int)( sqrt( (float)(xlen * xlen + ylen * ylen) ) + 0.5 );
         int count = 0;
         int maxPixel = size.x * size.y;
         while( !( (int)( x + 0.5 ) == b.x && (int)( y + 0.5 ) == b.y ) && count < maxP )
@@ -842,7 +842,7 @@ void Bild::drawLinieBorderedAlpha( Punkt a, Punkt b, int bc, int fc )
             unsigned char *cf = (unsigned char*)&fc;
             cf[ 3 ] = (unsigned char)( ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] ) );
         }
-        int maxP = (int)( sqrt( xlen * xlen + ylen * ylen ) + 0.5 );
+        int maxP = (int)( sqrt( (float)(xlen * xlen + ylen * ylen) ) + 0.5 );
         int alpha = ( ( fc >> 24 ) & 0xFF );
         int alpha2 = ( ( bc >> 24 ) & 0xFF );
         int na = ( 0x100 - alpha );
@@ -974,7 +974,7 @@ void Bild::drawLinie( Punkt a, Punkt b, int fc ) // zeichnet eine Linie von Punk
         else
             yf = yf < 0 ? -1 : 1;
         double x = (double)a.x, y = (double)a.y;
-        int maxP = (int)( sqrt( xlen * xlen + ylen * ylen ) + 0.5 );
+        int maxP = (int)( sqrt( (float)(xlen * xlen + ylen * ylen) ) + 0.5 );
         int count = 0;
         while( !( (int)( x + 0.5 ) == b.x && (int)( y + 0.5 ) == b.y ) && count < maxP )
         {
@@ -1060,7 +1060,7 @@ void Bild::drawLinieAlpha( Punkt a, Punkt b, int fc )
             unsigned char *cf = (unsigned char*)&fc;
             cf[ 3 ] = (unsigned char)( ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] ) );
         }
-        int maxP = (int)( sqrt( xlen * xlen + ylen * ylen ) + 0.5 );
+        int maxP = (int)( sqrt( (float)(xlen * xlen + ylen * ylen) ) + 0.5 );
         int count = 0;
         int alpha = ( ( fc >> 24 ) & 0xFF );
         int na = ( 0x100 - alpha );
@@ -1106,7 +1106,7 @@ void Bild::drawKreis( int xOff, int yOff, int r, int fc ) // zeichnet einen Krei
         return;
     for( int a = 0; a < r; ++a )
     {
-        int b = (int)( sqrt( (long)( r * r - a * a ) ) + 0.5 );
+        int b = (int)( sqrt( (float)(long)( r * r - a * a ) ) + 0.5 );
         if( xOff + a < dgx && xOff + a > dpx && yOff + b < dgy && yOff + b > dpy )
             this->fc[ xOff + a + ( yOff + b ) * size.x ] = fc;
         if( xOff - a < dgx && xOff - a > dpx && yOff + b < dgy && yOff + b > dpy )
@@ -1150,7 +1150,7 @@ void Bild::drawKreisAlpha( int xOff, int yOff, int r, int fc )
     int i2 = ( alpha * ( fc & 0x00FF00 ) ) >> 8;
     for( int a = 0; a < r; ++a )
     {
-        int b = (int)( sqrt( (long)( r * r - a * a ) ) + 0.5 );
+        int b = (int)( sqrt( (float)(long)( r * r - a * a ) ) + 0.5 );
         int *pixel = 0;
         if( xOff + a < dgx && xOff + a > dpx && yOff + b < dgy && yOff + b > dpy )
         {
@@ -2069,7 +2069,7 @@ void Bild::replaceColorWithAlpha( int color )
         for( int x = dx + xx; x < bb; x++ )
         {
             unsigned char *cf = ( unsigned char* )&( fc[ x + ygr ] );
-            int abstand = (int)sqrt( ( r - cf[ 2 ] ) * ( r - cf[ 2 ] ) + ( g - cf[ 1 ] ) * ( g - cf[ 1 ] ) + ( b - cf[ 0 ] ) * ( b - cf[ 0 ] ) );
+            int abstand = (int)sqrt( (float)(( r - cf[ 2 ] ) * ( r - cf[ 2 ] ) + ( g - cf[ 1 ] ) * ( g - cf[ 1 ] ) + ( b - cf[ 0 ] ) * ( b - cf[ 0 ] )) );
             if( abstand > 255 )
                 abstand = 255;
             cf[ 3 ] = (unsigned char)( abstand );

+ 82 - 24
FrameworkMath.h

@@ -2,36 +2,94 @@
 #define FrameworkMath_H
 
 #include <math.h>
+#include <functional>
 #include "Betriebssystem.h"
 
+namespace Framework
+{
 #define PI 3.14159265
 
-// Gibt die größere Zahl zurück ohne if zu verwenden
-// Funktioniert nur, wenn die Zahlen nicht mehr als 16 bits verwenden
-//  a: Eine der beiden Zahlen
-//  b: Eine der beiden Zahlen
-inline int maxInt( int a, int b )
-{
-    return ( ( ( a - b ) >> 16 ) & b ) | ( ~( ( a - b ) >> 16 ) & a );
-}
+    // Gibt die größere Zahl zurück ohne if zu verwenden
+    // Funktioniert nur, wenn die Zahlen nicht mehr als 16 bits verwenden
+    //  a: Eine der beiden Zahlen
+    //  b: Eine der beiden Zahlen
+    inline int maxInt( int a, int b )
+    {
+        return ( ( ( a - b ) >> 16 ) & b ) | ( ~( ( a - b ) >> 16 ) & a );
+    }
 
-// Gibt die kleinere Zahl zurück ohne if zu verwenden
-// Funktioniert nur, wenn die Zahlen nicht mehr als 16 bits verwenden
-//  a: Eine der beiden Zahlen
-//  b: Eine der beiden Zahlen
-inline int minInt( int a, int b )
-{
-    return ( ( ( a - b ) >> 16 ) & a ) | ( ~( ( a - b ) >> 16 ) & b );
-}
+    // Gibt die kleinere Zahl zurück ohne if zu verwenden
+    // Funktioniert nur, wenn die Zahlen nicht mehr als 16 bits verwenden
+    //  a: Eine der beiden Zahlen
+    //  b: Eine der beiden Zahlen
+    inline int minInt( int a, int b )
+    {
+        return ( ( ( a - b ) >> 16 ) & a ) | ( ~( ( a - b ) >> 16 ) & b );
+    }
 
-// Gibt den positiven Wert eines Zeichnunges zurück.
-// Klappt nur, wenn der - und der < 0 operator definiert ist
-template< typename T>
-inline T abs( T t )
-{
-    if( t < 0 )
-        return -t;
-    return t;
+    // Gibt den positiven Wert eines Zeichnunges zurück.
+    // Klappt nur, wenn der - und der < 0 operator definiert ist
+    template< typename T>
+    inline T abs( T t )
+    {
+        if( t < 0 )
+            return -t;
+        return t;
+    }
+
+    inline float lowPrecisionSin( float radiant )
+    {
+        while( radiant < -3.14159265f )
+            radiant += 6.28318531f;
+        while( radiant > 3.14159265f )
+            radiant -= 6.28318531f;
+        float sin = 0;
+        if( radiant < 0 )
+        {
+            sin = 1.27323954f * radiant + .405284735f * radiant * radiant;
+
+            if( sin < 0 )
+                sin = .225f * ( sin *-sin - sin ) + sin;
+            else
+                sin = .225f * ( sin * sin - sin ) + sin;
+        }
+        else
+        {
+            sin = 1.27323954f * radiant - 0.405284735f * radiant * radiant;
+
+            if( sin < 0 )
+                sin = .225f * ( sin *-sin - sin ) + sin;
+            else
+                sin = .225f * ( sin * sin - sin ) + sin;
+        }
+        return sin;
+    }
+
+    inline float lowPrecisionCos( float radiant )
+    {
+        return lowPrecisionSin( radiant + 3.14159265f / 2.f );
+    }
+
+    inline float lowPrecisionTan( float radiant )
+    {
+        return lowPrecisionSin( radiant ) / lowPrecisionCos( radiant );
+    }
+
+    inline float lowPrecisionACos( float cos )
+    {
+        float negate = float( cos < 0 );
+        cos = abs( cos );
+        float ret = -0.0187293f;
+        ret = ret * cos;
+        ret = ret + 0.0742610f;
+        ret = ret * cos;
+        ret = ret - 0.2121144f;
+        ret = ret * cos;
+        ret = ret + 1.5707288f;
+        ret = ret * (float)sqrt( 1.0 - cos );
+        ret = ret - 2 * negate * ret;
+        return negate * 3.14159265358979f + ret;
+    }
 }
 
 #endif

+ 2 - 2
Mat3.h

@@ -69,8 +69,8 @@ namespace Framework
         //  radian: Der Winkel im Bogenmas, um dem der Vektor gedreht werden soll
         static Mat3 rotation( T radian )
         {
-            const T cosTheta = (T)cos( radian );
-            const T sinTheta = (T)sin( radian );
+            const T cosTheta = (T)lowPrecisionCos( radian );
+            const T sinTheta = (T)lowPrecisionSin( radian );
             Mat3 r = { cosTheta, -sinTheta, 0, sinTheta, cosTheta, 0, 0, 0, 1 };
             return r;
         }

+ 6 - 6
Mat4.h

@@ -216,8 +216,8 @@ namespace Framework
         //  radian: Der Winkel in Bogenmas
         static Mat4 rotationZ( T radian )
         {
-            const T cosTheta = (T)cos( radian );
-            const T sinTheta = (T)sin( radian );
+            const T cosTheta = (T)lowPrecisionCos( radian );
+            const T sinTheta = (T)lowPrecisionSin( radian );
             Mat4 r = { cosTheta, -sinTheta, 0, 0, sinTheta, cosTheta, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
             return r;
         }
@@ -225,8 +225,8 @@ namespace Framework
         //  radian: Der Winkel in Bogenmas
         static Mat4 rotationX( T radian )
         {
-            const T cosTheta = (T)cos( radian );
-            const T sinTheta = (T)sin( radian );
+            const T cosTheta = (T)lowPrecisionCos( radian );
+            const T sinTheta = (T)lowPrecisionSin( radian );
             Mat4 r = { 1, 0, 0, 0, 0, cosTheta, -sinTheta, 0, 0, sinTheta, cosTheta, 0, 0, 0, 0, 1 };
             return r;
         }
@@ -234,8 +234,8 @@ namespace Framework
         //  radian: Der Winkel in Bogenmas
         static Mat4 rotationY( T radian )
         {
-            const T cosTheta = (T)cos( radian );
-            const T sinTheta = (T)sin( radian );
+            const T cosTheta = (T)lowPrecisionCos( radian );
+            const T sinTheta = (T)lowPrecisionSin( radian );
             Mat4 r = { cosTheta, 0, sinTheta, 0, 0, 1, 0, 0, -sinTheta, 0, cosTheta, 0, 0, 0, 0, 1 };
             return r;
         }

+ 48 - 2
Text.cpp

@@ -62,6 +62,18 @@ Text::Text( double num )
     *this = num;
 }
 
+// Erstellt ein neues Text Objekt mit einer zahl als text
+//  num: Die Zahl, die im Text sein soll
+Text::Text( float num )
+    : txt( 0 ),
+    suchGBeg( 0 ),
+    suchGEnd( 0 ),
+    precision( 0 ),
+    ref( 1 )
+{
+    *this = num;
+}
+
 // Destruktor 
 Text::~Text()
 {
@@ -206,6 +218,14 @@ void Text::append( double num )
     append( ss.str().c_str() );
 }
 
+void Text::append( float num )
+{
+    std::stringstream ss;
+    ss.precision( precision );
+    ss << num;
+    append( ss.str().c_str() );
+}
+
 void Text::insert( int p, char c ) // Fügt an stelle p ein
 {
     if( p > getLength() || p < 0 ) // Auf unsinnige übergabe prüfen
@@ -1026,6 +1046,12 @@ Text &Text::operator+=( const double num )
     return *this;
 }
 
+Text &Text::operator+=( const float num )
+{
+    append( num );
+    return *this;
+}
+
 Text &Text::operator+=( const char *txt )
 {
     append( txt );
@@ -1052,6 +1078,13 @@ Text &Text::operator=( const double num )
     return *this;
 }
 
+Text &Text::operator=( const float num )
+{
+    setText( "" );
+    append( num );
+    return *this;
+}
+
 Text &Text::operator=( const char *txt )
 {
     setText( txt );
@@ -1085,11 +1118,14 @@ Text::operator __int64() const
 
 Text::operator double() const
 {
-    if( getLength() > 2 && txt[ 0 ] == '0' && txt[ 1 ] == 'x' )
-        return TextZuInt( ( txt + 2 ), 16 );
     return TextZuDouble( txt );
 }
 
+Text::operator float() const
+{
+    return TextZuFloat( txt );
+}
+
 bool Text::operator>( Text &t ) const
 {
     int len1 = getLength();
@@ -1466,11 +1502,21 @@ double Framework::TextZuDouble( char *c ) // Konvertiert c zu double
     return strtod( c, 0 );
 }
 
+float Framework::TextZuFloat( char *c ) // Konvertiert c zu double
+{
+    return strtof( c, 0 );
+}
+
 double Framework::TextZuDouble( char *c, char **c_ende )
 {
     return strtod( c, c_ende );
 }
 
+float Framework::TextZuFloat( char *c, char **c_ende )
+{
+    return strtof( c, c_ende );
+}
+
 int Framework::textLength( const char *txt ) // gibt die Länge von txt zurück
 {
     if( !txt )

+ 21 - 0
Text.h

@@ -32,6 +32,9 @@ namespace Framework
         // Erstellt ein neues Text Objekt mit einer zahl als text
         //  num: Die Zahl, die im Text sein soll
         __declspec( dllexport ) Text( double num );
+        // Erstellt ein neues Text Objekt mit einer zahl als text
+        //  num: Die Zahl, die im Text sein soll
+        __declspec( dllexport ) Text( float num );
         // Löscht den Text
         __declspec( dllexport ) ~Text();
         // Legt die Suchgrenzen fest, die von den Suchfunktionen verwendet werden.
@@ -79,6 +82,9 @@ namespace Framework
         // Hängt eine Kommazahl am Ende des Textes an
         //  num: Die Kommazahl, die am Ende des Textes angehängt werden soll
         __declspec( dllexport ) void append( double num );
+        // Hängt eine Kommazahl am Ende des Textes an
+        //  num: Die Kommazahl, die am Ende des Textes angehängt werden soll
+        __declspec( dllexport ) void append( float num );
         // Fügt an einer Bestimmten Stelle ein Zeichen in den Text ein
         //  p: Die position im Text bei der das Zeichen eingefügt werden soll
         //  c: Das Zeichen, das eingefügt werden soll
@@ -277,6 +283,8 @@ namespace Framework
         __declspec( dllexport ) Text &operator+=( const __int64 num );
         // Hängt eine Kommazahl ans Ende des Textes an
         __declspec( dllexport ) Text &operator+=( const double num );
+        // Hängt eine Kommazahl ans Ende des Textes an
+        __declspec( dllexport ) Text &operator+=( const float num );
         // Hängt eine Zeichenkette ans Ende des Textes an
         __declspec( dllexport ) Text &operator+=( const char *txt );
         // Hängt eine Kopie des Inhalts eines Textes ans Ende des Textes an
@@ -285,6 +293,8 @@ namespace Framework
         __declspec( dllexport ) Text &operator=( const int num );
         // Setzt den Inhalt des Textes gleich einer Kommazahl
         __declspec( dllexport ) Text &operator=( const double num );
+        // Setzt den Inhalt des Textes gleich einer Kommazahl
+        __declspec( dllexport ) Text &operator=( const float num );
         // Setzt den Inahlt des Textes gleich einer Zeichenkette
         __declspec( dllexport ) Text &operator=( const char *txt );
         // Setzt den Inhalt des Textes gleich einer Kopie des Inhalts eines anderen Textes
@@ -297,6 +307,8 @@ namespace Framework
         __declspec( dllexport ) operator __int64() const;
         // Konviertiert den Inhalt des Textes zu einer Kommazahl
         __declspec( dllexport ) operator double() const;
+        // Konviertiert den Inhalt des Textes zu einer Kommazahl
+        __declspec( dllexport ) operator float() const;
         // Prüft, ob der Inhalt des Textes nach alphabetischer Ordnung später kommt als der Inhalt eines anderen Textes
         __declspec( dllexport ) bool operator>( Text &t ) const;
         // Prüft, ob der Inhalt des Textes nach alphabetischer Ordnung früher kommt als der Inhalt eines anderen Textes
@@ -395,11 +407,20 @@ namespace Framework
     //  c: Die Zeichenkette, die konvertiert werden soll
     //  return: Das double, was in der Zeichenkette stand
     __declspec( dllexport ) double TextZuDouble( char *c );
+    // Konvertiert eine Zeichenkette zu einem Float
+    //  c: Die Zeichenkette, die konvertiert werden soll
+    //  return: Das float, was in der Zeichenkette stand
+    __declspec( dllexport ) float TextZuFloat( char *c );
     // Konvertiert eine Zeichenkette zu einem Double
     //  c: Die Zeichenkette, die konvertiert werden soll
     //  c_ende: Wird duch die Funktion gesetzt und darf 0 sein. Ein Zeiger auf das nächste Zeichen nach dem Double in der Zeichenkette
     //  return: Das double, was in der Zeichenkette stand
     __declspec( dllexport ) double TextZuDouble( char *c, char **c_ende );
+    // Konvertiert eine Zeichenkette zu einem float
+    //  c: Die Zeichenkette, die konvertiert werden soll
+    //  c_ende: Wird duch die Funktion gesetzt und darf 0 sein. Ein Zeiger auf das nächste Zeichen nach dem float in der Zeichenkette
+    //  return: Das float, was in der Zeichenkette stand
+    __declspec( dllexport ) float TextZuFloat( char *c, char **c_ende );
     // Ermittelt die Länge einer bestimmten Zeichenkette
     //  txt: Die Zeichenkette, deren Länge ermittelt werden soll
     //  return: Die Länge der Zeichenkette

+ 4 - 4
Vec2.h

@@ -15,7 +15,7 @@ namespace Framework
         // Konstruktor
         inline Vec2() noexcept
             : x( 0 ),
-              y( 0 )
+            y( 0 )
         {}
         // Konstruktor
         //  x: X Komponente des Vektors
@@ -187,8 +187,8 @@ namespace Framework
         inline Vec2 rotation( const float angle ) const
         {
             Vec2 result;
-            float cosine = cosf( angle );
-            float sine = sinf( angle );
+            float cosine = lowPrecisionCos( angle );
+            float sine = lowPrecisionSin( angle );
             result.x = (T)( x * cosine - y * sine );
             result.y = (T)( x * sine + y * cosine );
             return result;
@@ -196,7 +196,7 @@ namespace Framework
         // Ermittelt den Winkel zwischen zwei Vektoren
         inline T angle( const Vec2 &v2 ) const
         {
-            return (T)acos( ( *this * v2 ) / sqrt(  getLengthSq() * v2.getLengthSq() ) );
+            return (T)lowPrecisionACos( MIN( MAX( (float)( *this * v2 ) / (float)sqrt( (float)( getLengthSq() * v2.getLengthSq() ) ), -1 ), 1 ) );
         }
     };
 }