Grundsätzlich hängt die richtige Zeitskala davon ab, was der Spieler erlebt. Möchten Sie, dass es auf der Zeitskala von Wochen genau ist und der Spieler in Echtzeit mit ihm interagiert? Das ist viel schwieriger, als es auf der Zeitskala von Wochen zum Laufen zu bringen, die der Spieler oft in Echtzeit erlebt ( dh eine Sekunde Spielererfahrung ist eine Woche in Echtzeit).
Mklingen
Wenn Sie Wolkenbewegungen oder thermodynamische Variablen in Zellen mit einer Breite von Hunderten von Metern und einem dt von 10 Minuten simulieren, ist dies sinnvoll. aber starrer Körper in üblichen Maßstäben, nicht zu viel. Was ist die Anwendung?
v.oddou
Die Anwendung ist eine "Aufhol" -Mechanik, bei der die Simulation seit dem letzten Laden (eines Teils der Welt) ausgeführt wird. Die Spielelogik basiert ausschließlich auf Rückrufen, bei denen Rückrufe Timer oder Kollisionsrückrufe sind. Ich möchte die Physik zum nächsten ausführen können Timer-Rückruf effizient und die Physiksimulation befasst sich mit dem Aufrufen von Kollisionsrückrufen. Kollisionen sind relativ unwahrscheinlich, aber ich möchte, dass Kollisionsrückrufe zum Zeitpunkt der Kollision über den verfügbaren Spielstatus (Physik) verfügen.
fread2281
Antworten:
5
Sie werden wahrscheinlich für diese großen Zeitspannen eine konstante Beschleunigung verwenden (dies kann eine Beschleunigung von Null sein). Die Ableitung der konstanten Beschleunigung in Bezug auf die Zeit ist 0. Das bedeutet, dass sie sich in Bezug auf die Zeit nicht ändert, sodass es keine Rolle spielt, wie groß Ihre Deltazeit ist.
Diese kleine zeitliche Integration liefert die Gleichungen, die Sie benötigen.
a = a
v = at + v0
s =.5at^2+ v0*t + s0
Wobei: a = Beschleunigung, v = Geschwindigkeit, v0 = Anfangsgeschwindigkeit, s = Position, s0 = Anfangsposition, t = Zeit
Mit dieser Strategie können Sie Zeiträume von Millisekunden bis Wochen verwenden, wenn Sie möchten. Ihre Kombination würde in den v0und s0Parametern der Gleichung berücksichtigt.
Um Kollisionen zu behandeln, müssen Sie Strategien implementieren , die denen für kleine Hochgeschwindigkeitsobjekte ähneln . Berechnen Sie zuerst die neue Position mit der obigen Gleichung und wechseln Sie dann für alle Objekte zwischen der alten und der neuen Position. Da sich jedes dieser Objekte (Minuten oder Tage zuvor) geschnitten haben könnte, kann dies sehr komplex werden. Da Sie so große Deltazeiten haben, haben Sie wahrscheinlich genügend Zeit, um diese potenziellen Kollisionen zu verarbeiten.
Ich habe die Antwort aktualisiert, um Strategien für den Umgang mit Kollisionen aufzunehmen.
MichaelHouse
das ist falsch. Es ist bekannt, dass die Euler-Integration für konstante Integrationen abweicht, während Verlet (oder RK2, RK4) dies nicht tut.
v.oddou
@ v.oddou Angesichts der Tatsache, dass diese Simulationen für Spiele gedacht sind, halte ich die von Ihnen benötigte Genauigkeit nicht für erforderlich. Die zusätzliche Komplexität und Schwierigkeit, Kollisionen für Verlet hinzuzufügen, macht die Euler-Integration zu einer überlegenen Wahl.
MichaelHouse
2
Nehmen wir ein Beispiel mit der Schwerkraft.
Nehmen wir in der folgenden Funktion an, dass wir Klassenmitgliedsvariablen für Position und Geschwindigkeit haben. Wir müssen sie aufgrund der Schwerkraft alle dt Sekunden aktualisieren.
void update(float dt ){
acceleration = G * m / r^2;
velocity = velocity + acceleration * dt;
position = position + velocity * dt;}
Wenn dtunsere Simulation immer kleiner wird, wird sie immer genauer (wenn sie jedoch dtzu klein wird, können beim Hinzufügen kleiner Zahlen zu großen Zahlen Präzisionsfehler auftreten).
Grundsätzlich müssen Sie das Maximum dtfestlegen , das Ihre Simulation verarbeiten kann, um ausreichend gute Ergebnisse zu erzielen. Und wenn das dt, was hereinkommt, zu groß ist, teilen Sie die Simulation einfach in kleinere Schritte auf, wobei jeder Schritt das Maximum ist dt, das Sie zulassen.
void update(float dt ){
acceleration = G * m / r^2;
velocity = velocity + acceleration * dt;
position = position + velocity * dt;}// this is the function we call. The above function is a helper to this function.void updateLargeDt(float dt ){constfloat timeStep =0.1;while( dt > timeStep ){
update( timeStep );
dt -= timeStep ;}
update( dt );// update with whatever dt is left over from above}
Mit dieser Strategie können Sie sich also einfach timeStep auf die gewünschte Wiedergabetreue einstellen (machen Sie eine Sekunde, Minute, Stunde oder was auch immer erforderlich ist, um eine genaue Darstellung der Physik zu erhalten.
Die meisten Spiele tendieren dazu, die einfache Euler- Methode der Vorwärtsintegration zu verwenden (dh die Geschwindigkeit in die Position über die Zeit zu integrieren und die Beschleunigung in die Geschwindigkeit zu integrieren). Leider ist die Euler-Methode nur für sehr kleine Zeiträume und kurze Auflagen geeignet.
Es gibt komplexere Methoden, die über sehr lange Zeiträume genauer sind. Das beliebteste und am einfachsten zu implementierende ist vielleicht Runge-Kutte-4 . RK4 bestimmt die Position in der Zukunft, indem vier Positionen und Geschwindigkeiten in der Vergangenheit abgetastet und interpoliert werden. Es ist in längeren Zeiträumen tendenziell viel genauer als die Euler-Methode, ist jedoch rechenintensiver.
Wenn Sie beispielsweise die Physik eines realen umlaufenden Planeten berechnen möchten, der alle paar Tage in Echtzeit aktualisiert wird, bewirkt die Euler-Methode, dass der Planet aufgrund numerischer Fehler bereits nach wenigen Umlaufbahnen in den Weltraum schießt. RK4 hält den Planeten im Allgemeinen viele tausend Mal in ungefähr derselben Form, bevor zu viele Fehler akkumuliert werden.
Die Implementierung von Kollisionen in RK4 kann jedoch sehr schwierig sein ...
Antworten:
Sie werden wahrscheinlich für diese großen Zeitspannen eine konstante Beschleunigung verwenden (dies kann eine Beschleunigung von Null sein). Die Ableitung der konstanten Beschleunigung in Bezug auf die Zeit ist 0. Das bedeutet, dass sie sich in Bezug auf die Zeit nicht ändert, sodass es keine Rolle spielt, wie groß Ihre Deltazeit ist.
Diese kleine zeitliche Integration liefert die Gleichungen, die Sie benötigen.
Wobei: a = Beschleunigung, v = Geschwindigkeit, v0 = Anfangsgeschwindigkeit, s = Position, s0 = Anfangsposition, t = Zeit
Mit dieser Strategie können Sie Zeiträume von Millisekunden bis Wochen verwenden, wenn Sie möchten. Ihre Kombination würde in den
v0
unds0
Parametern der Gleichung berücksichtigt.Um Kollisionen zu behandeln, müssen Sie Strategien implementieren , die denen für kleine Hochgeschwindigkeitsobjekte ähneln . Berechnen Sie zuerst die neue Position mit der obigen Gleichung und wechseln Sie dann für alle Objekte zwischen der alten und der neuen Position. Da sich jedes dieser Objekte (Minuten oder Tage zuvor) geschnitten haben könnte, kann dies sehr komplex werden. Da Sie so große Deltazeiten haben, haben Sie wahrscheinlich genügend Zeit, um diese potenziellen Kollisionen zu verarbeiten.
quelle
Nehmen wir ein Beispiel mit der Schwerkraft.
Nehmen wir in der folgenden Funktion an, dass wir Klassenmitgliedsvariablen für Position und Geschwindigkeit haben. Wir müssen sie aufgrund der Schwerkraft alle dt Sekunden aktualisieren.
Wenn
dt
unsere Simulation immer kleiner wird, wird sie immer genauer (wenn sie jedochdt
zu klein wird, können beim Hinzufügen kleiner Zahlen zu großen Zahlen Präzisionsfehler auftreten).Grundsätzlich müssen Sie das Maximum
dt
festlegen , das Ihre Simulation verarbeiten kann, um ausreichend gute Ergebnisse zu erzielen. Und wenn dasdt
, was hereinkommt, zu groß ist, teilen Sie die Simulation einfach in kleinere Schritte auf, wobei jeder Schritt das Maximum istdt
, das Sie zulassen.Mit dieser Strategie können Sie sich also einfach
timeStep
auf die gewünschte Wiedergabetreue einstellen (machen Sie eine Sekunde, Minute, Stunde oder was auch immer erforderlich ist, um eine genaue Darstellung der Physik zu erhalten.quelle
Die meisten Spiele tendieren dazu, die einfache Euler- Methode der Vorwärtsintegration zu verwenden (dh die Geschwindigkeit in die Position über die Zeit zu integrieren und die Beschleunigung in die Geschwindigkeit zu integrieren). Leider ist die Euler-Methode nur für sehr kleine Zeiträume und kurze Auflagen geeignet.
Es gibt komplexere Methoden, die über sehr lange Zeiträume genauer sind. Das beliebteste und am einfachsten zu implementierende ist vielleicht Runge-Kutte-4 . RK4 bestimmt die Position in der Zukunft, indem vier Positionen und Geschwindigkeiten in der Vergangenheit abgetastet und interpoliert werden. Es ist in längeren Zeiträumen tendenziell viel genauer als die Euler-Methode, ist jedoch rechenintensiver.
Wenn Sie beispielsweise die Physik eines realen umlaufenden Planeten berechnen möchten, der alle paar Tage in Echtzeit aktualisiert wird, bewirkt die Euler-Methode, dass der Planet aufgrund numerischer Fehler bereits nach wenigen Umlaufbahnen in den Weltraum schießt. RK4 hält den Planeten im Allgemeinen viele tausend Mal in ungefähr derselben Form, bevor zu viele Fehler akkumuliert werden.
Die Implementierung von Kollisionen in RK4 kann jedoch sehr schwierig sein ...
quelle