Kreis berechnen



  • Hallo,

    ich siitze hier an einem ziemlich verzwickten Problem.

    Ich brauche eine Funktion die mir die Koordinaten einzelner Punkte auf einem Kreis ausgibt.
    Aber nacheinander und in gleichbleibenden zeitlichen Abständen.

    Soweit bin ich im Moment:

    // fd - globale Variable zum 
    // vzw - Vorzeichenwechsel, siehe: y = +- Wurzel (r²-x²) 
    
    	if (fd+1 > r || fd-1 <= -r) vzw *= -1;
    	int x, y;
    
    	if (vzw < 0) x = fd--;
    	else x = fd++;
    
    	//Memo1->Lines->Add(IntToStr((int)fd));
    
    	y=sqrt(pow(r,2)-pow(x,2))*vzw;
    	PaintBox1->Canvas->LineTo(250+x,250+y);
    

    Damit läuft es auch schon fast wie gewünscht.
    Allerdings werden die Abstände am rechten, bzw. linken Rand des Kreises immer größer und genau das möchte ich vermeiden.

    Zur Veranscheulichung hier das kompilierte Programm: http://www.file-upload.net/download-2421030/Project1.exe.html
    (Auf das Forumular klicken um die Animation zu starten)

    Ich hoffe jemand kann mir helfen



  • Dafuer hat ein schlauer Mensch mal sin&cos erfunden, damit hast du auch nicht mehr das Problem mit dem Verzeichenwechsel.

    for( double i = 0 bis 2pi )
    {
     double x = r * cos( i );
     double y = r * sin( i );
    
    }
    


  • Das Problem hierbei ist jedoch, dass die Punkte nicht nacheinander den Kreis füllen sondern immer an verschiedenen Positionen.

    Wenn du möchtest , kann ich dir zeigen, was dann passiert.

    Außerdem sind sinus-Funktionen sehr ressourcenfressend.


  • Mod

    yuri _m schrieb:

    Das Problem hierbei ist jedoch, dass die Punkte nicht nacheinander den Kreis füllen sondern immer an verschiedenen Positionen.

    Wenn du möchtest , kann ich dir zeigen, was dann passiert.

    Du versuchst nicht zufällig die Funktionen mit Winkeln in Grad zu benutzen? Die erwarten nämlich Bogenmaß.

    Außerdem sind sinus-Funktionen sehr ressourcenfressend.

    😃 Kein Kommentar.



  • yuri _m schrieb:

    Außerdem sind sinus-Funktionen sehr ressourcenfressend.

    Du benutzt grad Wurzel und exp-Funktionen und zeichnest deinen einzelnen Punkt in einer langsamen GUI mit einer sehr langsamen Zeichenmethode. Da macht ein sin/cos nichts mehr aus.



  • yuri _m schrieb:

    Das Problem hierbei ist jedoch, dass die Punkte nicht nacheinander den Kreis füllen sondern immer an verschiedenen Positionen.

    Wenn du möchtest , kann ich dir zeigen, was dann passiert.

    Außerdem sind sinus-Funktionen sehr ressourcenfressend.

    Aha...ja wuerde mich mal interessieren wie du das meinst.
    Dir ist Performance also wichtig, verwendest aber pow um ein Quadrat zu berechnen? Ausserdem ist ein sqrt auch nicht grad billig und das was du haben willst, eine gleichmassige Verteilung, kriegst du nur mit sin/cos hin.



  • yuri _m schrieb:

    Das Problem hierbei ist jedoch, dass die Punkte nicht nacheinander den Kreis füllen sondern immer an verschiedenen Positionen.

    .. das liegt wahrscheinlich daran, dass Du den Unterschied zwischen Grad und Bogenmaß nicht kennst.

    SeppJ schrieb:

    Außerdem sind sinus-Funktionen sehr ressourcenfressend.

    😃 Kein Kommentar.

    Ich beobachte eine gewisse Korrelation zwischen dem Unwissen eines Programmierers und dem Trieb das schnellstmögliche Programm zu schreiben. man beachte:

    yuri _m schrieb:

    y=sqrt(pow(r,2)-pow(x,2))*vzw;
    

    .. wenn Du bei pow(..,2) die richtige Include-Datei erwischt hat (die mit 2 double als Paramter), dann kann man von 'ressourcenfressend' reden.



  • Das ist doch nicht das Programm an dem ich programmiere. 🙄
    Das was ich oben stehen habe, dient der Veranschaulichung.

    Also bitte, darum geht es hier schließlich auch nicht.



  • Fairerweise soll Dir noch verraten werden, wie es wirklich performant zu lösen geht.

    stumpfi schrieb:

    Dir ist Performance also wichtig, verwendest aber pow um ein Quadrat zu berechnen? Ausserdem ist ein sqrt auch nicht grad billig und das was du haben willst, eine gleichmassige Verteilung, kriegst du nur mit sin/cos hin.

    Das stimmt, nur wie oft? Man muss sin/cos nämlich nur genau einmal aufrufen. In etwa so:

    const double PI = std::acos(-1.0); // benötigt #include <cmath>
    const double delta = 20* (PI/180); // das sind 20Grad (das Delta um das der Kreisbogen weiter gezeichnet wird) im Bogenmaß 
    const double sin_delta = std::sin( delta );
    const double cos_delta = std::cos( delta );
    
    // .. Initialisierung:
    double x = r;
    double y = 0;
    
        // .. später dann in der Schleife, wird x und y aus den alten Werten neu bestimmt.
        double x_neu =  x*cos_delta + y*sin_delta;
        y = -x*sin_delta + y*cos_delta;
        x = x_neu;
        // usw.
    


  • okay, danke werner.

    es lag tatsächlich daran, dass ich bogenmaß und gradmaß verwechselt habe.
    ich bin noch nicht so alt, da darf man sich so einen Fehler schon mal erlauben 🙂

    nun funktioniert es perfekt.


  • Mod

    Ist es denn auch schnell genug? Schließlich kann ein moderner Prozessor nur gut 15 Millionen Punkte pro Sekunde berechnen.



  • Wenn du cmath schon inkludierst, kannst auch gleich M_PI benutzen statt es "selbst" zu berechnen. 😉



  • Fellhuhn schrieb:

    Wenn du cmath schon inkludierst, kannst auch gleich M_PI benutzen statt es "selbst" zu berechnen. 😉

    Nein, denn M_PI steht nämlich nicht im C++-Standard. 😉



  • Ah, okay. Naja. Mir egal. 😛


  • Mod

    Aber ich würde wenigstens die Berechnung durch einen festen Wert ersetzen. Ich wäre mir nämlich nicht so sicher, ob ein acos wegoptimiert wird.


Anmelden zum Antworten