Schnee

Beispiel

Visual Studio Projekt herunterladen

Als einfaches System, das Vektoren und ein physikalisches Bewegungmodell verwendet, hier ein Beispiel für Schnee. Für die Massepunkte dieses Beispiels arbeiten wir mit einem Feld von Partikeln.

Vektoren

Wir verwenden hier eine einfache Vektorenklasse (vertex.h und vertex.cpp). Die Klasse enthält öffentlich zugängliche x, y und z Koordinaten sowie Methoden zur Vektoraddition, Subtraktion, Skalarmultiplikation und einer Längenberechnung nach Pythagoras.

Neben dem Standardkonstruktor gibt es einen Konstruktor, der drei Koordinaten zur Initialisierung als Parameter annimmt. Man nennt dies ein Überladen des Konstruktors, d.h. es existieren mehrere Funktionen mit demselben Namen aber unterschiedlichen Parametern bzw. Rückgabewerten. Wir kommen in der Stunde über Vererbung und Polymorphie noch genauer darauf zu sprechen.

In den nächsten Beispielen wird diese Klasse verfeinert und wesentlich eleganter implementiert werden.

Partikel

In particle.h und particle.cpp befindet sich eine einfache Partikelklasse. Ein Partikel ist hier eher als Datenstruktur zu verstehen, da außer Standardkonstruktor und Destruktor keine Methoden vorkommen. Vorerst werden alle Berechnungen in der Datei main.cpp durchgeführt. In den folgenden Beispielen werden auch hier intelligentere Funktionen hinzukommen.

Die Variable isVisible bestimmt, ob das Partikel sichtbar ist. Darüber hinaus besitzt jedes Partikel eine gewisse Lebensenergie. Position und Geschwindigkeit sind die einzigen Parameter, die wir in diesem Beispiel zur Simulation von fallendem Schnee benötigen.

Initialisierung

In der Datei main.cpp gibt es gegenüber den vorherigen Beispielen wenige Änderungen. Ganz oben in der Datei wird unser Partikelfeld als einfaches Array deklariert. Darunter gibt es eine Funktion zur Berechnung von zufälligen Werten in einem Bereich zwischen min und max.

In der main-Funktion werden alle Partikel unsichtbar gemacht und erhalten eine zufällige Lebensenergie. Ist diese Energie abgelaufen (Funktion update), so wird das Partikel neu initialisiert (Funktion initParticle), sichtbar, und erhält volle Lebensenergie. Ganz unten in der update Funktion wird jedem Patrikel Lebensenergie abgezogen.

Das alles hat zur Folge, dass der Schnee gleichmäßig anfängt zu schneien und die Partikel jedes Mal, wenn sie unterhalb des sichtbaren Bildausschnitts liegen, als neues Partikel nach oben gesetzt werden.

Mechanik

Das Kernstück unserer Simulation ist die Gleichung darunter, in der die Partikel bewegt werden. Wir lösen hiermit näherungsweise folgendes Problem: Die Geschwindigkeit ist die erste Ableitung der Position nach der Zeit (je schneller sich die Position ändert, desto höher ist die Geschwindigkeit), also v = dx/dt mit dx = Änderung der Position, dt = Änderung der Zeit.

Wir haben für jedes Partikel eine aktuelle Position x0 und eine aktuelle Geschwindigkeit v gegeben. Um die nächste Position x1 zu berechnen, lösen wir die Gleichung nach dx auf: dx = v*dt und damit x1 = x0 + dx = x0 + v*dt.

Das sieht recht schön aus, kann sich aber als eine schlechte numerische Näherung erweisen. v*dt ist eigentlich ein Integral. Ersetzen wir unser dt durch eine sechzigstel Sekunde und multiplizieren es mit unserer aktuellen Geschwindigkeit v ist die Lösung nur korrekt, wenn die Geschwindigkeit sich in dieser sechzigstel Sekunde nicht ändern würde. Für die Illusion von fallendem Schnee reicht diese Näherung voll und ganz.

Transformation

Die Funktion glutPostRedisplay() haben wir in die idle-Funtkion verschoben. GLUT ruft diese Funktion jedes Mal auf, wenn sonst nichts zu tun ist.

Um die korrekte Position und den korrekten Öffnungswinkel für unsere Kamera in der Funktion transform zu erhalten, wollen wir dieses Mal etwas rechnen (siehe Bild). Diese Berechnung wird uns in den folgenden, interaktiven Beispielen wiederbegegnen.

Der Schnee wird auf der y-Achse im Bereich von 1 bis -1 niedergehen. Die Kamera steht am Punkt (0,0,2) mit Blick auf den Ursprung (0,0,0) des rechtshändigen OpenGL-Koordinatensystems. Die y-Achse (0,1,0) zeigt nach oben.

Berechnung des Field of View

Da die Länge 1 auf der y-Achse dem Sinus des eingezeichneten Winkels entspricht, die Länge 2 auf der z-Achse dem Cosinus, ergibt sich der vertikale Öffnungswinkel fov (field of view) also aus:

    GLdouble fieldOfView = atan(1.0/2.0)*2.0*180.0/PI;

Dies beinhaltet schon die Umrechnung von Radian in Grad also grad=radian*180.0/PI. Der Öffnungswinkel entspricht in etwa den 53 Grad der letzten Beispiele.

Selbständige Programmierung
  • Lasst den Schnee leicht auf die Kamera zu treiben
  • Programmiert das Beispiel um, so dass eine Sternenflugsimulation entsteht

zurück