Arkustangens



  • Die for-Schleife muss bei 1 anfangen.
    (Das Element 0 benutzt du schon bei der initialisierung)

    Und die Rückgabewerte musst du noch skalieren

    result=(float)((180.0 * -winkel)/(0x7FFFFFFFL));
    


  • Ich habe die Skalierung in der main vorgenommen. Habe deinen Vorschlag eingebaut, jedoch kommt nach wie vor ein falscher Wert heraus.

    WinkelA= 0.000000 | WinkelF= -43.254131 | error= 43.254131
    WinkelA= 0.099997 | WinkelF= 84.269104 | error= 84.169106
    WinkelA= 0.199995 | WinkelF= 78.535240 | error= 78.335243
    WinkelA= 0.299993 | WinkelF= 72.809349 | error= 72.509354
    WinkelA= 0.399990 | WinkelF= 67.076645 | error= 66.676651
    WinkelA= 0.499989 | WinkelF= 61.349762 | error= 60.849773
    WinkelA= 0.599987 | WinkelF= 55.623222 | error= 55.023235
    WinkelA= 0.699987 | WinkelF= 49.897209 | error= 49.197224
    WinkelA= 0.799986 | WinkelF= 44.158195 | error= 43.358208
    WinkelA= 0.899986 | WinkelF= 38.432198 | error= 37.532211
    WinkelA= 0.999985 | WinkelF= 32.698338 | error= 31.698353
    WinkelA= 1.099985 | WinkelF= 26.971798 | error= 25.871813
    WinkelA= 1.199985 | WinkelF= 21.245785 | error= 20.045799
    WinkelA= 1.299985 | WinkelF= 15.512209 | error= 14.212224
    WinkelA= 1.399986 | WinkelF= 9.786195 | error= 8.386209
    WinkelA= 1.499986 | WinkelF= 4.059656 | error= 2.559670
    WinkelA= 1.599987 | WinkelF= -1.667833 | error= 3.267820
    WinkelA= 1.699988 | WinkelF= -7.395354 | error= 9.095342
    WinkelA= 1.799989 | WinkelF= -13.135355 | error= 14.935344
    WinkelA= 1.899990 | WinkelF= -18.867949 | error= 20.767939



  • WinkelA ist der Wert der math.h atan2 Funktion, WinkelF ist der Wert den meine Funktion zurückliefert.



  • Mit welchen Werten rufst du denn die Funktionen auf?

    Zeig doch mal die Funktion, mit der du die Ausgabe ("WinkelA= 0.000000 | WinkelF= -43.254131 | error= 43.254131 ") machst.



  • Also diesen Aufruf erzeuge ich über ein Textfile

    fprintf(ATANFILE,"WinkelA= %f|WinkelF= %f|error= %f\n",atan2(mysin,mycos),winkelF,error);

    Der Funktionsaufruf für atan2 : winkelF = (i_atan2(mysin2,mycos2));
    mysin und mycos werden in einer anderen Funktion berechnet und anschließend für atan2 in integer umgewandelt.

    mysin2 = (int)(mysinPOW_31_MINUS_1);
    mycos2 = (int)(mycos
    POW_31_MINUS_1);

    In der main läuft eine for-Schleife, die mir 20 Sinus/Cosinus Werte und daraus atan2 Werte berechnet.Hier doch besser die main:

    int main()
    {
    	int i;
    	int mysin2,mycos2;
    	float angle=0,error=0.0;
    	float mysin,mycos,arctan,winkelF=0.0;
    	ATANFILE=fopen("atan.txt","w");
    
    	for(i=0;i<20;i++)
    	{
    		mysin = sinF(angle);
    		mycos = cosF(angle);
    
    		mysin2 = (int)(mysin*POW_31_MINUS_1);
    		mycos2 = (int)(mycos*POW_31_MINUS_1);
    
    		winkelF = (i_atan2(mysin2,mycos2));
    		error = fabs(winkelF-atan2(mysin,mycos));
    
    		fprintf(ATANFILE,"WinkelA= %f |  WinkelF= %f  |  error= %f  \n",atan2(mysin,mycos),winkelF,error);
    
    		angle += 0.1; 
    	}
    
    fclose(ATANFILE);
    
    return 0;
    }
    


  • mysin/mycos liefert Werte zwischen -1 und 1



  • DirkB schrieb:

    Beachte aber auch die Reihenfolge der Parameter von der Funktion (atan2) aus der Standardbibliothek.
    Du solltest es nicht anders machen.

    Der Prototyp von atan2 aus der math.h lautet

    double atan2 (      double y,      double x );
    

    Deine Funktion:

    float i_atan2(int x,int y)
    

    DirkB schrieb:

    Winkel werden bei Computern meist/oft/häufig im Bogenmaß angegeben.
    Du scheinst aber mit Grad zu rechnen.
    Wofür ist der Algorithmus denn ausgelegt.

    atan2 aus der math.h gibt Bogenmaß zurück.
    Bei der Umrechnung, die ich geschrieben habe, habe ich Grad verwendet, da Bogenmaß mit int nicht sehr sinnvoll ist.
    (Wo ist diese Umrechnung denn jetzt? Du hast geschrieben die sei in der main)

    Statt POW_31_MINUS_1 kannst du auch 10000 (oder 100000) nehmen.

    Interresant sind doch die Werte für 0, 45, 90 ... Grad.

    winkelF = (i_atan2( 10000,      0));  //  0 Grad
    winkelF = (i_atan2( 10000,  10000));  //  45 Grad
    winkelF = (i_atan2(     0,  10000));  //  90 Grad
    winkelF = (i_atan2(-10000,      0));  // 180 Grad
    winkelF = (i_atan2(     0, -10000));  // -90 Grad
    


  • result=(float)((-winkel)*DIVPOW_31_MINUS_1 *180));
    

    Ich hatte es kurz vorher in die Funktion geschrieben.

    atan2(y=cos,x=sin)?



  • MrChipsy schrieb:

    result=(float)((-winkel)*DIVPOW_31_MINUS_1 *180));
    

    Ich hatte es kurz vorher in die Funktion geschrieben.

    Also Grad.
    Wenn du das mit dem Ergebnis von atan2 vergleichen willst, musst du Umrechnen.

    Aber warum denn jetzt noch DIVPOW_31_MINUS_1 als neue Konstante.

    MrChipsy schrieb:

    atan2(y=cos,x=sin)?

    Einheitskreis
    x = cos; y = sin

    Wenn der Y-Wert 0 ist und X positiv (> 0), kommt 0° raus
    sin(0°) = 0, cos(0°) = 1

    Wenn der Y-Wert positiv (> 0) ist und X gleich 0, kommt 90° raus
    sin(90°) = 1, cos(90°) = 0



  • mysin2 = (int)(mysin*POW_31_MINUS_1);
    		mycos2 = (int)(mycos*POW_31_MINUS_1);
    

    Das war meine Normierung für Festkomma, um danach wieder auf Fließkomma zu kommen multipliziere ich den Kehrwert von POW_31_MINUS_1.
    Macht man das nicht so?
    Nach wie vor komme ich nicht auf die Werte



  • WinkelA= 0.000000 | WinkelF= 46.752865 | error= 46.752865
    WinkelA= 5.729409 | WinkelF= 5.729409 | error= 0.000000
    WinkelA= 11.458842 | WinkelF= 11.458842 | error= 0.000001
    WinkelA= 17.188329 | WinkelF= 17.188330 | error= 0.000000
    WinkelA= 22.917751 | WinkelF= 22.917751 | error= 0.000000
    WinkelA= 28.647286 | WinkelF= 28.647287 | error= 0.000001
    WinkelA= 34.376748 | WinkelF= 34.376751 | error= 0.000003
    WinkelA= 40.106289 | WinkelF= 40.106289 | error= 0.000000
    WinkelA= 45.835820 | WinkelF= 45.835823 | error= 0.000003
    WinkelA= 51.565372 | WinkelF= 51.565372 | error= 0.000000
    WinkelA= 57.294938 | WinkelF= 57.294937 | error= 0.000001
    WinkelA= 63.024476 | WinkelF= 63.024479 | error= 0.000003
    WinkelA= 68.754089 | WinkelF= 68.754089 | error= 0.000000
    WinkelA= 74.483655 | WinkelF= 74.483658 | error= 0.000003
    WinkelA= 80.213275 | WinkelF= 80.213280 | error= 0.000005
    WinkelA= 85.942875 | WinkelF= 85.942871 | error= 0.000003
    WinkelA= 91.672488 | WinkelF= 91.672493 | error= 0.000005
    WinkelA= 97.402108 | WinkelF= 97.402115 | error= 0.000007
    WinkelA= 103.131742 | WinkelF= 103.131744 | error= 0.000003
    WinkelA= 108.861382 | WinkelF= 108.861382 | error= 0.000001

    So es klappt jetzt, großes Dankeschön an dich!
    Muss jetzt nur noch schauen, dass ich den ersten Wert hinbekomme.



  • Für die Berechnung des atan2 spielt es keine Rolle ob du bei x und y jetzt OW_31_MINUS_1 oder 100000 hast. Hauptsache beide Werte sind gleich skaliert.
    Und auch der atan2 aus der math.h kann die selben Werte bekommen.

    Da cos(0) = 1 ist, kann es sein dass du mit deinen OW_31_MINUS_1 an die Grenze des Algorithmus kommst. Versuch es doch mal mit 100000.

    Nebenbei werden alle Fließkommeberechnungen vom Compiler als double ausgeführt.
    Es hat eigentlich nur Nachteile float statt double zu nehmen.


Anmelden zum Antworten