Benötigten Winkel berechnen um eine bestimmte Distanz am Umfang einer Ellipse zurückzulegen

Neue Frage »

nano99 Auf diesen Beitrag antworten »
Benötigten Winkel berechnen um eine bestimmte Distanz am Umfang einer Ellipse zurückzulegen
Meine Frage:
In einer kleinen, selbstgestellten Programmierübung möchte ich verschiedene Dinge über Ellipsen berechnen. Der Teil, bei dem ich nicht mehr weiterkomme, ist der folgende: Ich will den Winkel berechnen, der nötig ist, um eine gegebene Distanz auf dem Umfang einer gegebenen Ellipse zurückzulegen, während bei einem gegebenen Winkel gestartet wird. Das angehängte Bild sollte das Problem deutlich machen.

Es ist sicher, dass , aber es ist möglich, dass .

Ich möchte das alles nur mit mathematischen Operationen erreichen, die in allgemeinen Programmiersprachen verfügbar sind (z.B. C++, die in math.h). Also möchte ich, während in meinem Programm das endgültige Ergebnis berechnet wird, Integrale oder Ableitungen vermeiden. Für die Herleitung des Lösungsalgorithmus sind sie selbstverständlich erlaubt. Obwohl das Endergebnis wahrscheinlich eine geringere Genauigkeit ohne diese Operationen haben wird, sollte es eine maximale Abweichung von ca. 5% besitzen.

Meine Ideen:
Ich habe jetzt schon mehrere Stunden nach elliptischen Integralen recherchiert, insbesondere der zweiten Art, nach Exzentritäten und auch schon über Lösungen im kartesischen oder im polaren Koordinatensystem nachgedacht, konnte aber bisher keine Lösung finden.
HAL 9000 Auf diesen Beitrag antworten »

Soweit ich das erkenne, sind in math.h keine elliptischen Integrale drin, also musst du ja bereits bei der (Teil-)Umfangbestimmung mit irgendwelchen Näherungen arbeiten. Sofern es nicht auf die letzte Schnelligkeit ankommt, dann nimm doch einfach diese Prozeduren, um dich iterativ dem gesuchten Winkel anzunähern (z.B. Sekantenverfahren).
nano99 Auf diesen Beitrag antworten »
Benötigten Winkel berechnen um eine bestimmte Distanz am Umfang einer Ellipse zurückzulegen
Eine ähnliche Näherungsmethode habe ich schon versucht, allerdings ist sie langsam, speicherintensiv und ineffizient, weswegen ich mich entschieden habe, diese nicht in meiner Hauptfrage zu erwähnen.

Falls es trotzdem jemanden interessiert, ist hier mein bisheriger Algorithmus in Pseudocode:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
variable ellipseBreite = 100;
variable ellipseHoehe = 50;
array kantenLaengen;

generiereEllipsenKantenlaengen()
{
    variable rad = PI / 180;
    punkt letzterPunkt = punkt(ellipseBreite, 0);

    for(variable a=0.5; a<=90.5; a+=0.5)
    {
        punkt neuerPunkt = punkt(cos(a*rad)*ellipseBreite, sin(a*rad)*ellipseHoehe);
        kantenLaengen.fuegeHinzu(abstand(letzterPunkt, neuerPunkt));
        letzterPunkt = neuerPunkt;
    }
}

ellipsenKantenWinkel(gesamtLaenge, beginnWinkel)
{
    variable index = abrunden((beginnWinkel - modulo(beginnWinkel, 0.5)) / 0.5);
    variable bereitsZurueckgelegt = kantenLaengen[index] * (modulo(beginnWinkel, 0.5) / 0.5);
    variable rueckgabe = modulo(beginnWinkel, 0.5);

    while(bereitsZurueckgelegt < gesamtLaenge)
    {
        index = index + 1;
        bereitsZurueckgelegt = bereitsZurueckgelegt + kantenLaengen[index];
        rueckgabe = rueckgabe + 0.5;
    }

    variable endDifferenz = betrag(bereitsZurueckgelegt - gesamtLaenge) / kantenLaengen[index];
    retAngle = retAngle - 0.5 * endDifferenz;

    zurueckgeben retAngle;
}

main()           //Hier beginnt das Programm
{
    variable bogenLaenge = 20;
    variable beginnWinkel = 60;

    generiereEllipseKantenlaengen();

    print("Breite: " + ellipseBreite);
    print("Hoehe: " + ellipseHoehe);
    print("Bogenlaenge: " + bogenLaenge);
    print("Beginnwinkel: " + beginnWinkel);
    printf("Endergebnis: " + ellipsenKantenWinkel(bogenLaenge, beginnWinkel));
}


Bei so viel Code bin ich mir sicher, dass eine clever vereinfachte Funktion ein wesentlich genaueres und schnelleres Ergebnis liefern könnte, das weniger Schreibarbeit benötigt.

Außerdem will ich den Algorithmus, den ich in meinem kleinen Testprogramm entwickle, später in einer OpenGL-Anwendung verwenden, deswegen sollte die Funktion in Echtzeit ausgeführt werden können, was natürlich mit einer Formel am einfachsten geht.
HAL 9000 Auf diesen Beitrag antworten »

Ich kenne zumindest einen bewährten "Trick", wie man diese aufwändigen cos(a*rad),sin(a*rad)-Berechnungen erheblich beschleunigen kann:

Winkelfunktionen sind relativ "teuer" im Rechenaufwand - wenn man immer im gleichen Winkelabstand "weiterrückt", kann man Additionstheoreme nutzen:





Man benötigt also nur die Winkelfunktionen für , startet mit cn:=1;sn:=0 und fährt dann die Iteration

cn1:=cn*c-sn*s;
sn1:=cn*s+sn*c;
...
cn:=cn1;
sn:=sn1;


ab, nun mit den (vergleichsweise) sehr schnellen Grundrechenarten.
Neue Frage »
Antworten »



Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »