wahsaga: Ellipsenbahn berechnen - Schrittweite

hi,

das Thema dieser Frage hat nur am Rande was mit Javascript zu tun, eigentlich ist es eher Mathematik.

Ich möchte mit Javascript ein Objekt auf einer elliptischen Bahn bewegen. (Die Ellipse sei breiter als hoch, bzw. ggf. wäre, falls doch einmal der gegenteilige Fall auftreten sollte, die Vorgehensweise umzukehren.)

Grundsätzlich nicht allzu schwer, ich gehe von einer Ellipse in der 1. Hauptlage aus, habe die Formel
  [latex]\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1[/latex]
und stelle diese nach y um, und "bewege" das Objekt dann auf der Ellipsenbahn, in dem ich den Wert von x von 0 bis a/2 und zurück variiere. Noch ein bisschen triviales Vorzeichengebastel dazu, um das Objekt immer im richtigen Quadranten darzustellen, und schont bewegt sich mein Objekt auf einer elliptischen Bahn.

Was daran allerdings noch unschön aussieht: Wenn ich in einem festen Zeitinterval den Wert von x um gleichgroße Schritte verändere, so fängt das bewegte Objekt "an zu rennen", wenn es sich den bei seitlichsten Punkten nähert, und wenn es wieder zu einem der beiden Punkte oben oder unten kommt, wird es wieder langsamer.
Es ist also noch keine schön "fließende" Bewegung.

Also muss ich wohl einen sinnvollen Weg finden, wenn x gleich 0 ist mit größeren Schrittweiten zu beginnen, die dann kleiner werden, wenn x sich dem Wert von a/2 nähert [1].

Ich habe die vernebelte Vorstellung, dass mir der/ein Logarithmus dabei behilflich sein könnte - habe allerdings keine genaue Idee, wie (hab' die Dinger schon zu Schulzeiten nicht sonderlich leiden können, und mich seitdem auch nicht mehr gerne damit beschäftigt).
Wer hat eine für mich?

gruß,
wahsaga

[1] Alternative wäre eventuell, statt der Schrittweite die Zeitintervalle zu verändern. Damit könnte man wohl ebenso eine gleichmäßigere Bewegung hinbekommen, allerdings dürften die "Sprünge" des Objektes damit immer noch unterschiedlich weit ausfallen.

--
/voodoo.css:
#GeorgeWBush { position:absolute; bottom:-6ft; }
  1. Moin!

    Ich möchte mit Javascript ein Objekt auf einer elliptischen Bahn bewegen.

    Live animiert? Oder nur simpel berechnet?

    Was daran allerdings noch unschön aussieht: Wenn ich in einem festen Zeitinterval den Wert von x um gleichgroße Schritte verändere, so fängt das bewegte Objekt "an zu rennen", wenn es sich den bei seitlichsten Punkten nähert, und wenn es wieder zu einem der beiden Punkte oben oder unten kommt, wird es wieder langsamer.
    Es ist also noch keine schön "fließende" Bewegung.

    Weil du in deiner gesamten Formel bislang noch nirgendwo den Begriff "Geschwindigkeit" mit einfließen hast lassen. Wobei: Konstante Änderungen von X sind natürlich auch eine Art von Geschwindigkeit, nur eben eine, die dir nicht vorschwebte.

    Definiere zunächst, welche Geschwindigkeit dein Objekt haben soll: Konstante Winkelgeschwindigkeit, konstante Streckengeschwindigkeit - oder wohlmöglich soll es nach Newtons Gesetzen als Objekt auf einer Umlaufbahn um eine große Masse unterwegs sein.

    Diese Geschwindigkeit wird dann irgendwie in die Projektion deiner Ellipse einfließen müssen, um das Objekt gleichmäßiger darauf zu bewegen.

    Ich habe die vernebelte Vorstellung, dass mir der/ein Logarithmus dabei behilflich sein könnte

    Nein, der Logarithmus hilft dir hier nicht - der würde lediglich als Faktor dafür sorgen, dass du bei bewegungskritischen X-Werten etwas feinere Schrittweiten kriegst - allerdings auch nicht automatisch, sondern nur nach passendem Tuning.

    - Sven Rautenberg

    --
    "Love your nation - respect the others."
  2. Hallo wahsaga,

    Ich möchte mit Javascript ein Objekt auf einer elliptischen Bahn bewegen.
      [latex]\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1[/latex]
    und stelle diese nach y um, ...

    dann bekommst du aber eine recht "unhandliche" Formel mit einer Wurzel und einem fiesen Quotienten.

    Was daran allerdings noch unschön aussieht: Wenn ich in einem festen Zeitinterval den Wert von x um gleichgroße Schritte verändere, so fängt das bewegte Objekt "an zu rennen", wenn es sich den bei seitlichsten Punkten nähert, und wenn es wieder zu einem der beiden Punkte oben oder unten kommt, wird es wieder langsamer.

    Hast du schon mal daran gedacht, die Ellipse in Polarkoordinaten anzusetzen?
    Dann hättest du

    x = a * sin(u)
     y = b * cos(u)

    Anstatt der Wurzel hast du dann eine trigonometrische Funktion, die man aber im Interesse der Geschwindigkeit durch ein Tabellen-Lookup ersetzen kann - du verwendest doch wahrscheinlich eh eine endliche Schrittweite?
    Wenn du nun den Parameter u in gleichmäßigen Schritten laufen lässt, hast du eine fast gleichförmige Bewegung; die Winkelgeschwindigkeit ist immerhin konstant.

    So long,
     Martin

    --
    Die beste Informationsquelle sind Leute, die jemand anderem versprochen haben, nichts weiterzuerzählen.
      (alte Journalistenweisheit)
    1. hi,

      Anstatt der Wurzel hast du dann eine trigonometrische Funktion, die man aber im Interesse der Geschwindigkeit durch ein Tabellen-Lookup ersetzen kann - du verwendest doch wahrscheinlich eh eine endliche Schrittweite?

      Ja, könnte man machen.
      Da ich das Element allerdings um Ellipsen mit verschieden Ausmaßen, die mir erst zur Laufzeit bekannt sind, laufen lassen will, wäre es dann nur sinnvoll, mir die Sinus-/Cosinus-Werte irgendwo abzulegen - und dann jeweils noch mit a und b zu multiplizieren [1].

      Aber die mathematischen Funktionen sind nach meinen Erfahrungen in solchen Fällen sowieso selten der Flaschenhals - das neu positionieren des Objektes bzw. das Rendern dieser Positionsveränderung ist meist das, was "dauert".

      Aber ich werde trotzdem schauen, ob ich das umsetze - und sei es nicht der effektiven optischen Geschwindigkeit wegen, sondern nur der Rechenperformance.

      gruß,
      wahsaga

      [1] Bringt das dann überhaupt was? Ältere Taschenrechner hatten doch AFAIK eh schon immer Lookup-Tabellen, in denen dann die Werte näherungsweise nachgeschlagen wurden - ob das bei JS überhaupt anders ist?

      --
      /voodoo.css:
      #GeorgeWBush { position:absolute; bottom:-6ft; }
      1. Hallo,

        Da ich das Element allerdings um Ellipsen mit verschieden Ausmaßen, die mir erst zur Laufzeit bekannt sind, laufen lassen will, wäre es dann nur sinnvoll, mir die Sinus-/Cosinus-Werte irgendwo abzulegen - und dann jeweils noch mit a und b zu multiplizieren.

        so hatte ich das auch gemeint.

        Aber die mathematischen Funktionen sind nach meinen Erfahrungen in solchen Fällen sowieso selten der Flaschenhals - das neu positionieren des Objektes bzw. das Rendern dieser Positionsveränderung ist meist das, was "dauert".

        Hm, das ist wohl wahr ...

        [1] Bringt das dann überhaupt was? Ältere Taschenrechner hatten doch AFAIK eh schon immer Lookup-Tabellen, in denen dann die Werte näherungsweise nachgeschlagen wurden - ob das bei JS überhaupt anders ist?

        Keine Ahnung, wie es in JS *allgemein* gemacht wird. Die JS-Engine von Mozilla/Firefox ("Spidermonkey") berechnet Sinus- und Cosinuswerte jedenfalls über ein Polynom 14. Grades, von dem allerdings nur die geraden Terme berücksichtigt werden - bleiben also 6 Polynomglieder und eine Konstante. Die Runtime-Libraries und Standardbibliotheken verschiedener Programmiersprachen/Compiler berechnen transzendente Funktionen (Sinus/Cosinus, Logarithmen, Wurzeln) ähnlich aufwendig. In so einem Fall bringt es einen erheblichen Zeitgewinn (bezogen auf die Mathematikfunktion), wenn man stattdessen auf eine Tabelle zugreift; sogar eine lineare Interpolation von Zwischenwerten kann sich von der Performance her noch auszahlen. Bei Sinus/Cosinus ist in vielen Fällen eine Tabelle mit 256 Stützpunkten ausreichend für die jeweilige Anwendung, und die Werte selbst kann man als 16bit-Integers ablegen (Definition: ±32767 entspricht ±1.0). Allein der Verzicht auf Fließkommaarithmetik dürfte die Rechnung erheblich beschleunigen.

        So long,
         Martin

        --
        Der Gast geht solange zum Tresen, bis er bricht.
        1. 'Nabend.

          Statt eines Lookup Tables bietet sich für Winkelfunktionen auch folgende Rekursionsformel an, die sich aus den Tschebycheff-Polynomen ergibt:

          k = 2 · cos(w)
          y[n] = k · y[n-1] - y[n-2]

          Wird z.B. in Audioplugins gerne mal als Oszillator benutzt. Allerdings sollte es schon eine 32-Bit-Fließkommazahl sein, um nicht bereits nach ein paar hundert Rekursionschritten "abzudriften".

  3. Hallo wahsaga,

    Was daran allerdings noch unschön aussieht: Wenn ich in einem festen Zeitinterval den Wert von x um gleichgroße Schritte verändere, so fängt das bewegte Objekt "an zu rennen", wenn es sich den bei seitlichsten Punkten nähert, und wenn es wieder zu einem der beiden Punkte oben oder unten kommt, wird es wieder langsamer.
    Es ist also noch keine schön "fließende" Bewegung.

    was hättest Du denn gerne als "fließende" Bewegung?

    - (einigermaßen) konstante Bahngeschwindigkeit?
      - (einigermaßen) konstante Winkelgeschwindigkeit?

    oder eine Bewegung gemäß dem zweiten Keplerschen Gesetz?

    Freundliche Grüße

    Vinzenz

  4. Hallo wahsaga,

    [latex]\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1[/latex]

    hast du schon mal dran gedacht, diese Formel zu nehmen:

    x = a*cos(phi)
    y = b*sin(phi)

    und den Winkel phi lässt du als Parameter von 0 bis 2Pi laufen. So hättest du dann eine konstante Winkelgeschwindigkeit bzw. -diskretisierung.

    Gruß, Jürgen

    1. hi,

      hast du schon mal dran gedacht, diese Formel zu nehmen:

      x = a*cos(phi)
      y = b*sin(phi)

      und den Winkel phi lässt du als Parameter von 0 bis 2Pi laufen. So hättest du dann eine konstante Winkelgeschwindigkeit bzw. -diskretisierung.

      Ja, das dürfte dann vermutlich der einfachere (einfachste) Weg sein - und ich hab mal wieder zu kompliziert gedacht :-)

      Danke auch den anderen, deren Antworten ja größtenteils auf das gleiche hinausliefen.

      gruß,
      wahsaga

      --
      /voodoo.css:
      #GeorgeWBush { position:absolute; bottom:-6ft; }