Wurm

Beispiel

Visual Studio Projekt herunterladen

In diesem schon recht anspruchsvollen, interaktiven Beispiel verwenden wir ein erweitertes physikalisches Bewegungsmodell, das die Beschleunigung eines Punktes explizit modelliert. Für die Massepunkte arbeiten wir wieder mit einem Feld von Partikeln bzw. Knoten, deren Anzahl konstant bleibt.

CVertex

Die 3D-Vektorenklasse in vertex.h und vertex.cpp ist eine stark erweiterte Version der 2D-Vektoren aus der vorherigen Lektion. Sie macht ausgiebig Gebrauch von überladenen Operatoren. Alle Methoden sind aus Geschwindigkeitsgründen inline ausgeführt. Aus demselben Grund sind die Attribute x, y und z auch öffentlich.

CParticle

Die "Partikel" bzw. Kettenglieder in particle.h und particle.cpp besitzen verschiedene Methoden zur Manipulation von Position, Geschwindigkeit und Beschleunigung. Ich möchte hier nur auf zwei Funtkionen eingehen.

accelerateTowards beschleunigt den Partikel auf ein Ziel zu. Dabei wird die Richtung zum Ziel d-p normiert zu |d-p| (siehe Bild) und danach noch mit einem Faktor skaliert. Das bedeutet, der Partikel wird mit einem konstanten Faktor zum Ziel hin beschleunigt, egal wie weit entfernt er davon ist.

Auf einen Punkt zu beschleunigen

Damit schießt er aufgrund seiner Trägkeit zwangsläufig über das Ziel hinaus und es entstehen die Verwirblungen, die im Kopf des Wurms zu sehen sind.

update enthält ein erweitertes Bewegungsmodell. Hier berechnen wir jetzt nicht nur x = x + v*dt, sondern vorher v = v + a*dt mit der Beschleunigung (acceleration a) und Geschwindigkeit v (velocity). Danach ziehen wir von der Geschwindigkeit wieder einen gewissen Faktor für den Luftwiderstand ab.

Die Beschleunigung wird in jedem Frame durch Addition verschiedener Kräfte neu bestimmt, deshalb wird sie am Ende der update-Methode mit Null initialisiert.

main

In der Funktion update der Datei main.cpp wird die Simulation jeweils um ein Bild weiterbewegt. Hier liegt auch die Grundlogik des Systems verborgen. Das erste Partikel wählen wir als Kopf des Wurms. Es steuert auf die aktuelle Mausposition zu. Die restlichen Glieder in unsere Kette steuern jeweils auf ein Glied weiter vorne in der Kette zu. Dadurch ergibt sich optisch ein Wurm (oder eine Schlange). Die letzte Kraft, die auf die Kettenglieder wirkt, ist eine Art Schwerkraft oder Wind in Richtung der Kamera.

Interaktion

Für eine direkte Interaktion greifen wir in der Funktion motion die aktuelle Position der Maus ab und wandeln sie in den Bereich [-0.5, 0.5] auf der y-Achse um. Auf der x-Achse tun wir dasselbe, nur um das Seitenverhältnis des Fensters skaliert.

Da die y-Koordinate des Fenster-Koordinatensystems nach unten zeigt, und die unseres OpenGL 3D-Koordinatensystems aber nach oben, invertieren wir den y-Wert der Maus.

Um die korrekte Position und den korrekten Öffnungswinkel für unsere Kamera zu erhalten, nehmen wir denselben Öffnungswinkel, wie im Schnee-Beispiel. Wir positionieren die Kamera allerdings auf den Punkt (0,0,1), so dass wir die y-Achse genau von -0.5 bis 0.5 (unseren Mauskoordinaten) sehen.

Bewegen wir den Kopf auf die so berechneten Mauskoordinaten der (x,y)-Ebene zu, stimmt sein Ziel genau mit der Mausposition überein.

Selbständige Programmierung
  • Erzeuge Header- und C++-Dateien für eine eigene Simulationsklasse CWorm und verschiebe alle Parameter der Simulation dort hinein. Verwende dann die Simulation in der Datei main.cpp.
  • Überlege dir eine eigene Simulation und breche dazu ggf. die Verkettung der Partikel zu einem Wurm auf. Gäbe es eine Möglichkeit, häufiger verwendete Funktionen oder Parameter der Simulationen in einer Oberklasse CParticleSimulation zu vereinen?
  • Wie wäre es z.B., wenn man der Oberklasse in einer Methode die Anzahl der Partikel übergeben würde und diese dynamisch Speicher belegt? Das Freigeben des alten Feldes nicht vergessen...

zurück