Klassen- und Funktionsbeschreibung
Einführende Beschreibung des Programms :
Basisklassen bilden die Vektorklasse und die Fischklasse. Die Vektorklasse ist dabei natürlich die Grundlage für
alle Operationen der benötigten Vektoren. Von der Fischklasse (sie selbst wird nicht instanziert) werden die
übrigen Fischarten (Schwarmfisch1, Schwarmfisch2 und Raubfisch) abgeleitet. Diese Klassen erben die grundlegenden
Methoden und erweitern diese um ensprechende Funktionalitäten. Die Gegenstände und das Aquarium selbst bilden
jeweils eigene Klassen. Als Gegenstände wurden Steine und Wasserpflanzen modelliert. Ein Klassendiagramm ist in der
Dokumentation enthalten.
Der Echtzeitcharakter der Simulation wird dadurch erreicht, dass die "Neuzeichenfunktion" von OpenGl (glutPostRedisplay())
zyklisch aufgerufen wird und dabei den aktuellen Stand aller Objekte neu darstellt. Dieser zyklische Aufruf wird innerhalb
der berechne()-Funktion durch die von OpenGl bereitgestellte Funktion glutTimerFunc() realisiert. Die Berechnung der neuen
Koordinaten der Fische erfolgt in der Routine simufunc(), welche während eines Aufrufs mehrere Wegpunkte berechnet, um
so eine feinere Granularität zu erhalten.
Die Initialisierung der OpenGl-Parameter wird in init() vorgenommen, welche ebenso wie der Fensteraufbau aus der main() heraus
angestossen wird.
Detailierte Beschreibung der erstellten Klassen :
Die Klasse : vector (MyVector.h/.c)
Die Vektorklasse stellt die üblichen Operatoren sowie u.a. die Methoden Skalarprodukt, Kreuzprodukt, Betrag, Normalisierung,
Abstand und Ausgabe zur Verfügung.
Die Klasse : Fisch (MyFisch1.h/.c)
Die Fisch-Basisklasse stellt die Methoden zur Verfügung, die auch von allen anderen Fischarten benötigt werden.
Neben der Bestimmung der Beschleunigung, der Geschwindigkeit und der Position des Fisches werden folgende Kraftkomponenten
berechnet :
- berechne_F_v : sorgt dafür, dass der Fisch mit seiner bevorzugten Geschwindigkeit schwimmt.
- berechne_F_aqu : diese Kraft sorgt dafür, dass der Fisch sich innerhalb des Aquariums aufhält. D.h.
die Aquariumseiten und die Wasseroberfläche bilden eine Art Potentialfläche, von der der Fisch je nach
Abstand und Winkel eine abstossende Kraft erfährt.
- berechne_F_geg : berechnet ähnlich wie oben die abstossende Kraft von Gegenständen, sodass die Fische den
Steinen und Wasserpflanzen ausweichen. Die Fische behalten dabei, je nach Winkel zwischen ihrer Bewegungsrichtung und dem Vektor
von ihrem Mittelpunkt zu dem Objektmittelpunkt ihre Richtung weitestgehend bei.
Zusätzlich existieren noch zwei Funktionen (init_afeld und berechene_Abstand) die auf einem Feld operieren, das die
Abstände der nähesten Fische speichert. Während init_afeld die Initialisierung vornimmt, füllt
berechene_Abstand dieses mit den Positionen der Fische, die aktuell die kürzeste Entfernung zu dem aufrufenden Fisch
haben.
Die Klasse : S_Fisch1 (MyFisch1.h/.c)
Die Klasse S_Fisch1 ist abgeleitet von Fisch und wird mit folgenden Methoden erweitert :
- berechne_F : diese Methode setzt das Schwarmverhalten der Fische um und nutzt dabei das Feld a_feld. Die Positionen
der darin gespeicherten Fische werden gemittelt. Damit erhält man einen Punkt auf den sich die Kraftkomponente richtet.
Fische finden so zu einem Schwarm zusammen. Zudem wird dafür gesorgt, dass die Fische untereinander einen Mindestabstand
halten.
- berechene_F_zpos : führt den Fisch zu einer zufällig gewählten Zielposition. Ist diese mit einem gewissen
Toleranzbereich erreicht wird wieder zufällig ein neue Zielposition vorgegeben.
- berechne_F_gefahr : mit Hilfe dieser Methode beschleunigt der Fisch und ändert gleichzeitig seine Bewegungsrichtung,
sobald ein Raubfisch in seiner Nähe ist.
- zeichne_dich : Mittels OpenGl Befehlen wird ein Modell der Fischarten gezeichnet und mit entsprechenden Transformationen
in die aktuelle Position (unter Berücksichtigung der Bewegungsrichtung) gebracht. Ein Parameter bestimmt dabei die
Größe und die Farbe des Fischmodells und simuliert somit die einzelnen Fischarten.
Die Klasse : S_Fisch2 (MyFisch2.h/.c)
Die Klasse S_Fisch1 ist abgeleitet von S_Fisch1 und wird mit folgenden Methoden erweitert :
- berechne_F_slow : der Fisch verringert sein Geschwindigkeit, wenn Raubfische ausserhalb eines gewissen Radiuses sind.
Befindet sich ein Raubfisch in einem Toleranzbereich behält er seine Geschwindigkeit bei. Sobald der Raubfisch jedoch
den Toleranzabstand unterschreitet verhält sich der Fisch wie bei berechne_F_gefahr.
- berechne_F_slow : Variante von berechne_F_slow, falls keine Raubfische existieren. Der Fisch verringert seine
Geschwindigkeit.
Die Klasse : Raubfisch (MyFisch2.h/.c)
Die Klasse Raubfisch ist abgeleitet von Fisch und wird mit folgenden Methoden erweitert :
- berechne_F : hier wird wieder auf Basis des Feldes a_feld die Kraft berechnet um den Fisch mit der geringsten
Entfernung zu dem Raubfisch zu jagen. Ebenfalls wird dafür gesorgt, dass sich die Raubfische nicht zu nah kommen.
Die Klasse : Stein (Gegenstand.h/.c)
Diese Klasse beinhaltet Methoden zur Rückgabe der Position und des Radiuses sowie die zeichne_dich Funktion, in der
mittels OpenGL Kommandos ein Stein modelliert wird.
Die Klasse : Wasserpflanze (Gegenstand.h/.c)
Die Klasse Wasserpflanze ist abgeleitet von Stein. Sie überschreibt lediglich deren zeichne_dich Funktion.
Beschreibung der wichtigsten Funktionen :
Die Funktion : main() (SimuMain.c)
ist die Ausgangsfunktion. Hier werden die Fenster (Simulation und Parameterauswahl und der Darstellungsmodus definiert
sowie die wichtigsten OpenGL Basisfunktionen aufgerufen. Unter anderem wird z.B. festgelegt welche Funktion die
Tastatureingaben (→keyboard()) regelt, welche Funktion für die Darstellung (→display()) zuständig ist
und welche Funktion bei Veränderung der Fenstergröße (→reshape()) aufgerufen wird.
Die Funktion : init() (Init.h/.c)
legt die wichtigsten OpenGL Parameter fest. Hier wird der Tiefenpuffer, das Licht- sowie das Schattenmodell definiert.
Die Funktion : berechne() (SimuMain.c)
regelt die zyklische Erneuerung des dargestellten Simulationsbildes (→display()) und stößt die Berechnung
(→simufunc()) der Simulationsschritte an. Dadurch erhält die Animation ihren Echtzeitcharakter.
Die Funktion : display() (Init.h/.c)
zeichnet das Aquarium, alle Fische (Schwarmfischart 1 und 2 sowie die Raubfische), die Steine und die Wasserpflanzen.
Die Funktion : simufunc() (Init.h/.c)
führt die Berechnung der einzelnen Simulationsschritte durch. Dabei wird für jeden Fisch die auf ihn wirkende Kraft
berechnet. Diese setzt sich aus mehreren Komponenten zusammen. Einflußgrößen sind : das Aquarium, Fische gleicher
Art (→Schwarmbildung, sowie Einhaltung eines gewissen Abstandes zueinander), Schwarmfische der anderen Art, die Gegenstände,
die Raubfische, die Lieblingsgeschwindigkeit sowie die aktuelle Zielposition. Bei den Raubfischen wirkt noch zusätzlich der
zu jagende Fisch in die Kraftberechnung mit ein. Aus der resultierenden Kraft wird anschliessend die neue Beschleunigung, die
neue Geschwindigkeit und die neue Position des Fische berechnet.
Die Funktion : reshape() (SimuMain.c)
legt den sichtbaren Bereich innerhalb des Fensters, den Bildausschnitt der Simulation und die Kameraposition (d.h. die Stelle
von der aus die Simulation betrachtet wird) fest.
|