Sie sind auf Seite 1von 11

D3D-Pendulum

Johannes Fackler

Gliederung

1. berblick
2. Frontend (Graphical User Interface)
1. Bereitgestellte Funktionen
2. Einstellungsmglichkeiten
3. Anwendung

3. Backend
1. berblick
2. Physikberechnung
3. Grafikdarstellung ber Direct3D
1. Initialisierung
2. Generelle Funktonsweise
3. Die Render()-Funktion
4. Grafikdarstellung ber System.Drawings
5. Maussteuerung des Pendels

4. Geschwindigkeitsoptimierung
1. Multithreading
2. Graphen und zugehrige Arrays

5. Exception Prevention
1. Benutzereingaben absichern
2. Zu verhindernde BufferOverflow-Zustnde

6. Abschluss

1. Ein erster berblick


Im Rahmen unserer Informatik-Veranstaltung ist nun dieses Programm entlang der allgemeinen
Vorgaben entstanden. Der vorgegebene Rahmen sah eine in Visual Basic .NET geschriebene
Pendelsimulation mit grafischer Darstellung, mehreren Windows Forms und individuellen,
programmseitig abgesicherten Benutzereingaben zur Vernderung des Pendels und seiner
Umgebungsbedingungen vor. Diese Anforderungen stellen das Grundgerst dar, bei Ausarbeitung
wurden allerdings auch neue Schwerpunkte gesetzt. Dazu zhlen:

Dreidimensionale Darstellung, hardwarebeschleunigt ber DirectX.Direct3D

Geschwindigkeitsoptimierte Funktionen

mglichst klare und bersichtliche Darstellung im Einklang mit ausreichenden


Konfigurationsmglichkeiten.

Der Groteil der Arbeit bestand darin, die 3D-Schnittstelle stabil zu initialisieren und erste Objekte
zu laden. Die restlichen Berechnungen wie Transformationen sowie Licht- und Farbverwaltung
werden hauptschlich von DirectX erledigt. Beim Thema Geschwindigkeitsoptimierung musste
immer wieder abgewogen werden zwischen

Geschwindigkeit

Sicherheit

Komfort

Beeintrchtigung anderer Funktionen,

was oft die Rckbesinnung auf die eigentlichen Ziele erforderte. Doch nun zum Look and Feel des
Programms:

2. Frontend
2.1 Bereitgestellte Funktionen
Wird das Programm gestartet, ist zuerst nur das Hauptfenster zu sehen. Ist Direct3D initialisiert und
das Pendel geladen, sind alle graphischen Elemente auf einen Blick sichtbar: Das Pendel und die
drei Graphen fr Winkel, -geschwindigkeit und -beschleunigung. Grundlegende Einstellungs- und
Steuerungsmglichkeiten sind hier auch untergebracht, zusammen mit einer bersicht ber aktuelle
Einstellungen der (noch nicht gestarteten) Simulation. Um Simulationswerte zu ndern, kann man
durch einen Klick auf den Randbed.-Button das zugehrige Fenster aufrufen oder, sollte es schon
sichtbar sein, in den Vordergrund holen.

2.2 Einstellungsmglichkeiten
Dieses Fenster ist thematisch in zwei Bereiche unterteilt: Einstellungen am Versuchsobjekt, dem
Pendel, und Einstellungen fr Umgebungsbedingungen. Die Einstellungen werden ber
NumericUpDown-Objekte vorgenommen, was die Vorteile einer einfachen Bedienung,
einheitlichen Gestalt und zugleich sicheren Eingabe vereint. Minimal- und Maximalwerte sind auf
den jeweiligen Wert angepasst, so kann beim Startwinkel zum Beispiel zwischen und + PI (3,141)

jede Zahl auf drei Stellen hinter dem Komma genau festgelegt werden Werte auerhalb von PI
sind unntig und knnen, bei extrem groen Zahlen, Variablen zum berlaufen bringen.
Die Einstellungen der Umwelt sind weniger umfangreich, haben aber teils recht deutliche Effekte
und sind mit den Pendelvariablen eng verknpft: So ist der Kugelradius am Pendel einzig zur
Berechnung der Reibkraft ntig, die auch groteils mit der Viskositt des umgebenden Mediums
zusammenhngt. Um die Dimensionen der einzustellenden physikalischen Werte besser vorstellbar
zu machen, sind statt der Beschriftung Auswahlfelder platziert, die realistische Voreinstellungen
beinhalten, so sind die Fallbeschleunigungen aller Planeten sowie die Viskositten von
verschiedenen Gasen und Flssigkeiten, z.Bsp. Luft, Wasserstoff, Wasser und als Extremfall
Glycerin durch einfaches Auswhlen verfgbar und werden gleich in das NumericUpDown-Feld
eingetragen. Auch im Hauptfenster wird dann nicht der Zahlenwert, sondern das dazugehrige
Element angezeigt, um die physikalischen Gegebenheiten besser darzustellen.

2.3 Anwendung
Durch den Button Laufende Simulation ndern werden alle Werte auer Winkel und
Geschwindigkeit in die Simulation geladen. Dies bedeutet fr das Pendel, dass es seinen Zustand
behlt, aber augenblicklich mit neuen Attributen in einer anderen Umwelt platziert ist. Ist die
Simulation noch nicht gestartet, wird die Physikberechnung auch nicht anlaufen, um noch weitere
Einstellungen zu ermglichen. Sind diese getan, kann der Physik-Timer und damit die Simulation
mit einfachen Klicks gestartet, pausiert, fortgesetzt oder beendet werden. Whrenddessen kann man
graphische Einstellungen wie die Anzeige aller Simulationsdaten oder die Pendelfarben ndern.
ber ein DropDown-Men kann die Abtastraten der Graphen verndert werden. Dies stellt sicher,
dass sowohl sehr schnelle als auch sehr langsame Schwingungen optimal dargestellt werden. Diese
Einstellung kann bewusst nicht fr jeden Plotter einzeln eingestellt werden, um die
bereinanderstellung von Auslenkung, Geschwindigkeit und Beschleunigung nicht durcheinander
zu bringen.
Wie oben beschrieben kann man noch die Umgebungsbedingungen ndern.

3. Backend
3.1 berblick
Die Berechnungen im Hintergrund sind hauptschlich in drei Bereiche gegliedert:
Physik-Timer: 100 mal in der Sekunde wird die Beschleunigung aus der aktuellen Auslenkung und
den anderen Faktoren wie Strmungswiderstand berechnet und ein Integrationsschritt zur
Geschwindigkeit addiert. Die Berechnung der neuen Auslenkung schliet diesen einfachen Teil ab.
Graphen: Die folgenden Anweisungen in der Funktion des Physik-Timers sind fr die Datenplotter
wichtig: Der neue Integrationsschritt wird verarbeitet, in Pixeldaten umgerechnet und, je nach
Einstellung, der Zoom angepasst.
Direct3D-Darstellung: Abgegrenzt dazu luft die Render-Funktion der 3D-Darstellung in einem
eigenen Thread, um die Kapazitten moderner multicore-CPUs voll auszunutzen. Die Funktion in
der Main-Klasse ruft nur die Methoden der engine-Klasse auf, die spter separat behandelt werden.

3.2 Physik-Berechnung
Da sich der Groteil der Entwicklungszeit auf die Geschwindigkeitsoptimierung (im Sinne von
Graphik-Hardwarebeschleunigung und Schleifenbereinigung) konzentriert hat, wurde die
rudimentre Art der Physikberechnung nicht weiter verbessert in der Hoffnung, durch
beschleunigten Code und damit krzere Iterationsintervalle den Fehler klein zu halten.

3.3 Grafikdarstellung ber Direct3D


3.3.1 Initialisierung
Das grte Manko und gleichzeitig die grte Strke von Microsofts 3D-Bibliothek liegt bei den
Systemvoraussetzungen. Direct3D und seine Unterklassen schaffen eine relativ einfache und
komfortable Umgebung zur direkten Ansteuerung der Graphikkarte, was enorme
Geschwindigkeitsvorteile und eine starke Reduktion der CPU-Last mit sich bringt. Durch genau
diese Schnittstelle sind allerdings auch Probleme und Grenzen gegeben: Will man eine Funktion der
Graphikkarte nutzen, sollte diese auch von der entsprechenden Hardware untersttzt werden. Da wir
aber nicht in Zeiten leben, in denen es nur einen Kartentyp gibt, sondern eine Flle von
unterschiedlichen Bauteilen in allen Preisklassen und Funktionsumfngen besteht, ist es ntig, sich
ber die Fhigkeiten der verfgbaren Adapter zu informieren und das Programm darauf reagieren
zu lassen. Diese Routine, Enumeration genannt, ist sehr aufwndig und kann im Rahmen eines
Informatikmoduls nur schwer komplett erarbeitet werden. Dennoch wurden einige
Sicherheitsvorkehrungen getroffen, die Exceptions durch Zugriffe auf nicht vorhandene HardwareFunktionen verhindern sollen. Doch zuerst zu den Anfngen:
' Directx-Grafik initialisieren
engine0 = New engine(Panel1)
...
If engine0.Init Then running = True Else Me.Close()
Dim graphicsthread As New Threading.Thread(AddressOf render)
graphicsthread.Start()

' Grafikthread starten

Mit New engine(Panel1) wird der Konstruktor der engine-Klasse aufgerufen. Dieser versucht, ein
Direct3D-Device im bergebenen Container zu erstellen. Dieser Container kann ein Fenster oder,
wie hier, ein Panel sein, das der DirectX-Bibliothek die Bildschirmkoordinaten sowie die
Begrenzungen des Fensters aufzeigt. Als nchstes wird berprft, ob die Initialisierung erfolgreich
war. Wenn ja, kann der Thread mit der Render-Schleife gestartet werden sowie die zugehrige
Kontrollvariable auf true umspringen.
In der Engine-Klasse passiert Folgendes:
Public Sub New(ByVal target As Control)
Dim pp As New PresentParameters()
With pp
.Windowed = True
.SwapEffect = SwapEffect.Discard
.BackBufferCount = 1
.BackBufferFormat = Manager.Adapters(0).CurrentDisplayMode().Format

.BackBufferWidth = target.ClientSize.Width
.BackBufferHeight = target.ClientSize.Height
End With
p_target = target
Init = InitDevice(pp)
CreateGeometry()
End Sub

Es wird eine Instanz der PresentParameters-Struktur erstellt, die alle Einstellungen fr die DirectXSchnittstelle beinhaltet. Nicht alle mssen neu zugewiesen werden, nur die wichtigsten werden
explizit auf die gewnschten Werte gesetzt, einige wenige mchte ich hier beschreiben:
.Windowed:

Da wir keine Fullscreen-Anwendung haben, ist dieser Wert true.

.BackBufferCount: Ein Backbuffer ist ein reservierter Bereich im Speicher dies kann im
optimalen, nicht selten vorkommenden Fall der schnelle Grafikspeicher sein -,
der das Abbild eines Bildes, das auf den Bildschirm gezeichnet werden kann,
enthlt. Aufgrund der verschiedenen Methoden kann man eine
unterschiedliche Anzahl an Backbuffern bentigen. Hier wird auf die flipMethode verzichtet, bei der ein Pointer rasend schnell zwischen zwei
Backbuffern hin- und herspringen und hohe Framerates erzielen kann. Dies ist
bei der Komplexitt eines Pendelmodells noch nicht ntig.
Die weiteren Einstellungen beziehen sich auf das Backbuffer- und somit auch das Ausgabeformat.
Durch das bergebene Panel sind diese Daten leicht abfragbar.
Anschlieend wird die Funktion InitDevice() aufgerufen, in der, wie der Name schon sagt, das
eigentliche Device erstellt wird. Diese Instanz der Klasse Microsoft.DirectX.(Direct3D).Device
reprsentiert alle Einstellungsmglichkeiten und Fhigkeiten der Hardwarebeschleunigung
dementsprechend lang ist auch der Code, in dem damit umgegangen wird. Zu den wichtigsten
Zeilen gehren folgende:
p_D3DDevice = New Device(0, DeviceType.Hardware, p_target, CreateFlgs, pp)

Hiermit wird das Device erstellt, sicherheitshalber in einer Try- Catch- Schleife, die allerdings auch
nicht immer hilft. Um nicht auf inexistende Hardwarefunktionen zuzugreifen, wird vorher ein Teil
der vorhandenen Fhigkeiten festgestellt:
If D3DCaps.DeviceCaps.SupportsHardwareTransformAndLight() And
D3DCaps.DeviceCaps.SupportsPureDevice Then
CreateFlgs = CreateFlags.HardwareVertexProcessing Or
CreateFlags.PureDevice
ElseIf D3DCaps.DeviceCaps.SupportsHardwareTransformAndLight() Then
CreateFlgs = CreateFlags.HardwareVertexProcessing
Else
CreateFlgs = CreateFlags.SoftwareVertexProcessing
End If

In einer simplen If-ElseIf-Bedingung werden die Anforderungen immer weiter gesenkt, bis die
optimale Einstellung gefunden ist. Die schlechteste Mglichkeit ist die des
SoftwareVertexProcessing, bei der die Graphikkarte fast nur noch als D/A-Wandler fr das analoge
VGA-Signal fungiert.

3.3.2 Generelle Funktionsweise


Ist dieser entscheidende Schritt geschafft, kann es an die Umgebungseinstellungen gehen. Dazu ist
etwas Hintergrundwissen ntig: Wie funktioniert DirectX?
In der Vorlesung haben wir schon die Mglichkeit kennen gelernt, einen einfachen Wrfel mit
Linien so darzustellen, das er auf dem zweidimensionalen Bildschirm rumlich erscheint. Dazu
brauchten wir etliche Zeilen Code, der jeden einzelnen Punkt ber trigonometrische Funktionen zur
richtigen Bildschirmkoordinate transformierte. Die gleiche Prozedur, nur viel effizienter und
komfortabler, bernimmt DirectX. Grundgerst der Transformation sind 4x4-Matrizen, die die
translatorischen und rotatorischen Zustnde sowie andere Eigenschaften von Objekten wie Meshs
oder der Kamera beinhalten. Hier wird hauptschlich mit zwei dieser Matrizen gearbeitet:
Die World-Matrix: Die virtuelle Welt besitzt natrlich ein Koordinatensystem. Dies stimmt
allerdings nicht immer mit dem der Objekte berein wir haben also die Mglichkeit, entweder alle
Punkte unseres Objektes so zu verndern, dass es in der Umgebung am richtigen Platz erscheint,
oder dem Renderer beizubringen, dass das ganze Objekt verschoben werden soll. Dies wird mit der
World-Matrix erledigt. Es kann verschiedene Matrizen fr verschiedene Objekte geben, wenn
verschiedene Objekte an verschiedenen Positionen gezeichnet werden sollen was nicht selten der
Fall ist.
In der Pendelsimulation gibt es zwei Objekte, die sich relativ zueinander bewegen: Das
Pendelgerst, das fest bleibt, und das eigentliche Pendel. Der horizontale Stab in der Aufhngung
kann entweder mitschwingen oder nicht, da dies sowieso nicht sichtbar ist erledigt sich diese
berlegung allerdings relativ schnell. Es sind also zwei World-Matrizen ntig: Die einfachere von
beiden steuert die statische Position des Gerstes, das sich weder dreht noch translatorisch bewegt.
Microsoft hat dafr bereits eine fertige Matrix in die Bibliothek integriert, die hier zugewiesen wird:
p_D3DDevice.Transform.World = Matrix.Identity

Etwas schwieriger, im Vergleich zum manuell berechneten pseudo-3D-Wrfel aber immer noch
trivial, gestaltet sich die Transformation des Pendels. Auch hier gibt es vorgefertigte Funktionen, die
das programmieren eines 3D-Pendels innerhalb eines Semesters berhaupt mglich machen:
MatPendulum = Matrix.RotationZ(phi)

matPendulum, eine Instanz der Matrix-Klasse, erhlt nun alle ntigen Informationen, mit denen das
Pendel um die Z-Achse gedreht werden kann. Dies gestaltet sich aufgrund einiger Eigenschaften der
geladenen Pendelform so einfach, dass man nur einen Winkel an die Funktion bergeben muss. Nun
fehlen aber noch weitere Einstellungen: Aus welcher Richtung und von welcher Entfernung sieht
der Beobachter nun das Pendel? Wie sind die Lichtverhltnisse?
Fr die erste Frage gibt es die View-Matrix:
.Transform.View = Matrix.LookAtLH(New Vector3(0, 0, -10), _
New Vector3(0, 0, 0), _
New Vector3(0, 1, 0))

Die Funktion, die eine LeftHanded-Viewmatrix generiert, bentigt als ersten Vektor den Standpunkt
des Beobachters: Dieser liegt hier bei -10 Einheiten auf der Z-Achse verschoben.
Der zweite Vektor ist die Blickrichtung eine entscheidende Erleichterung ist die Tatsache, dass der
Vektor nicht in Blickrichtung zeigen muss, sondern auf einen Punkt, auf den der Blick gerichtet sein
soll. Im Falle unseres Pendels soll der Blick immer auf das Pendel selbst gerichtet sein, da ja keine
anderen Objekte im Raum vorhanden sind, weswegen der zweite Wert immer gleich bleiben kann.
Dasselbe gilt fr den dritten bergebenen Vektor: Der CameraUpRight-Vector. Er gibt vor, wo oben
ist, in diesem Falle ist es immer die positive y-Richtung.

3.3.3 Die Render()-Funktion


An sich hat die Render()-Funktion in frmMain.vb keinen eigenen Gliederungspunkt verdient. Eher

sind es die aufgerufenen Methoden in der engine-Klasse, die die Darstellung des Pendels bewirken.
Dim graphicsthread As New Threading.Thread(AddressOf render)
graphicsthread.Start()

Hier wird eine neue Instanz des Objekts Thread initialisiert und gestartet. Dies bewirkt nur, dass die
Private Sub render() als eigener Prozess aufgerufen wird.
Do While running
(...)
Try
engine0.UpdateFrame(phi, rotateH, rotateV)
engine0.RenderFrame()
Catch stopexp As Threading.ThreadAbortException
statuslabel.Text = "Fehler in der Render-Funktion"
Return
End Try
Loop

Diese Schleife luft so lange, wie die Statusvariable des Direct3D-Objekts anzeigt, dass eine
Graphikberechnung mglich ist. Dabei bedient sie sich der Methoden UpdateFrame() und
RenderFrame().
UpdateFrame() aktualisiert die World- und die Viewmatrix, stellt also die Verbindung zwischen
Physik-Backend und 3D-Darstellung her. Aufgrund der Angabe von phi, dem
Pendelauslenkungswinkel, sowie rotateH und rotateV, die die Position der Kamera angeben, knnen
die entsprechenden Matrizen einfach berechnet werden: Fr die Pendelauslenkung ist die Funktion
Matrix.RotationZ(phi)

ausreichend, die Berechnung der Kameraposition gestaltet sich etwas schwieriger: Der Beobachter
soll die Kamera durch Ziehen mit der Maus auf einer gedachten Kugel um das Pendel bewegen
knnen. Dabei hat man zwei Winkel: rotateH, die Drehung in der horizontalen Ebene, sowie
rotateV, sozusagen die Hhe ber oder unter dem anvisierten Objekt. Da bei Hhennderung
allerdings auch der Abstand von der senkrechten Achse kleiner wird, sieht die endgltige
Berechnung so aus:
' Viewmatrix
Dim kameraposition As Vector3
Dim multiplikator As Single
multiplikator = 11 * Convert.ToSingle(Math.Cos(rotateV))
kameraposition = New Vector3(multiplikator * _
Convert.ToSingle(Math.Sin(rotateH)), 12 * _
Convert.ToSingle(Math.Sin(rotateV)), -multiplikator * _
Convert.ToSingle(Math.Cos(rotateH)))
MatView = Matrix.LookAtLH(kameraposition, New Vector3(0, 0, 0), New
Vector3(0, 1, 0))

Sind die Matrizen nun fertig berechnet, wir die Routine renderFrame() aufgerufen, die den
eigentlichen Zeichenvorgang erwirkt. Zuerst muss die Szene geleert werden. Anschlieend wird die
World-Matrix sowie das Material fr die zu zeichnenden Elemente zugewiesen, die Elemente
gezeichnet, um anschlieend eine neue Gruppe mit identischen Eigenschaften zu zeichnen. In
diesem Vorgang wird irgendwann, bevor die Subsets fr Pendelstab und -kugel in den Backbuffer
geschrieben werden, die matPendulum der World-Matrix zugewiesen. Die ViewMatrix muss nur
einmal zugewiesen werden. Ist auch diese Routine am Ende angekommen, ist ein neuer Frame
generiert bis er nach ca. 10 ms vom nchsten abgelst wird.

3.4 Graphendarstellung ber System.Drawings


Trotz Verwendung von Direct3D wurde in diesem Programm nicht auf zweidimensionale Elemente
verzichtet: Der zeitliche Verlauf der drei Werte Auslenkung, Geschwindigkeit und Beschleunigung
wird mit der System.Drawings-Klasse in einfachen Graphen ausgegeben. Dies wurde schon in der
Vorlesung grundlegend behandelt, was relativ einfach, aber auch rechenaufwndig war. Die grte

Optimierung in diesem Bereich war die direkte Speicherung der Pixelwerte in einem Array und die
damit ermglichte Verwendung der Funktion DrawLines(), die alle Punkte dieses Arrays verbindet.
Somit konnte eine Schleife weggelassen werden, die nach jeder Physikberechnung knapp 400
einzelne Linien zeichnen musste bei 10ms Timer-Intervall sind dies 40000 Linien * zwei
Pixelberechnungen pro Sekunde und wurde durch einen einfachen Funktionsaufruf ersetzt, bei
dem die im .NET-Framework mitgelieferte Methode die schon vorhandenen Pixeldaten einfach
verbinden musste.
Ein Nachteil dieser Vorgehensweise ist, dass das Vergrern bzw. Verkleinern der Graphen
erheblich komplizierter wurde. Konnte man davor einfach den Multiplikator, der die y-Werte der
Pixel bestimmte, verndern, sind nun die Positionen der Punkte auf dem Bildschirm fest
zugewiesen. Die Lsung war die Einfhrung eines zoomRequest-Arrays, das den Wunsch einer
Vernderung dieses Multiplikators beinhaltet. Vor dem Zeichnen der Graphen wird der Wunsch mit
dem tatschlich vorhandenen (im zoom()-Array gespeicherten) Werten verglichen. Ist eine
Anpassung ntig (sei es aufgrund eines Klicks auf Vergrern / Verkleinern oder durch einen
Request seitens der AutoScale-Routine) werden alle Pixeldaten neu berechnet. Da dies erheblich
seltener vorkommt als das Zeichnen, fllt der Vorgang kaum ins Gewicht. Bei einer Vergrerung
tritt aber eine Rasterung auf, da Informationen ber die Auslenkung vorher nicht genau genug
gespeichert wurden.Diese Rasterung verschwindet allerdings mit neu berechneten Werten wieder.
Dieser Nachteil wird vom enormen Geschwindigkeitsvorteil wieder wettgemacht.

3.5 Maussteuerung des Pendels


Eine 3D-Ansicht ruft nur dann ein vertrautes Gefhl hervor, wenn man sich in der 3D-Welt auch
bewegen kann. Eine etwas rudimentre Art der Bewegung, nmlich die auf einer gedachten Kugel
um den Koordinatenursprung, ist mittels Mausbewegungen mglich. Deswegen wird innerhalb der
Render()-Funktion auch stndig geprft, ob Mauseingaben ankommen und wie diese zu verarbeiten
sind. Daraus werden dann rotateH und rotateV berechnet, die weiteren Schritte werden dann in der
updateFrame-Sub ausgefhrt.

4. Geschwindigkeitsoptimierung
Erste Entwrfe der Pendelsimulation verfgten zwar ber einige Funktionen, belasteten den
Prozessor aber derart, dass der Hauptschwerpunkt nach einer Zeit auf Geschwindigkeitsoptimierung
bei gleicher oder sogar noch verbesserter (3D-) Darstellungsqualitt gelegt wurde. Dies wurde
teilweise durch optimale Verwendung der verfgbaren Hardware erreicht, teilweise konnten
Schleifen so verbessert werden, dass sie nur noch einen Bruchteil der vorher angefallenen
Rechenlast verursachen.

4.1 Multithreading
Die Leistungssteigerung neuerer Prozessoren beruht hauptschlich darauf, mehrere Kerne in einen
Prozessor zu integrieren (Multicore). Da diese aber nicht allzu verzahnt ineinander arbeiten knnen,
mssen Programme, die von mehreren Kernen profitieren wollen, die Rechenlast auch auf
entsprechend viele Prozesse / Threads aufteilen (Multithreading). Da die meisten Prozessoren im
mittleren Preissegment 2 Kerne haben und sich bei der Pendelsimulation zwei relativ unabhngige
Rechenleistungsverbraucher gegenberstehen, bietet sich die Auslagerung der 3D-Darstellung in
einen eigenen Prozess an. Nachteil davon ist, dass die einzelnen Threads untereinander nur
eingeschrnkt kommunizieren knnen. Zum Beispiel knnte der 3D-Prozess kein Label auf dem
Hauptfenster ndern, dies wrde eine Exception hervorrufen.
Durch die Optimierung an anderen Stellen ist die Belastung so stark gesunken, dass ein
Prozessorkern alle Aufgaben ohne Probleme bernehmen knnte. Dennoch soll Multithreading eher

als zustzlicher Ansatz denn als Lsung eines hier vorhandenen Problems gesehen werden, mit dem
das verfgbare, wenn auch nicht genutzte, Potential an Rechenkapazitt auf einem modernen
Prozessor fast verdoppelt werden konnte. Fast deswegen, weil die beiden Prozesse fr eine exakte
Verdopplung exakt den gleichen Rechenaufwand bernehmen mssten, was allerdings nicht
realistisch ist.

4.2 Graphen und zugehrige Arrays


Nun zu den drei Graphen, die den zeitlichen Verlauf der Pendelwerte darstellen. Der Kern dieser
Funktion liegt in der Fuktion des Physics-Timers, der auch das Plotten der Werte in die
vorgegebenen Arrays anstt. Dies wurde in der Vorlesung durch Schreiben der aktuellen Werte in
Arrays realisiert, die Werte wurden nach jeder Iteration komplett um eine Position nach vorne
(zeitlich nach hinten) geschoben. Diese Operation belastet hauptschlich den Arbeitsspeicher, der
durch die anderen Aktionen allerdings nicht so belastet ist, als dass dies einen Engpass darstellen
wrde. Viel mehr fiel die Umrechnung aller Graphenwerte von den physikalischen Daten in
Pixelwerte ins Gewicht, hier wurde bei jedem Neuaufbau der Graphen fr jeden einzelnen Wert eine
Multiplikation ntig. Im vorliegenden Programm wurde dieses Problem umgangen, indem die
Werte direkt von der Iteration schon in Pixeldaten umgewandelt und dann erst in die Arrays
geschrieben wurden.
Zudem wurde der Typ auf System.Drawings.Point gesetzt schon bestand das Array nicht mehr aus
einfachen Variablenwerten, sondern aus Pixeldaten, die beim Neuaufbau sehr schnell von der
graphics.drawLines()-Funktion mit einer Linie verbunden werden konnten. Die daraus
resultierenden Schwierigkeiten bei der AutoScale-Funktion wurden weiter oben schon
angesprochen.

5. Exception Prevention
5.1 Benutzereingaben absichern
Visual Studio bringt mit seinen NumericUpDown-Feldern eigentlich schon alles mit, was man sich
als Benutzereingabenabsicherung wnschen kann: Die Bedienung ist einfach, es werden ungltige
(nicht-Zahlen-) Werte geblockt und die eingegebenen Werte knnen nicht ber festgelegte Grenzen
hinausgehen. Somit war dies eine der leichteren Aufgaben in diesem Projekt. Es mussten nur fr
alle einzugebenden Werte sinnvolle Minimal- und Maximalwerte festgelegt werden. Eine weitere
Einstellung, nmlich das Intervall pro Klick auf eine der pfeilfrmigen Schaltflchen, dient eher
dem Komfort als der Sicherheit und sollte der Bandbreite an realistischen Werten fr die aktuelle
Eisntellung entsprechend angepasst sein. Weitere Absicherungen sind hier nicht ntig.

5.2 Zu verhindernde BufferOverflow-Zustnde


Eine Pendelsimulation ist zwar physikalisch durchaus berschaubar und leicht verstndlich,
dennoch knnen Geschwindigkeit oder Beschleunigung ungewollte Gren annehmen.
Eine Mglichkeit ist ein berlaufen der Zoom-Variable: Die Autoscale-Routine versucht, die
Graphen immer so zu skalieren, um den gesamten verfgbaren Platz zu verwenden. Ist ein
darzustellender Wert aber zu klein, wchst die ntige Vergrerungsvariable ber die Grenzen einer
Decimal-Zahl hinaus. Deswegen wurde der Maximalwert fr den Multiplikator auf 32000 gesetzt
wird er erreicht, erscheint im Statusbalken eine Benachrichtigung darber und der Graph wird nicht
weiter vergrert.Werden, zum Beispiel durch extrem hohe Viskositt, einer groen ReibkraftAngriffsflche und hohen Startgeschwindigkeiten, zu hohe Winkelgeschwindigkeiten oder
Beschleunigungen erreicht, bricht die Simulation mit einer entsprechenden Meldung ab. Dadurch,

dass extreme Beschleunigungen und Geschwindigkeiten auch den Fehler der Integrationsmethode
in die Hhe schnellen lassen, wurde die Grenze fr diese Werte deutlich unterhalb der eigentlichen
technischen Beschrnkung festgelegt.

6. Abschluss
Dieses Pendelprogramm nutzt bei weitem nicht alle Ressourcen, die durch die Optimierung frei
wurden, aus. Es soll eher veranschaulichen, dass es schon mit sehr wenig Erfahrung mglich ist, auf
die bentigte Rechenleistung zu achten und viel einzusparen. Visual Basic (mit oder ohne .NET) hat
den Ruf, viele Ressourcen zu verbrauchen, dafr aber sehr leicht erlernbar zu sein.
Man kann der Sprache und dem Framework aber auch die Chance geben, genau diesen Zeitvorteil
durch leichte Handhabung in die ressourcenschonende Programmierung einflieen zu lassen und so
einen sehr guten Kompromiss aus einfacher Programmierung und Geschwindigkeit zu erhalten.