2017-05-14 11 views
1

Ich schreibe einen Partikelsimulator in C++.Framerate unabhängige Beschleunigung/Verzögerung?

Ich bewege Partikel durch Hinzufügen ihrer Geschwindigkeit zu ihrer Position bei jedem Zeitschritt.

Der Wert des Zeitschritts ist ein Prozentsatz des aktuellen Rahmens. Der Vollbildzeitschritt ist also 1, der Halbbildzeitschritt ist 0,5, der Viertelbildzeitschritt ist 0,25 usw. Die gesamten Simulationsschritte sind frameCount/timeStep ... also je kleiner der Zeitschritt ist, desto größer ist die Gesamtzahl Schritte simuliert.

Grundlegende Bewegung über Zeitschritte hinweg ist das gleiche sehr einfach. Die Gleichung lautet:

position = position + velocity * timeStep; //10 full frames later, end position is always the same 

es aber für mein gegenwärtiges Verständnis von Mathematik zu kompliziert wird, wenn ich versuche, zu der Geschwindigkeit im Laufe der Zeit zu ändern. Zum Beispiel, wenn ich dies tue:

velocity = velocity * .95f; 
position = position + velocity * timeStep; //10 full frames later, end position dependent on time step 

Die Ergebnisse über verschiedene Zeitschritte sind nicht mehr die gleichen. Ich weiß, das ist, weil, wenn ich die Gesamtanzahl von Schritten vergrößere, die durch Verringern des Zeitschritts berechnet werden, nehme ich auch die Geschwindigkeit viel öfter ab, was einen großen Einfluss auf die Endposition des Partikels haben wird.

Wie kann ich die Geschwindigkeit über die Zeit so ändern, dass ich identische Ergebnisse über verschiedene Zeitschritte bekomme?

Antwort

2

Geschwindigkeit ist Positionsänderung über die Zeit. Sie haben das in Ihrer Gleichung richtig berechnet.

position = position + velocity * timeStep; 

Beschleunigung ist die Änderung der Geschwindigkeit im Laufe der Zeit. Sie verwenden also nur die gleiche Gleichung, aber ändern Sie die Variablen entsprechend. Das heißt, Position zu Geschwindigkeit und Geschwindigkeit zu Beschleunigung ändern. Der Zeitschritt bleibt gleich.

velocity = velocity + acceleration * timeStep; 

Wenn Sie die Reibung simulieren wollen, dann, was Sie tun, ist die Geschwindigkeit durch einen konstanten Reibungswert und der Zeitschritt, multiplizieren und dies von der Beschleunigung subtrahieren. Dieser Wert sollte jedoch nur für den Frame verwendet werden und nicht im tatsächlichen Beschleunigungswert gespeichert werden.

float temp_accel = acceleration - friction * velocity * timeStep; 

Dann ändern Sie Ihre Geschwindigkeit nach Temp_accel.

velocity = velocity + temp_accel * timeStep; 

Wenn Ihre Beschleunigung Null ist, dann kann man das aus der Gleichung nehmen:

float temp_accel = -friction * velocity * timeStep; 
+0

Hmm, wie kann ich herausfinden, wie hoch der Beschleunigungswert in Ihrer Funktion sein sollte, ausgehend von meiner anfänglichen (De) Beschleunigungsformel von (velocity * = .95)? – Tyson

+0

@Tyson: Das ist keine Verzögerungsformel. Also gibt es keinen richtigen Weg, um es in eine Verzögerung zu übersetzen. Ich würde empfehlen, mit Zahlen herumzuspielen, bis Sie einen Wert bekommen, der richtig aussieht und sich anfühlt. –

+0

Ist es nicht? Es beschreibt eine Änderung der Geschwindigkeit über die Zeit, nämlich eine Abnahme. Ich glaube, ich habe eher auf eine mathematische Lösung gehofft als auf eine Lösung, die 'wackelt, bis es funktioniert'. – Tyson

0

Die akzeptierte Antwort ist gut, aber ich möchte betonen, dass Sie nie vollständig unabhängig sein kann der Schrittgröße der Simulation.

Die Bewegungsgleichungen (die uns zu einem bestimmten Zeitpunkt Position und Geschwindigkeit geben) sind Integrale. Simulationen nähern die Integration an, indem sie über kleine Schritte Summen ausführen. Aber weil diese Schritte endlich und nicht unendlich klein sind, gibt es immer Fehler. Je kleiner Sie die Schritte ausführen können, desto mehr können Sie den Fehler reduzieren.Für Videospiele und UI-Animationen reichen Zeitschritte in der Größenordnung der Bildrate, z. B. 10-100 Schritte pro Sekunde, normalerweise aus, um den Fehler so klein zu halten, dass er das Aussehen der Animation nicht beeinträchtigt oder die Spielbarkeit eines Spiels.

Wenn Sie jedoch die gleiche Simulation sowohl mit 10 als auch mit 100 Schritten pro Sekunde ausführen, können Sie unterschiedliche Ergebnisse erzielen, da das letztere eine bessere Annäherung als das erstere darstellt.

Wenn Sie die Schritte verkleinern, erhöht sich auch der Rechenaufwand. Manchmal haben Sie nicht genug PS, um Schritte zu verwenden, die klein genug sind, um den Fehler im Rahmen zu halten. Unter diesen Umständen gibt es numerische Integratoren, die bessere Annäherungen ergeben als wiederholte Summen. Der wohl bekannteste numerische Integrator ist Runge-Kutta (RK4). Wenn Sie feststellen, dass Sie timeStep unpraktisch klein einstellen müssen, versuchen Sie es mit RK4.