Arkustangens



  • 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