73
Interaktive 3-D-Visualisierung ozeanographischer Daten mittels Web-Technologien Bachelorarbeit Patricia Beier 26. September 2016 Christian-Albrechts-Universität zu Kiel Institut für Informatik Arbeitsgruppe Software Engineering Betreut durch: Prof. Dr. Wilhelm Hasselbring Dr. Arne Johanson

Interaktive 3-D-Visualisierung ozeanographischer Daten mittels Web-Technologieneprints.uni-kiel.de/34760/1/2016BScBeier.pdf · In dieser Bachelorarbeit wird eine 3-D-Visualisierung

Embed Size (px)

Citation preview

Interaktive 3-D-Visualisierungozeanographischer Datenmittels Web-Technologien

Bachelorarbeit

Patricia Beier

26. September 2016

Christian-Albrechts-Universität zu Kiel

Institut für Informatik

Arbeitsgruppe Software Engineering

Betreut durch: Prof. Dr. Wilhelm HasselbringDr. Arne Johanson

Eidesstattliche Erklärung

Hiermit erkläre ich an Eides statt, dass ich die vorliegende Arbeit selbstständig verfasstund keine anderen als die angegebenen Quellen und Hilfsmittel verwendet habe.

Kiel, 26. September 2016

ii

Zusammenfassung

Wissenschaftliche Tätigkeit beschränkt sich nicht auf das Sammeln von Daten. Nach derErmittlung von Datensätzen müssen diese untersucht werden, um zu weiterem Erkenntnis-gewinn zu gelangen. Dies gilt auch für die ozeanographische Forschung. Um entsprechendeUntersuchungen zu vereinfachen, können Hilfsmittel eingesetzt werden, zu denen dieVisualisierung der Daten mittels Computersoftware gehört.

In dieser Bachelorarbeit wird eine 3-D-Visualisierung ozeanographischer Daten entwi-ckelt. Diese wird in die Web-Anwendung OceanTEA eingebunden. Berücksichtigt werdendabei verschiedene Datentypen, zu denen die Oberflächenstruktur des Meeresbodensund das zeitabhängige Verhalten von Strömungen gehören. Die Visualisierung wird mitverschiedenen Hilfsfunktionen ausgestattet, um dem Nutzer das Ablesen der Daten unddamit seine Forschungstätigkeit zu erleichtern.

Nach der Implementierung wird das entstandene System evaluiert, wobei qualitativeExperteninterviews herangezogen werden. Ziel der Evaluation ist es, die Eignung derAnwendung für die wissenschaftliche Arbeit zu überprüfen. Dabei werden Mitarbeiterdes GEOMAR Helmholtz-Zentrum für Ozeanforschung Kiel zu ihrem Nutzungserlebnisbefragt. Im Ergebnis lässt sich feststellen, das das hier entwickelte System bereits fürdie Anwendung in der ozeanographischen Forschung geeignet ist. Die Evaluation ergibtdarüber hinaus Hinweise für die Weiterentwicklung der Software in der Zukunft.

iii

Inhaltsverzeichnis

1 Einleitung 11.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Ziele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.2.1 Ziel 1: Entwicklung einer 3-D-Visualisierung für ozeanographischeDaten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.2.2 Ziel 2: Evaluation der implementierten Anwendung . . . . . . . . . . 21.3 Aufbau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2 Grundlagen und Technologien 32.1 OceanTEA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.2 Three.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.3 3-D-Computergrafik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.3.1 Aufbau dreidimensionaler Objekte . . . . . . . . . . . . . . . . . . . . . 52.3.2 Transformationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.3.3 Das Koordinatensystem . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3 Entwicklung des Konzepts 133.1 Die Einbindung in OceanTEA . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.2 Sichtbarmachen des Koordinatensystems . . . . . . . . . . . . . . . . . . . . . 133.3 Der Boden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.4 Die Messstationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.5 Darstellung der Strömungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.5.1 Visualisierung durch Pfeile . . . . . . . . . . . . . . . . . . . . . . . . . 143.5.2 Zeitliche Abhängigkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.5.3 Steuerung durch den Nutzer . . . . . . . . . . . . . . . . . . . . . . . . 14

4 Implementierung der 3-D-Visualisierung 174.1 Aufbau der Webseite und Beschreibung der Funktionen . . . . . . . . . . . . 174.2 Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204.3 Implementierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4.3.1 Die Slider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234.3.2 Die erste Region . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264.3.3 Das User-Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274.3.4 Die show()-Funktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294.3.5 Die Lookup-Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314.3.6 Die Steuerung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

v

Inhaltsverzeichnis

4.3.7 Das sichtbare Koordinatensystem . . . . . . . . . . . . . . . . . . . . . 314.3.8 Platzierung der Messstationen . . . . . . . . . . . . . . . . . . . . . . . 364.3.9 Die Pfeile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414.3.10 Der Ozeanboden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434.3.11 Die Checkboxen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

5 Evaluation 515.1 Ziel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515.2 Versuchsaufbau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

5.2.1 Teilnehmer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525.2.2 Präsentierte Fragen und Aufgaben . . . . . . . . . . . . . . . . . . . . . 525.2.3 Beschreibung der Durchführung . . . . . . . . . . . . . . . . . . . . . . 53

5.3 Ergebnisse und ihre Diskussion . . . . . . . . . . . . . . . . . . . . . . . . . . . 545.3.1 Usability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545.3.2 Nutzbarkeit für wissenschaftliche Zwecke . . . . . . . . . . . . . . . . 555.3.3 Vorschläge für Verbesserungen . . . . . . . . . . . . . . . . . . . . . . . 56

5.4 Bedrohungen der Validität . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565.4.1 Anzahl der Probanden . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565.4.2 Zeitliche Beschränkung . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

6 Verwandte Arbeiten 596.1 Fledermaus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596.2 ExplorViz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

7 Fazit und Ausblick 637.1 Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637.2 Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

Bibliografie 65

vi

Kapitel 1

Einleitung

1.1. Motivation

Die Erhebung von Daten in der ozeanographischen Forschung geschieht unter anderemdadurch, dass Informationen zur topologischen Gestalt des Ozeanbodens oder zum zeitab-hängigen Verhalten von Strömungen an einem relevanten Standpunkt gesammelt werden.Diese sind Basis für weitere wissenschaftliche Untersuchungen.

Um wissenschaftliche Untersuchungen zu erleichtern, können Hilfsmittel zur Visuali-sierung von gesammelten Daten eingesetzt werden. Zu diesen Hilfsmitteln zählen Com-puterprogramme [Telea 2007]. Sie helfen dabei, wesentliche Eigenschaften der Datensätzeherauszuarbeiten. Wissenschaftlich relevante Entwicklungen innerhalb der Daten werdenfür den Nutzer eines solchen Programms leichter zugänglich.

Es gibt verschiedene Möglichkeiten, Software für die Datenvisualisierung zu nutzen.Neben unmittelbar auf dem Rechner installierten Programmen ist es auch möglich, denWeb-Browser für die Darstellung zu verwenden. OceanTEA (Oceanographic Time SeriesExploration and Analysis)1 stellt ein System für die wissenschaftliche Datenvisualisierungim Browser dar [Johanson u. a. ohne Datum]. OceanTEA erlaubt es, Daten aus der Ozeano-graphie mittels moderner Web-Technologien interaktiv zu erforschen und zu analysieren.Relevant werden dabei durch das GEOMAR Helmholtz-Zentrum für Ozeanforschung Kiel2

(kurz: GEOMAR) ermittelte Datenmengen.Die vorliegende Bachelorarbeit leistet einen Beitrag zu OceanTEA in Form einer 3-

D-Visualisierung bestimmter ozeanographischer Daten. Zu diesen Daten gehören dieDarstellung der Oberflächenstruktur des Ozeanbodens einer ausgewählten Region und diezeitabhängige Visualisierung der dort zu findenden gemessenen Strömungen. Auf dieseWeise soll die raumbezogene Analyse der Daten unterstützt werden.

1.2. Ziele

Für diese Bachelorarbeit setzen wir uns einige Ziele, die wir im Laufe der Entwicklungerreichen möchten:

1http://maui.se.informatik.uni-kiel.de:9090.2http://www.geomar.de.

1

1. Einleitung

1.2.1. Ziel 1: Entwicklung einer 3-D-Visualisierung für ozeanographi-sche Daten

Für die Entwicklung einer Web-Anwendung mit einer dreidimensionalen Darstellung ozea-nographischer Daten soll das JavaScript-API Three.js eingesetzt werden. Das entwickelteProgramm soll die zu visualisierenden Daten vom Server erhalten und diese in geeigneterWeise verarbeiten. Die Visualisierung soll die Auswahl verschiedener Regionen ermögli-chen. Nach der Auswahl einer Region durch den Nutzer erscheinen die Visualisierung derOberflächenstruktur des Bodens, die zeitabhängige Darstellung von Strömungen sowiedie Darstellung von Messstationen, mit deren Hilfe diese Strömungen ermittelt wurden.Außerdem soll die Anwendung die Möglichkeit zur Interaktion bieten. Der Nutzer sollsich durch die Darstellung bewegen können. Er soll einzelne Elemente verändern können,wenn er den Wunsch hat, bestimmte Daten abzulesen.

1.2.2. Ziel 2: Evaluation der implementierten Anwendung

Die Implementierung soll einer Evaluation unterzogen werden. Zu diesem Zweck werdenExperten befragt, die die Software ausprobieren und ihre Meinung zu bestimmten The-menkomplexen äußern sollen. Dabei wird ihnen eine fortgeschrittene Version der Softwarezur Verfügung gestellt.

1.3. Aufbau

In Kapitel 2 finden sich Grundlagen und Technologien, die für die Bachelorarbeit vonBedeutung sind. Sie unterstützen das Verständnis der Implementierung. In Kapitel 3wird das Konzept erklärt, das der Implementierung zugrundeliegt. Kapitel 4 erläutertdie Implementierung selbst. Der Evaluation ist Kapitel 5 gewidmet. Dort werden dieErgebnisse der Expertenbefragung und ihre Bedeutung für die weitere Entwicklung desProgramms dargestellt. In Kapitel 6 werden verwandte Arbeiten vorgestellt. Kapitel 7enthält schließlich ein Fazit sowie einen Ausblick auf zu erwartende Entwicklungen zumThema dieser Bachelorarbeit.

2

Kapitel 2

Grundlagen und Technologien

Wir besprechen nun einige Grundlagen und Technologien, deren Verständnis für diespätere Implementierung wesentlich ist.

2.1. OceanTEA

Das in dieser Bachelorarbeit entwickelte Programm wird in OceanTEA integriert. OceanTEA([Johanson u. a. ohne Datum]) ist eine Open-Source Web-Anwendung zur Visualisierungvon Zeitreihendaten mit Bezug auf Ergebnisse aus der Klimaforschung. Bei Zeitreihendatenhandelt es sich um Daten, die über mehrere einander folgende Zeitpunkte gesammelt wer-den. OceanTEA dient insbesondere dazu, Daten zu visualisieren, die die Forschungsarbeitvon Mitarbeitern des GEOMAR unterstützen.

Die Anwendung basiert auf dem Microservice Architecture Pattern. Dieser Begriff be-schreibt Software-Anwendungen, die aus einzelnen Microservices bestehen. Microservicessind Services, die voneinander unabhängig hinzugefügt oder entfernt werden können[Fowler und Lewis 2015]. Services sind einzelne Anwendungen, die jeweils eine bestimmteFunktion bieten.

Die Microservices in OceanTEA sind in drei Vertikale ([Kraus u. a. 2013]) eingeteilt.Kennzeichnend für Vertikale ist, dass es sich um voneinander unabhängige Teilsystemehandelt. Es gibt hier unter anderem keinen geteilten Quellcode und ein getrenntes Frontend(die Benutzeroberfläche einer Webseite). Vertikale können unabhängig voneinander entwi-ckelt werden – auch durch getrennt voneinander arbeitende Entwickler. Sie kommunizierenim Einsatz durch REST-Schnittstellen (REpresentational State Transfer) miteinander.

Im ersten Vertikal (Time Series) von OceanTEA befinden sich Microservices, die dieBehandlung von Zeitreihendaten betreffen. Im zweiten Vertikal wird die Spatial Analysis,also die räumliche Analyse behandelt. Im dritten Vertikal geht es um Pattern Discovery inTime, also um Musterentdeckung im zeitlichen Verlauf. Die Abbildung 2.1 zeigt die entspre-chende Struktur von OceanTEA. Die in dieser Bachelorarbeit entwickelte Implementierungfindet ihren Platz im Spatial Analysis-Vertikal.

3

2. Grundlagen und Technologien

Abbildung 2.1. OceanTEA-Microservices

2.2. Three.js

Three.js1 ist ein JavaScript-API (Application Programming Interface – eine Schnittstelle zur An-wendungsentwicklung), das es dem Entwickler ermöglicht, 3-D-Elemente in eine Webseitezu integrieren. Dessen Urheber ist der Github-User Mr.doob – Ricardo Cabello2.

Three.js greift auf Funktionen von WebGL (Web Graphics Library) zurück. Bei WebGLhandelt es sich um ein DOM-API, das von der Khronos Group3 entwickelt wurde. WebGLbietet die Möglichkeit, 3-D-Grafiken direkt im Browser darzustellen, ohne dass dafürweitere Software installiert werden muss. Die erzeugten 3-D-Visualisierungen werden ineine Webseite integriert, wobei die Strukturierung durch HTML-Tags ausgenutzt werdenkann. Das macht es möglich, andere HTML-Elemente (zum Beispiel Buttons) auf der3-D-Darstellung zu platzieren. WebGL wird durch gängige moderne Browser dargestellt[Parisi 2012]. Dabei handelt es sich vor allem um Firefox 4+, Google Chrome 9+, Opera 12+,Safari 5.1+ und Internet Explorer 11+ [Dirksen 2015].

Für diese Bachelorarbeit wurde nicht unmittelbar mit WebGL gearbeitet. Basis der hierentstandenen 3-D-Visualisierung ist Three.js. Der Vorteil der Verwendung von Three.jsliegt darin, dass sie unkomplizierter ist und weniger umfangreiches Wissen voraussetzt alsder direkte Zugriff auf WebGL [Dirksen 2015]. Dennoch ist es über Three.js möglich, dieOptionen zu nutzen, die WebGL dem Entwickler zur Verfügung stellt.

1http://threejs.org.2https://github.com/mrdoob/three.js/tree/master.3https://www.khronos.org/webgl.

4

2.3. 3-D-Computergrafik

Parisi [2012] beschreibt die Vorteile der Verwendung von Three.js gegenüber der un-mittelbaren Nutzung von WebGL. Dazu gehört, dass der Entwickler unmittelbar mitden Objekten arbeiten kann, die eine 3-D-Szene ausmachen. Mit den Details ihrer Dar-stellung muss er sich nicht beschäftigen. Dabei ist Three.js objektorientiert strukturiert.Die Repräsentation der Elemente als Objekte mit Attributen und Methoden stützt dasVerständnis zusätzlich. Dabei werden dem Entwickler zahlreiche vordefinierte Struktu-ren zur Verfügung gestellt, die er direkt übernehmen kann. Zum Beispiel existieren inThree.js vordefinierte Würfel (THREE.BoxGeometry), Kreise (THREE.CircleGeometry), Ebenen(THREE.PlaneGeometry) oder dreidimensionale Texte (THREE.TextGeometry), die mit derAngabe einiger weniger Parameter (die sich etwa auf Breite und Höhe beziehen) erstelltund direkt in die 3-D-Szene gesetzt werden. Außerdem gibt es einfache Wege, interaktiveElemente in die Darstellung zu integrieren – zum Beispiel die Bewegung mit Maus undTastatur durch ein Controls-Objekt.

Die Klassen in Three.js können entsprechend dem objektorientierten Ansatz erweitertwerden, sodass der Entwickler auf ihrer Basis eigene Klassen und damit vor allem eigenegeometrische Objekte definieren kann.

Three.js unterstützt die Integration von 3-D-Elementen, die in Dateiformaten wieJSON (JavaScript Object Notation) definiert wurden. Damit können geometrische Objektedurch externe Hilfsprogramme erzeugt und auf einfache Weise in die Implementierungübernommen werden.

Ein in Three.js geschriebenes Programm enthält eine Scene (Szene), in der 3-D-Objekteplatziert sind. Diese Objekte betrachtet der Nutzer mithilfe einer Camera, die an einergewünschten Stelle im Koordinatensystem positioniert ist. Sie macht es möglich, dieDarstellung aus einer gewünschten Entfernung und von einem gewünschten Winkel ausanzusehen. Ein Renderer, der in Three.js wie Scene und Camera ein aus einer Klasseerzeugtes Objekt ist, erzeugt die zweidimensionale Abbildung der dreidimensionalenSzene auf dem Bildschirm.

2.3. 3-D-Computergrafik

Grundkenntnisse der 3-D-Computergrafik helfen dabei, die hier entwickelte Visualisierungbesser zu verstehen.

2.3.1. Aufbau dreidimensionaler Objekte

Objekte (Meshes) in einer dreidimensionalen Darstellung besitzen einen gemeinsamengrundlegenden Aufbau. Sie bestehen aus Vertices, also Knoten oder Punkten, und Fa-ces. Diese Struktur ermöglicht die Erzeugung von Meshes mit beliebiger Form. Verticesbestimmten die Form des Objekts. Außerdem haben sie einen bestimmten Platz im Koordi-natensystem der 3-D-Szene. Mit ihrer Hilfe wird festgelegt, wo genau sich das Objekt inder Szene befindet.

5

2. Grundlagen und Technologien

Faces in Three.js sind Dreiecke, die jeweils drei Vertices miteinander verbinden. Durchdie richtige Auswahl der Knoten für einzelne Dreiecke wird erreicht, dass die Oberflächeeines Meshs komplett bedeckt wird [Hughes u. a. 2013].

Einen anderen Aufbau besitzen Linien, die ebenfalls in einer 3-D-Darstellung vorkom-men können. Linien in Three.js verbinden jeweils zwei Vertices miteinander. Auch bei einemLinienzug sind immer zwei Vertices durch ein Liniensegment miteinander verbunden. EineLinie besitzt keine Faces [Dirksen 2015].

Vertices und Faces bilden die Three.js-Geometry. Diese wird mit einem Material versehen.Über das Material kann der Entwickler festlegen, welche Farbe oder Textur das Meshbesitzen soll.

Der Entwickler kann auf vorgefertigte 3-D-Objekte zurückgreifen. So kann er etwa beieiner THREE.BoxGeometry lediglich Breite, Höhe und Tiefe angeben, um einen Würfel zuerzeugen. Die eigentliche Struktur, die auch hier aus Vertices und Faces besteht, ist inThree.js vordefiniert.

2.3.2. Transformationen

Um Objekte in einer 3-D-Szene an die gewünschte Stelle zu setzen, ihnen die richtige Größeund die richtige Drehung zu verleihen, bedarf es der Anwendung von Transformationen.Zu den Transformationen zählen die Translation – die Verschiebung, die Skalierung, die fürVergrößerung oder Verkleinerung sorgt und die Rotation, die ein Objekt um eine Achse desKoordinatensystems dreht.

Es existieren unterschiedliche Arten, die Transformation eines Objekts zu betrachten.Wir folgen der von Nischwitz und Haberäcker [2013] bevorzugten Sichtweise, die von einemlokalen Koordinatensystem ausgehen, das fest mit dem jeweiligen Objekt verbunden ist.Die Transformationen, die stattfinden, beziehen sich auf dieses lokale Koordinatensystem,das in einer bestimmten Weise beeinflusst wird.

Die Translation

Eine Translation ([Nischwitz und Haberäcker 2013] [Mukherjee 2004]) verschiebt das lokaleKoordinatensystem in der erwähnten Betrachtungsweise an einen vorgegebenen PunktT = (Tx, Ty, Tz)T . T beschreibt den neuen Ursprung des Koordinatensystems. Der Ursprung(0, 0, 0)T des lokalen Koordinatensystems des Objekts befindet sich nach Durchführungder Translation also an der Stelle (Tx, Ty, Tz)T .

Formal bezieht sich eine Translation auf die Vertices des betreffenden Objekts. AlleVertices besitzen eine bestimmte Position v = (x, y, z)T . Nach der Translation nehmensie eine neue Position v1 = (x1, y1, z1)T ein. Der neue Punkt wird ermittelt, indem eineVektoraddition stattfindet. Der die Position des Vertex beschreibende Vektor v wird mitdem Richtungsvektor T = (Tx, Ty, Tz)T addiert. Zu beachten ist dabei, dass dieser Rich-tungsvektor dem neuen Ursprung des lokalen Koordinatensystems entspricht.

6

2.3. 3-D-Computergrafik

Abbildung 2.2. Translation (Bildquelle: Schlechtweg, Hochschule Anhalta)

ahttp://www.mttcs.org/Skripte/Pra/Material/vorlesung3.pdf.

Es gilt also: v1 = (x1, y1, z1)T = (x, y, z)T + T = (x, y, z)T + (Tx, Ty, Tz)T = (x + Tx, y +Ty, z + Tz)T . Diese Rechnung findet unter Zugrundelegung eines kartesischen Koordina-tensystems statt.

Eine andere mögliche Betrachtungsweise ist die Annahme homogener Koordinaten.Diese erlauben es, Transformationen allgemein als Matrixoperationen darzustellen. DieTranslation kann so ebenfalls durch die Multiplikation von v mit einer 4x4-Translations-Matrix T beschrieben werden.

Es gilt: v1 = Tv =

1 0 0 Tx0 1 0 Ty0 0 1 Tz0 0 0 1

xyzw

. Dabei wird w = 1 gesetzt.

In Abbildung 2.2 ist eine Translation in der x-y-Ebene zu sehen. Die Translation imRaum verläuft analog.

Die Rotation

Bei der Rotation ( [Brüderlin u. a. 2013] [Mukherjee 2004]) wird das lokale Koordinatensys-tem des Objekts um den in Grad angegebenen Winkel α in Bezug auf den Richtungsvektorr = (rx, ry, rz)T gedreht. Wenn der Winkel positiv ist, dann erfolgt die Drehung gegen denUhrzeigersinn, also im mathematisch positiven Sinn. Hier kann – wie in Abbildung 2.3 –eine Rechte-Hand-Regel unterstützend für die Veranschaulichung eingesetzt werden. Zeigtder Daumen der rechten Hand in die Richtung des Vektors, geben die vier eingerolltenFinger die Richtung der Drehung an [Nischwitz und Haberäcker 2013].

In den homogenen Koordinaten gibt es drei unterschiedliche Rotationsmatrizen. Welchedavon die richtige ist, hängt davon ab, ob die Rotation um die z-Achse (Rzα), um diex-Achse (Rxα) oder um die y-Achse (Ryα) erfolgt.

7

2. Grundlagen und Technologien

Abbildung 2.3. Rechte-Hand-Regel bei Rotation (Bildquelle: TU Ilmenaua)

ahttps://www.tu-ilmenau.de/fileadmin/media/gdv/Lehre/Computergrafik_I/Uebung/gdv1gt.pdf.

Es gilt:

Rzα =

cosα ´sinα 0 0sinα cosα 0 0

0 0 1 00 0 0 1

,

Ryα =

cosα 0 sinα 0

0 1 0 0´sinα 0 cosα 0

0 0 0 1

und

Rxα =

1 0 0 00 cosα ´sinα 00 sinα cosα 00 0 0 1

.

Wenn wir also zum Beispiel eine Rotation um den Winkel α um die z-Achse durch-führen möchten, dann gilt für die neue Position v1 des Vertex v = (x, y, z)T : v1 = Rzαv. InAbbildung 2.4 ist die Rotation in der x-y-Ebene dargestellt. Im Raum verläuft sie analog.

Die Skalierung

Skalierung ([Nischwitz u. a. 2012] [Mukherjee 2004]) ist die Streckung einer Achse des lo-kalen Koordinatensystems. Dafür wird ein Skalierungsfaktor (Streckungsfaktor) eingesetzt,der positiv und negativ, aber nicht 0 sein darf. Wenn der Skalierungsfaktor negativ ist,erfolgt zusätzlich zur Streckung eine Spiegelung an der entsprechenden Achse. Bei einemSkalierungsfaktor mit einem Betrag kleiner als 1 erfolgt eine Stauchung der Achse. Beträgtder Faktor genau 1, bleibt die Dimension der Achse unverändert. Die hier beschriebeneSkalierung erlaubt die voneinander unabhängige Behandlung der drei Achsen des Koordi-natensystems.

8

2.3. 3-D-Computergrafik

Abbildung 2.4. Rotation (Bildquelle: Schlechtweg, Hochschule Anhalta)

ahttp://www.mttcs.org/Skripte/Pra/Material/vorlesung3.pdf.

Abbildung 2.5. Skalierung (Bildquelle: Schlechtweg, Hochschule Anhalta)

ahttp://www.mttcs.org/Skripte/Pra/Material/vorlesung3.pdf.

Deshalb muss jede von ihnen mit einem eigenen Faktor skaliert werden: v1 = (x1, y1, z1)T =(x ˚ Sx, y ˚ Sy, z ˚ Sz)T .

In homogenen Koordinaten: v1 = Sv =

Sx 0 0 00 Sy 0 00 0 Sz 00 0 0 1

xyzw

Abbildung 2.5 stellt die analog zum Raum verlaufende Skalierung in der Ebene dar.

2.3.3. Das Koordinatensystem

3-D-Computergrafik, die auf OpenGL basiert, verwendet ein Euklidisches Koordinaten-system mit drei Achsen. Dabei verläuft die positive x-Achse vom Betrachter vor demBildschirm (Augenpunkt) aus gesehen aufsteigend nach rechts. Die darauf senkrecht stehen-de positive y-Achse weist vom Betrachter aus gesehen von unten nach oben. Die senkrechtauf beiden Achsen angeordnete positive z-Achse verläuft so, dass sie vom Bildschirm ausauf den Betrachter weist. Zu beachten ist, dass dieser Grundsatz nur in solchen Visualisie-

9

2. Grundlagen und Technologien

Abbildung 2.6. Rechte-Hand-Regel (Bildquelle: Clemson School Of Computinga)

ahttps://people.cs.clemson.edu/~dhouse/courses/405/notes/coord-systems.pdf.

rungen gilt, bei denen keine Manipulation der Kamera (also des Blickfeldes) stattgefundenhat. Deshalb ist es einfacher, die Betrachtung als rechtshändiges Koordinatensystem zu nut-zen. Der Daumen der rechten Hand ist die positive x-Achse, der Zeigefinger die positivey-Achse. Der zu den anderen Fingern senkrecht ausgestreckte Mittelfinger weist dann denVerlauf der positiven z-Achse [Nischwitz u. a. 2012]. Abbildung 2.6 stellt die Anwendungdieser Regel dar.

In der 3-D-Computergrafik unterschieden wir außerdem mehrere Arten von (rechtshän-digen) Koordinatensystemen. Die Basis für die Visualisierung ist das Welt-Koordinatensystemoder Augenpunkt-Koordinatensystem. Dieses füllt die komplette dargestellte Szene aus[Nischwitz u. a. 2012]. Neben diesem Koordinatensystem existiert das Objekt-Koordinatensystem.Es handelt sich hierbei um ein lokales Koordinatensystem, das sich bei jedem Objektbefindet, das für die 3-D-Szene erzeugt worden ist. Jedes Objekt besitzt ein eigenes Objekt-Koordinatensystem. Innerhalb dieses Koordinatensystems wird die Form festgelegt, die dasObjekt besitzt. Kennzeichnend für das Objekt-Koordinatensystem ist außerdem, dass dieObjekte im Ursprung ihres eigenen Koordinatensystems zentriert sind [Brüderlin u. a. 2013].Zudem gibt es das Projektions-Koordinatensystem. Dieses kommt dann zur Anwendung,wenn eine Projektion stattgefunden hat. Hierbei geht es unter anderem um den Blickwinkel,mit dem die Szene vom Betrachter angesehen wird. Es gibt außerdem normierte Koordinatenund die Bildschirmkoordinaten. Letztere stellen die Szene in der Fenstergröße des Browsersdar [Nischwitz u. a. 2012].

Wenn eine 3-D-Visualisierung stattfindet, hat jedes dieser Koordinatensysteme einewesentliche Bedeutung. Zunächst werden – aus Vertices und Faces – alle Objekte erzeugt,die in der 3-D-Szene ihren Platz finden sollen. Das geschieht mithilfe der zugehörigen

10

2.3. 3-D-Computergrafik

Abbildung 2.7. Koordinatensysteme (Bildquelle: [Nischwitz u. a. 2012])

Objekt-Koordinatensysteme. Jedes so erzeugte Objekt findet mithilfe einer Transformationden ihm zugeordneten Platz in der Szene. Anschließend findet eine weitere Transformationstatt, die auf alle in der Szene befindlichen Vertices angewendet wird. Diese ermöglicht dieAnpassung der Szene an den Augenpunkt, der beschreibt, wo die Kamera liegt, die ein Bildder Szene macht. Die beiden Transformationen werden als Modell- und Augenpunkttrans-formation bezeichnet. Danach wird eine Projektionstransformation auf die Weltkoordinatenangewendet. Diese ermöglicht die Anpassung der Sichtweise, die das sichtbare Volumenbestimmt. Es wird das Bild bestimmt, dass sich aus der Betrachtung durch eine Kamera er-gibt, die in der gewünschten Weise eingestellt ist. Bei diesem Schritt kann es passieren, dassbestimmte Vertices außerhalb des sichtbaren Volumens liegen und deshalb durch Clippingentfernt werden müssen. Jetzt liegen Projektions-Koordinaten (Clipping-Koordinaten) vor, umdie Position der Objekte in der Szene zu beschreiben. Der folgende Schritt besteht in einerNormierung, die dem Zweck dient, Normierte Koordinaten zu erzeugen. Die Koordinatender Form (x, y, z) werden in das Intervall [´w,+w] transformiert. Anschließend werdensie durch w dividiert. Im letzten Schritt erfolgt eine Viewpoint-Transformation. Diese rechnetalle in der Szene befindlichen Vertices in die Koordinaten des Bildschirms um. Dabeifinden die Pixel Berücksichtigung, die das Bildschirmfenster aufweist [Nischwitz u. a. 2012][Nischwitz und Haberäcker 2013].

Die Abfolge der Berechnungen wird aus Abbildung 2.7 deutlich.

11

Kapitel 3

Entwicklung des Konzepts

In diesem Kapitel beschäftigen wir uns mit der Entwicklung des Konzepts, das deranschließenden Implementierung zugrunde liegt.

3.1. Die Einbindung in OceanTEA

Die Anwendung soll in OceanTEA eingebunden werden. Dazu erhält sie die benötig-ten Daten von der ihr zugeordneten Server-Struktur. Dies geschieht – entsprechend derMicroservices-Architektur – unabhängig von den anderen Vertikalen in OceanTEA. Umdies zu ermöglichen, muss die Implementierung auf Schnittstellen zugreifen, die bereitsaufbereitete Forschungsdaten übermitteln.

3.2. Sichtbarmachen des Koordinatensystems

Da es sich um eine Visualisierung wissenschaftlicher Daten handelt, muss der Nutzer dieMöglichkeit erhalten, die Lage einzelner Objekte im Raum ablesen zu können. Deshalb solldie Visualisierung ein sichtbares Koordinatensystem erhalten, das die Longitude-Latitude-Ebene repräsentiert. Dieses Koordinatensystem muss beschriftet sein, um das Ablesen zuerlauben.

3.3. Der Boden

Für den Boden erhält die Implementierung Daten vom Server. Diese Daten bestehenaus Punkten, die jeweils durch ein Tripel (Longitude, Latitude, Elevation) dargestelltsind. Im Programm sollen diese Punkte in Vertices umgerechnet werden, die jeweils eineentsprechende Lage im 3-D-Koordinatensystem besitzen. Dabei wird die Longitude derx-Achse zugeordnet, die Latitude der y-Achse und die Elevation der z-Achse. Die Faces desBodens sollen mit einem Farbverlauf ausgestattet werden, der es dem Nutzer ermöglichensoll, die Höhe des Bodens an einem bestimmten Punkt in der Longitude-Latitude-Ebeneabzulesen. Der Boden soll durch den Nutzer entfernt werden und wieder hinzugefügtwerden können. Dies dient dem Zweck der Übersichtlichkeit. Möchte er etwa nur dieStrömungen betrachten, kann es sein, dass der Boden dabei stört.

13

3. Entwicklung des Konzepts

3.4. Die Messstationen

Die Visualisierung erhält die Darstellung der Messstationen, die an den jeweiligen OrtenStrömungsdaten (Richtung und Stärke) aufgezeichnet haben. Der Nutzer soll die Namender Stationen ablesen können. Außerdem soll er die Möglichkeit haben, die Stationen ausder Darstellung zu entfernen und sie wieder hinzuzufügen. In der Region, deren Bodendargestellt wird, haben die Messstationen eine bestimmte Position. Auch diese wird durchdie Angabe von Latitude, Longitude und Höhe als Datensatz zur Verfügung gestellt. DieStationen müssen in der Darstellung an diesen Punkten auf dem Ozeanboden positioniertwerden. Die Messungen finden an Messelementen (Bins) statt, die an der Oberseite und /oder der Unterseite einer Station befestigt sind. Dabei sind die einzelnen Bins an einer Ketteüber- beziehungsweise untereinander befestigt. Auch das soll die Darstellung enthalten.

3.5. Darstellung der Strömungen

Ein weiterer wichtiger Bestandteil der Darstellung sind die an den Messstationen ermittel-ten Strömungsdaten.

3.5.1. Visualisierung durch Pfeile

Für jede Station, die sich in der Visualisierung findet, werden Strömungsdaten zur Verfü-gung gestellt, die eine zeitliche Abhängigkeit besitzen. Über einen bestimmten Zeitraumhinweg sind die Strömungen an einer Station in Intervallen gemessen worden. Die Messun-gen beziehen sich auf die Stärke und die Richtung der Strömung. Dargestellt werden solldie Strömung durch Pfeile, die jeweils eine bestimmte Länge und eine bestimmte Richtungbesitzen. Dabei geht von jedem Bin einer Station ein Pfeil aus.

3.5.2. Zeitliche Abhängigkeit

Da die Strömungen über einen längeren Zeitraum hinweg gemessen werden, um ihreEntwicklung zu beobachten, muss sich diese zeitliche Veränderung in der Visualisierungwiederfinden. Deshalb soll ein Slider implementiert werden, mit dem der Nutzer zueinem gewünschten Zeitpunkt wechseln kann. Ziel dieses Bestandteils soll nicht nur dieDarstellung zu einem ausgewählten Zeitpunkt sein. Es geht auch darum, die Entwicklungder Strömung über eine Zeitspanne hinweg beurteilen zu können.

3.5.3. Steuerung durch den Nutzer

Um einzelne Elemente der Darstellung genauer betrachten zu können, muss der Nutzerdie Möglichkeit haben, sich mittels Maus und Tastatur durch die Darstellung zu bewegen.

14

3.5. Darstellung der Strömungen

Dabei soll es einen Zoom geben, die Möglichkeit zum Verschieben der Darstellung (Pan)und die Möglichkeit einer Rotation.

15

Kapitel 4

Implementierung der 3-D-Visualisierung

In diesem Kapitel diskutieren wir die Implementierung, die das vorgestellte Konzeptumsetzt.

4.1. Aufbau der Webseite und Beschreibung der Funktio-nen

Die 3-D-Visualisierung ist in eine Webseite eingebettet, die über einen Browser aufgerufenwerden kann. Die Webseite selbst befindet sich im Tab Spatial Analysis der OceanTEA-Anwendung. Abbildung 4.1 zeigt den Aufbau der Webseite.

Auf der linken Seite sind oben die Buttons platziert, mit denen der Nutzer die ge-wünschte Region für die Darstellung auswählen kann. Zum Zeitpunkt der Abgabe dieserBachelorarbeit ist lediglich eine Region vorhanden. Diese zeigt ein Kaltwasserkorallenriffin Stjernsund in Nord-Norwegen1 [Ashastina 2013]. Sie wird im Initialbildschirm als ersteRegion geladen und durch den Button mit der Aufschrift Northern Norway dargestellt.

Auf der unteren Seite der Webseite befinden sich zwei Slider. Der obere, längere vonihnen ermöglicht die Auswahl eines Zeitpunkts für die symbolisierten Strömungsdaten. Erwird im Folgenden Time-Slider genannt. Der Tooltip des Time-Sliders zeigt den gewähltenZeitpunkt im UTC-Format (Abbildung 4.2).

Der untere Slider, den wir als Speed-Slider bezeichnen, wird im Zusammenhang mit derAutoplay-Funktion verwendet. Diese zeigt alle Strömungsdaten in der zeitlichen Reihenfol-ge ihrer Messung nacheinander. Über den unteren Slider kann der Nutzer einstellen, wieschnell das Autoplay ablaufen soll. Er kann dabei zwischen 0.5 Sekunden und 10 Sekundenwählen. Nach Ablauf des so gewählten Zeitraums wird beim Autoplay jeweils ein neuerDatensatz für die Darstellung der Strömungen geladen. Die ausgesuchte Sekundenzahlgibt also an, wie schnell das Autoplay abläuft. Zu den Slidern gehört der Play-Button, mitdem der Nutzer die Autoplay-Funktion aktivieren und wieder deaktivieren kann.

Auf der oberen rechten Seite des Bildschirms finden sich Checkboxen und weitere But-tons, die im Folgenden – ihrer Aufschrift entsprechend – als Help-Button und Reset-Buttonbezeichnet werden. Mit ihnen kann der Nutzer Elemente der Darstellung beeinflussen.Über den Help-Button erhält er Informationen zur Steuerung der Kamera. Der Reset-Button

1http://www.geomar.de/index.php?id=4&no_cache=1&tx_ttnews%5btt_news%5d=781&tx_tt-news%5bbackPid%5d=185

17

4. Implementierung der 3-D-Visualisierung

Abbildung 4.1. Aufbau der Webseite

Abbildung 4.2. Time-Slider

setzt die Kamera zum initialen Zustand zurück. Die genannten Buttons und Checkboxensind in Abbildung 4.3 zu sehen.

Es existieren vier Checkboxen. Diejenige mit der Aufschrift Ocean Floor Visible erlaubtes dem Nutzer, die Darstellung des Bodens zu entfernen und wieder hinzuzufügen. DieCheckbox Stations Visible lässt den Würfel, der die Messstation symbolisiert, unsichtbaroder sichtbar werden. Diese Funktion bezieht sich nur auf den Würfel als solchen; die ausdem Würfel hervorgehenden Bins und Pfeile bleiben davon unberührt. Bei der CheckboxColor Gradient On Arrows Visible geht es darum, ob die Markierungen der Pfeile einenFarbverlauf tragen (Abbildung 4.4) oder einheitlich rot (Abbildung 4.5) sein sollen. DerFarbverlauf bezieht sich immer auf die Bins, die eine Station in einer Richtung hat. Er hilftdem Betrachter dabei, die unterschiedlichen Höhen der Pfeile und damit der gemessenenStrömungen besser zu unterscheiden. Er macht es auch möglich, die Strömungen und ihreEntwicklung in einzelne räumliche Abschnitte einzuteilen. Die Checkbox Arrows Visibleschließlich lässt die Pfeile bei Entfernen des Hakens verschwinden und nach dem Setzen

18

4.1. Aufbau der Webseite und Beschreibung der Funktionen

Abbildung 4.3. Checkboxen

wieder auftauchen. Alle Checkboxen sind beim Laden einer neuen Region markiert.

Innerhalb der Darstellung kann der Nutzer den Ozeanboden betrachten, der sich aufeiner weißen Ebene mit aufgezeichnetem Koordinatensystem befindet. Das Koordinatensys-tem gibt Latitude und Longitude der symbolisierten Höhendaten an. Auf dem Ozeanbodenbefinden sich Messstationen, die jeweils einen bestimmten Namen haben. Die Position derMessstationen in der Visualisierung entspricht der Position von Messstationen, die in derdarzustellenden Region platziert waren. Diese zeichneten Strömungen auf und liefertendie entsprechenden Datensätze. Die Messstationen sind in Abbildung 4.6 zu sehen.

Von den Messstationen gehen Bins aus, die die Eigenschaften der an ihnen vorbeiflie-ßenden Strömung messen. In der Darstellung sind sie als Kugeln symbolisiert, die an einerKette über- beziehungsweise untereinander an der Ober- oder Unterseite einer Stationplatziert sind. Eine Station kann an beiden Seiten oder nur an einer Seite Bins besitzen.Bins zeigt Abbildung 4.7.

Symbolisiert werden die Strömungen durch Pfeile, die von den Bins ausgehen. DieRichtung der Pfeile zeigt die Richtung der gemessenen Strömung zum ausgewähltenZeitpunkt. Ihre Länge steht für die Strömungsstärke in Millimetern pro Sekunde. Die Pfeilesind mit Markierungen versehen, die jeweils für zusätzliche 50 Millimeter pro SekundeStrömungsgeschwindigkeit stehen. Ein entsprechender Pfeil ist in Abbildung 4.8 zu sehen.

Bestandteil der Visualisierung ist außerdem eine Lookup-Table (Abbildung 4.11), die demFarbverlauf des dargestellten Ozeanbodens Höhen zuordnet. Enthalten ist weiterhin einPfeil (Abbildung 4.8), der dem Nutzer eine Hilfestellung für das Ablesen der Pfeillängengibt. Dieser Pfeil wird im Folgenden als Maßstabspfeil bezeichnet.

Der Nutzer hat die Möglichkeit, die Darstellung mittels Maus und Pfeiltasten zu steuern.Mit der linken Maustaste und einer Mausbewegung kann er die Darstellung rotieren.Denselben Effekt kann er erzeugen, indem er einen Finger auf dem Touchpad bewegt.Heran- oder herauszoomen kann er mit der mittleren Maustaste oder dem Mausrad odermit der öffnenden / schließenden Bewegung von zwei Fingern auf dem Touchpad. Pannen,also verschieben, kann er die Darstellung mit der rechten Maustaste, den Pfeiltasten odermit drei Fingern auf dem Touchpad.

19

4. Implementierung der 3-D-Visualisierung

Abbildung 4.4. Pfeile mit Farbverlauf

4.2. Architektur

Die Implementierung besteht aus einer HTML-Datei, CSS-Dateien und mehreren JavaScript-Dateien. Die JavaScript-Dateien sind in die HTML-Seite eingebunden. Sie enthalten den inThree.js geschriebenen Quellcode. Abbildung 4.9 zeigt die Architektur der Implementie-rung.

4.3. Implementierung

Die Basis der Visualisierung ist eine HTML-Datei. In diese sind die JavaScript-Dateieneingebunden, die den Three.js-Code enthalten. Der in den Dateien befindliche Source-Code

20

4.3. Implementierung

Abbildung 4.5. Pfeile ohne Farbverlauf

wird beim Laden der HTML-Datei im Browser aufgerufen.Die Visualisierung startet, indem window.onload = init in der Datei main.js ausgeführt

wird. Der Aufruf von window.onload geschieht dann, wenn das HTML-Dokument im Brow-serfenster geladen wurde, wobei auch die zugehörigen Stylesheets einbezogen wurden. DieZuordnung von init bewirkt, dass nun die in main.js befindliche init()-Funktion ausgeführtwird.

Die init()-Funktion enthält alle Aufrufe, die beim erstmaligen Laden der Visualisierungausgeführt werden müssen. Hier werden Elemente geladen, die sich dauerhaft in derVisualisierung befinden, also auch dann, wenn der Nutzer eine neue Region ausgewählt.Sie steht damit der show()-Funktion in der Datei main.js gegenüber. Die show()-Funktionwird nicht nur beim erstmaligen Laden, sondern auch beim Betrachten einer neuen Regionausgeführt.

In der init()-Funktion muss zunächst sichergestellt werden, dass der Nutzer die Check-boxen solange nicht bedienen kann, bis der zugehörige Inhalt geladen wurde. Deshalbwird für alle vier Checkboxen .disabled = true ausgeführt.

Anschließend wird ein neues Scene-Objekt erzeugt, das die Basis für die 3-D-Visualisierungist. Ein Clock-Objekt ist für die interaktive Steuerung erforderlich und wird deshalb eben-

21

4. Implementierung der 3-D-Visualisierung

Abbildung 4.6. Messstationen

falls erzeugt. Wesentlich für die Darstellung ist außerdem ein Renderer-Objekt. Der Rendererist dafür zuständig, das zweidimensionale Bild der 3-D-Szene zu erzeugen, das für dieDarstellung auf dem Bildschirm benötigt wird [Comninos 2010]. Dieses wird an dieGröße des Fensters angepasst ( renderer.setSize( window.innerWidth, window.innerHeight )) und es erhält außerdem Grau als Hintergrundfarbe. Durch document.body.appendChild(renderer.domElement ) wird es Bestandteil der Webseite.

22

4.3. Implementierung

Abbildung 4.7. Bins

Abbildung 4.8. Strömungspfeil

4.3.1. Die Slider

Im Anschluss daran werden über die Funktion loadSlider() die beiden Slider geladen. Diesgeschieht über einen Aufruf in der init()-Funktion, da der Speed-Slider zum Einstellen derGeschwindigkeit in jeder Region dasselbe Aussehen hat. Der Time-Slider zur Auswahldes Zeitpunkts wird beim Laden einer neuen Region über die Anpassung seines kleinstenund größten Wertes verändert, bleibt aber als Teil der Visualisierung über den gesamtenProgrammverlauf hinweg erhalten.

In loadSlider() werden der timeSlider und der speedSlider initialisiert. Der timeSlider er-

23

4. Implementierung der 3-D-Visualisierung

laubt dem Nutzer die Auswahl des Zeitpunkts, für den die Strömungsdaten visualisiertwerden. Der speedSlider gibt die Geschwindigkeit des Autoplays an. Beide Slider sindbootstrap-slider2. Sie werden innerhalb der main.html-Datei eingebunden und im Rahmenvon guistyle.css an ihre Position auf der Webseite gesetzt.

Über den Aufruf der formatter-Option wird der Wert festgelegt, den die Slider in ihremTooltip zurückgeben. Da der Speed-Slider mit Werten in Millisekunden umgeht, muss seinRückgabewert in Sekunden umgerechnet werden. Der Time-Slider gibt das ausgesuchteDatum im UTC-Format zurück. Die Umrechnung in dieses Format geschieht dadurch, dasszunächst ein Date-Objekt aus dem Slider-Wert (value) erzeugt wird. Dieses Objekt erhältdie Anzahl der Millisekunden, die vom 1.1.1970 aus gerechnet am betreffenden Datumabgelaufen sind. Mit dem Aufruf toISOString() wird die Umrechnung in das UTC-Formaterzielt.

Der Speed-Slider erhält außerdem einen Minimalwert von 500 Millisekunden und einenMaximalwert von 10000 Millisekunden. Seine Position beim Laden der Seite wird auf 3000Millisekunden – also 3 Sekunden – festgesetzt. Seine Schrittweite beträgt 500 Millisekunden.Der Nutzer kann also den Slider in 0.5-Sekunden-Einheiten verstellen.

Im nächsten Schritt erfolgt der Aufruf der Funktionen whatTheTimeSliderDoes() undwhatTheSpeedSliderDoes(). Diese bestimmen das Verhalten der beiden Slider, wenn sie durchden Nutzer bewegt werden. In beiden Fällen wird zwischen slideStart und slideStop un-terschieden. In Verbindung mit dem Test originalTimeVal != timeValue beziehungsweiseoriginalSpeedVal != speedValue wird auf diese Weise erreicht, dass der jeweilige Slider nurdann feuert, wenn der Nutzer den Wert auf dem Slider tatsächlich verändert (und ihn nichtnur angeklickt) hat.

Wenn der Time-Slider bewegt wird, ruft er mit dem ausgesuchten Wert moveArrows()auf. Diese Funktion bewirkt, dass sich die Strömungspfeile verändern – sie nehmen fürjedes Bin an jeder Station die Länge und den Winkel an, die in dem vom Server geladenenDatensatz erhalten sind. Welcher Datensatz dabei geladen wird, ist abhängig von demWert, der auf dem Slider ausgesucht wird. Der initiale Aufruf der Funktion durch denTime-Slider übergibt die Parameter stationsOfCurrentRegionList[0], timeValue und arrowCoun-ter. moveArrows() ist so aufgebaut, dass die Liste der Stationen in der gerade visualisiertenRegion – stationsOfCurrentRegionList – durchlaufen wird. Dabei stellt arrowCounter dieZählvariable dar, mit der die einzelnen Werte des Arrays nacheinander ausgelesen werden.Der in timeValue gespeicherte Wert ist derjenige, der auf dem timeSlider ausgesucht wurde.

Die Funktion moveArrows() deaktiviert zunächst die Funktionalität der Checkbox ar-rowsVisibleCheckbox. Das verhindert, dass während der Pfeilbewegung auf die Pfeile zuge-griffen werden kann. Dies könnte Fehler in der Darstellung verursachen. Außerdem wirdmit document.getElementById( ’arrowsVisibleCheckbox’ ).checked = true; scaleArrow.visible = true;sichergestellt, dass mit dem Erscheinen der Pfeile durch die Bewegung bei einem Autoplayauch die zugehörige Checkbox gesetzt wird und der Maßstabspfeil sichtbar ist.

2https://github.com/seiyria/bootstrap-slider.

24

4.3. Implementierung

Die Variablen upLoad und downLoad enthalten die Aufrufe, die den gewünschten Da-tensatz vom Server laden. Die Speicherung der Aufrufe in den Variablen ist erforderlich,damit die Abfrage vom Server nur dann ausgeführt wird, wenn Bins in der entsprechendenRichtung (up und / oder down) an der einzelnen Station vorhanden sind. Wir beachten da-bei, dass das Laden der Daten innerhalb einer $.when().then()-Struktur geschieht. Es handeltsich hierbei um einen jQuery-Funktionsaufruf. Der Code im then-Abschnitt wird erst dannausgeführt, wenn das Laden der Daten vom Server innerhalb des when-Teils abgeschlossenwurde. Dadurch, dass die $.ajax-Befehle in den Variablen upLoad und downLoad gespeichertsind, wird ermöglicht, dass das Laden vom Server nur dann geschieht, wenn mindestensein Bin in der betreffenden Richtung an der Station vorhanden ist.

Die vom Server geladenen Daten werden für den Aufruf von station.moveUpArrows()beziehungsweise station.moveDownArrows() verwendet. Das sind Funktionen, die die in derjeweiligen Richtung vorhandenen Pfeile an einer Messstation bewegen. Diese erhalten dievom Server geladenen Daten (Länge und Richtung der Pfeile) sowie die Angabe, ob derFarbverlauf an den Pfeilen einer Station zu sehen sein soll.

Nach dem Laden der Daten und dem Ausführen der genannten Funktionen wird inmoveArrows() die Zählvariable arrowCounter hochgezählt. Falls ein Autoplay stattfindet,muss getestet werden, ob die Pfeile in allen Richtungen an allen Stationen bewegt wurden(weil nur dann der Slider zum nächsten Abruf weitergehen soll). Deshalb wird eine weitereZählvariable über AutoplayNS.incNumberOfMovedArrowDirections() inkrementiert. Die Ab-frage if ( arrowCounter < stationsOfCurrentRegionList.length ) nimmt die Fallunterscheidungvor, die besagt, ob ein weiterer rekursiver Aufruf stattfinden muss. Falls kein weitererAufruf stattfindet, wird die Checkbox über document.getElementById( ’arrowsVisibleCheckbox’).disabled = false wieder bedienbar.

Der Speed-Slider (in whatTheSpeedSliderDoes()) ermöglicht es dem Nutzer, die Geschwindig-keit beim Autoplay zu regeln. Er bestimmt, nach welchem Zeitraum ein neuer Datensatzfür die Strömungspfeile vom Server geladen wird. Wird er verändert, muss ein eventuellzu diesem Zeitpunkt laufendes Autoplay in seiner Geschwindigkeit angepasst werden. Dasgeschieht über AutoplayNS.resetPlay( timeIntervalTillAutoplayMovement ), wobei timeInter-valTillAutoplayMovement der neu ausgesuchte Wert ist. Die Funktion bezieht sich auf dieVariable AutoplayNS.playButtonActivated. Hierin ist gespeichert, ob gerade ein Autoplaystattfindet – ein in einer Schleife ablaufender wiederholter Aufruf von AutoplayNS.play. Istgerade ein Autoplay aktiv, wird dieses über clearInterval( AutoplayNS.playButtonActivated )angehalten. Danach wird der zeitliche Abstand des Schleifenaufrufs über den übergebenenWert timeIntervalTillAutoplayMovement neu gesetzt. Auf diese Weise kann das Autoplaykontinuierlich ablaufen und endet erst, wenn der Nutzer den Play-Button erneut anklickt.

25

4. Implementierung der 3-D-Visualisierung

4.3.2. Die erste Region

Nach dem Aufruf von loadSlider() werden in der init()-Funktion einige Daten vom Servergeladen, die für den gesamten Programmverlauf konstant bleiben. In stations wird einArray gespeichert, das alle vorhandenen Messstationen enthält. Dabei wird nicht zwischeneinzelnen Regionen unterschieden. Die Variable regions enthält eine Liste aller vorkom-menden Regionen. In regionNames werden die Namen der Regionen hinterlegt. Das Ladenvom Server geschieht im Rahmen einer $when().then()-Verknüpfung. Erst, wenn alle Datenerfolgreich geladen wurden, wird der then-Teil ausgeführt. Dort erfolgt ein Aufruf derFunktion loadFirstRegion()

In loadFirstRegion() wird die erste Region geladen, also die Region, die dargestellt wird,wenn die Seite aufgerufen oder neu geladen wurde. Hierzu wird diejenige Region ver-wendet, die in der regions-Liste an der ersten Stelle steht. Über den Download vom Serverwerden die für den Aufbau der Region wesentlichen Daten ermittelt. Sie beziehen sichauf wichtige Eigenschaften, die der Ozeanboden besitzt. Zu beachten ist dabei, dass dieLatitude der y-Achse und die Longitude der x-Achse der Darstellung zugeordnet wird. DieHöhe wird durch die Größe Elevation angegeben, die für die Höhe über dem Meeresspiegelsteht.

Die wesentlichen Daten sind:

Der kleinste gemessene Wert für die Latitude – in smallesty zu speichern

Der kleinste Wert für die Longitude – in smallestx

Der größte gemessene Wert für die Latitude – biggesty

Der größte Wert für die Longitude – biggestx

Größter und kleinster Wert für die Elevation – minelevation und maxelevation

Vertices (vertices) und Faces (faces) –Punkte und die Punkte verbindende Flächen, diedie gemessene Struktur des Bodens angeben. Die Punkte beziehen sich auf Einträgein lat und lon.

Die Arrays lat und lon, die die gemessenen Longituden und Latituden für einzelnePunkte darstellen

Nach dem erfolgreichen Laden werden createGui(), show() und render() aufgerufen. create-Gui() sorgt für den Aufbau des User-Interfaces, also für die Funktionalität der Buttons unddie Platzierung von Hilfsmitteln, die den Nutzer beim Ablesen von Daten unterstützen.Bei der show()-Funktion geht es darum, Daten zu laden, die bei jeder neuen Region anderssind – also Daten, die sich nach dem Klick auf einen der Regionen-Buttons ändern.

26

4.3. Implementierung

4.3.3. Das User-Interface

Die Funktion createGui() ruft ihrerseits drei Funktionen auf, die dazu beitragen, das User-Interface aufzubauen. Dies sind: createButtons(), createLookupHelpers() und createRegionBut-tons().

Über createButtons() werden Play-Button, Reset-Button und Help-Button mit Funktiona-lität ausgestattet. Der Help-Button gibt dem Nutzer nähere Informationen dazu, wie ersich in der Darstellung bewegen kann. Dies geschieht über ein alert, also ein sich öffnendesFenster, das mit einem Mausklick wieder geschlossen werden kann.

Der Reset-Button setzt die Darstellung – genauer: die Kamera – wieder auf den ur-sprünglichen Zustand zurück. Damit kann der Nutzer wieder zum Ausgangszustandzurückkehren, wenn er erfolgte Veränderungen rückgängig machen möchte. Hierzu wirddie Methode controls.reset() aufgerufen. Diese bezieht sich auf die THREE.OrbitControls, dieebenfalls Bestandteil der Visualisierung sind. Diese sind die Basis für die Bewegung überDrehung (Orbit), Zoom und Pan.

Der Play-Button schließlich dient dem Zweck, das Autoplay auf dem Slider ablaufenzu lassen. Dieser erhält seine Funktionalität über AutoplayNS.createPlayButton(). Hier wirdzunächst über AutoplayNS.resetIndex() AutoplayNS.autoplayIndex = 0 gesetzt. Diese Variabledient als Index für das Durchlaufen des Arrays, indem alle vorkommenden Strömungs-daten gespeichert sind. Anschließend wird AutoplayNS.autoplay = !AutoplayNS.autoplaygesetzt – das Autoplay also aktiviert oder deaktiviert. Wenn das Autoplay nach demButtonklick aktiv ist (AutoplayNS.autoplay = true), dann wird bei der folgenden if-else-Abfrage der if -Teil beschritten. Hier wird in timeIntervalTillAutoplayMovement zunächst dieGeschwindigkeit des Autoplays gespeichert, die vom speedSlider abgelesen wird. Danachwird playButton.className = "btn btn-primary oceanteaSelectionBtn active" gesetzt. So siehtder Nutzer an der Färbung des Buttons, ob das Autoplay gerade abläuft. Danach wirddas Autoplay aktiviert – über AutoplayNS.playButtonActivated = setInterval( AutoplayNS.play,timeIntervalTillAutoplayMovement ). Durch setInterval() wird bestimmt, dass die FunktionAutoplayNS.play wiederholt in einer Schleife aufgerufen wird, wobei der Wert in timeIn-tervalTillAutoplayMovement angibt, in welchem zeitlichen Abstand die Wiederholungenzueinander liegen sollen.

Wenn hingegen AutoplayNS.autoplay = false gilt, dann erhält der Play-Button zunächstseine ursprüngliche Färbung (über playButton.className = "btn btn-primary oceanteaSelec-tionBtn"). Über clearInterval(AutoplayNS.playButtonActivated) wird die laufende Schleifegelöscht.

Die Funktion AutoplayNS.play() findet sich ebenfalls in der Datei slider.js. Die VariableAutoplayNS.autoplayIndex besagt, welcher Zeitstempel vom Server geladen werden soll.Zunächst wird in AutoplayNS.play der aktuelle Wert des timeSliders in der Variable current-Value gespeichert. Dieser Wert wird benötigt, um festzustellen, ob AutoplayNS.autoplayIndexinkrementiert werden muss. Dies betrifft Situationen, in denen das Autoplay nicht vomStartwert des timeSliders aus gestartet wird, sondern bei denen der timeSlider bereits

27

4. Implementierung der 3-D-Visualisierung

nach vorne geschoben wurde. In einer While-Schleife wird der Wert so lange erhöht, wiecurrentValue >= listOfAllTimestamps[ AutoplayNS.autoplayIndex ] gilt. Wenn der Nutzer denTimeSlider nach rechts gezogen hat, läuft das Autoplay also immer von dieser Position ausweiter.

Geprüft wird nun innerhalb von AutoplayNS.play, ob AutoplayNS. numberOfMovedAr-rowDirections >= numberOfStationDirections && AutoplayNS. autoplayIndex < listOfAllTime-stamps.length gilt. Der erste Teil dieser Prüfung, AutoplayNS. numberOfMovedArrowDirections>= numberOfStationDirections, verhindert, dass der Slider beim Autoplay weitergleitet, ob-wohl noch nicht alle Pfeile ihren neuen Platz eingenommen haben. Dieser Teil dient alsoder Synchronisierung von Slider und Pfeilen. Die Variable AutoplayNS. numberOfMovedAr-rowDirections wird über AutoplayNS. incNumberOfMovedArrowDirections hochgesetzt,was in moveArrows() geschieht.

Beim Autoplay wird der Time-Slider deaktiviert, ($(’#timeSlider’).slider( ’disable’ )) undwird beim Ausschalten des Autoplays wieder aktiviert ($(’#timeSlider’).slider( ’enable’ )).

Bei AutoplayNS.autoplayIndex < listOfAllTimestamps.length geht es darum, dass das Auto-play keine wesentlichen Aufrufe mehr ausführen soll, wenn es das Ende des Timesliderserreicht hat.

Ist die oben genannte Bedingung erfüllt, wird der Wert aus listOfAllTimestamps gele-sen, bei dem sich AutoplayNS.autoplayIndex gerade befindet. Auf diesen Wert wird derTime-Slider gesetzt. Danach wird moveArrows für den betreffenden Wert aufgerufen, umSlider und Pfeile zu synchronisieren. Dann wird AutoplayNS.autoplayIndex inkrementiert.Dies dient dem nächsten Aufruf von AutoplayNS.play, bei dem der nächste Wert aus listO-fAllTimestamps folgen soll. Außerdem wird AutoplayNS.numberOfMovedArrowDirections = 0gesetzt, um im nächsten Aufruf die genannte if -Abfrage zu ermöglichen.

Der Aufruf von createLookupHelpers() erzeugt die Lookup-Table für die Höhen des Bo-dens und den Pfeil, an dem die Abstände der Markierungen abgelesen werden können.

Das Problem, das hier gelöst werden musste, war das Erfordernis einer statischen,zweidimensionalen Darstellung dieser eigentlich dreidimensionalen Objekte. Es musstevermieden werden, dass sich diese beiden Objekte beim Verschieben der Sicht im Rahmender Steuerung ebenfalls bewegen. Das Problem wurde gelöst, indem zwei neue Renderergeschaffen wurden – lutRenderer und arrowRenderer – die sich unabhängig von der Haupt-Szene verhalten. Diese werden in eigene div-Elemente auf der Seite platziert und sindvon der Steuerung ausgeschlossen. Mithilfe der richtigen Positionierung der jeweiligenKamera ist es so möglich, die Lookup-Table und den Pfeil an derselben Stelle auf demBildschirm zu halten, obwohl sich der Nutzer durch die Darstellung bewegt. Durch dasSetzen von alpha: true wird bewirkt, dass der Hintergrund der Renderer transparent ist.Das ist erforderlich, damit wirklich nur die Lookup-Table und der Pfeil in der Darstellungerscheinen und von dem Hintergrund der beiden Renderer ansonsten nichts sichtbar ist. Sokann zum Beispiel auch der Boden unter die anderen Renderer geschoben werden, ohnedass ein optischer Bruch entsteht. Eine solche Situation zeigt Abbildung 4.10.

28

4.3. Implementierung

In createRegionButtons() werden die Buttons erzeugt, die das Laden einer anderen Regionermöglichen. Welche Buttons erscheinen, hängt davon ab, welche Regionen auf dem Serverzu finden sind. Diese sind in der Liste regions gespeichert worden. Beschrieben wird derButton mit dem Namen der Region, der er zugeordnet ist. In button.onclick wird festgelegt,welche Abläufe beim Laden einer neuen Region stattfinden. Es geht darum, den Bodenund die Stationen der vorher dargestellten Region zu entfernen und weitere Darstellungen– etwa die Lookup-Table oder den Slider – neu zu berechnen. Zunächst werden alleCheckboxen markiert. Denn beim Laden einer neuen Region sollen alle Elemente aufihren Initialzustand gebracht werden. Dazu gehört auch, dass vorher durch den Nutzerunsichtbar gemachte Elemente wieder in der Darstellung erscheinen. Durch den Aufrufvon scene.remove werden der Ozeanboden, die Darstellung des Koordinatensystems, dieStationen mitsamt den Pfeilen und die Lookup-Table aus der Darstellung entfernt. Eineventuell laufendes Autoplay wird zurückgesetzt. Außerdem wird der Nutzer durch dieSetzung von .disabled = true davon abgehalten, während des Ladevorgangs die Checkboxenoder Buttons zu bedienen und damit Fehler in der Darstellung hervorzurufen. Um dieDaten vom Server zu laden, muss hinter der URL die ausgewählte Region angegebenwerden. Diese wurde in der button.id des angeklickten Buttons hinterlegt. Die relevantenDaten für die Region werden vom Server geladen. Anschließend wird show() aufgerufen,um weitere Berechnungen durchzuführen.

4.3.4. Die show()-Funktion

In der show()-Methode werden zunächst einige Variablen (neu) gesetzt. Die Gruppen sta-tionsGroup, labelingGroup und lineGroup werden durch eine neue Wertzuweisung geleert,damit sie mit neu geladenen Daten neu befüllt werden können. Das gilt auch für numberOf-StationDirections, die Anzahl der Richtungen, die es bei den Stationen in der Visualisierungin der Summe gibt.

Aufgerufen wird anschließend die Methode getMinAndMaxForSliderAndTimestamps(). Diesehat den Zweck, den Timeslider neu zu berechnen. Das ist erforderlich, da die einzel-nen Regionen unterschiedliche Zeitstempel abdecken können. Die Funktion ist rekursivaufgebaut. Sie durchläuft alle Stationen, die der fraglichen Region zugeordnet sind undstellt auf diese Weise das Minimum und das Maximum des Timesliders fest. Außerdemwird zeitgleich eine Liste angelegt, die alle Timestamps enthält, die die Stationen in derRegion insgesamt haben. Jeder Aufruf der Funktion betrifft eine Station, die in der Re-gion vorhanden ist. Zunächst wird die Liste der Timestamps heruntergeladen, die fürdie jeweilige Station hinterlegt ist. Diese Liste ist aufsteigend geordnet, sodass der ersteWert der kleinste und der letzte Wert der größte ist. Das für die jeweilige Station geltendeMinimum wird berechnet, indem treference in Sekunden umgerechnet und der kleinsteTimestamp(data.timestamps[0]) darauf addiert wird. Für das Maximum wird entsprechendder größte Wert, data.timestamps[data.timestamps.length-1], verwendet. Beide Werte werdendann in jeweils in ein Array gespeichert. Das Array sliderMins enthält die kleinsten Werte

29

4. Implementierung der 3-D-Visualisierung

aller Stationen aus der Region und sliderMaxs die größten Werte. Anschließend wird eineentsprechende Berechnung mit allen Timestamps der Station durchgeführt. Die einzelnenErgebnisse werden im Array listOfAllTimestamps gespeichert. Diese Liste wird relevant fürdie Autoplay-Funktion, bei der alle verfügbaren Datensätze durchlaufen werden sollen.Nach Durchführung der Berechnungen für eine Station geschieht eine Fallunterscheidung.Ist die Liste der Stationen noch nicht vollständig durchlaufen, wird die Funktion rekursivaufgerufen, wobei die Arrays sliderMins, sliderMaxs und listOfAllTimestamps schrittweisegefüllt werden. Sind alle Stationen durchlaufen, muss listOfAllTimestamps aufsteigendsortiert werden, damit sie später als sinnvolle Basis für das Autoplay dienen kann. DieSortierung geschieht mithilfe des Aufrufs listOfAllTimestamps.sort(function(a, b)return a-b).

Daran anschließend müssen mögliche Duplikate entfernt werden. Der hierzu dienendeFunktionsaufruf ist listOfAllTimestamps = deleteDoubleEntries(listOfAllTimestamps). Die Funk-tion deleteDoubleEntries() arbeitet mit dem Prinzip, bereits gesehene Werte zu speichern.Bevor dann ein neuer Wert in das Ausgabearray arrayWithoutDoubleEntries übernommenwird, wird die Liste der bereits gesehenen Werte durchlaufen und auf diesen Wert hinüberprüft.

Nach dem Sortieren und dem Entfernen von eventuellen Duplikaten wird der kleins-te Wert in sliderMins und der größte Wert in sliderMaxs berechnet. Dies geschieht dadurch,dass zunächst der erste Wert des zugehörigen Arrays als Minimum beziehungsweise Maxi-mum festgelegt wird. Danach werden die beiden Arrays jeweils durchlaufen und es wirdgetestet, ob der gerade aktuelle Wert kleiner beziehungsweise größer ist als der gerade inder Variable gespeicherte. Ist das der Fall, wird die Variable mit dem neuen, besseren Wertbelegt. Nach dem Durchlaufen der Arrays stehen dann sliderMin und sliderMax fest. Mitden so ermittelten Werten werden Minimum und Maximum des Timesliders neu berechnet.

In der show()-Funktion geht es nun damit weiter, dass die Kamera (neu) gesetzt wird.Die Kamera ist eine THREE.PerspectiveCamera. Das Aussehen der Kamera muss davonabhängen, wie groß der Ozeanboden der gerade dargestellten Region ist. Deshalb wird derParameter Camera frustum far plane, der letzte der vier Parameter, an die Gegebenheitender Region angepasst. Hierzu werden zunächst die Werte diffxToNextThousand und diffy-ToNextThousand berechnet. Sie enthalten den auf den nächsten Tausender aufgerundetenAbstände zwischen dem minimalen und maximalen Wert auf der x-Achse beziehungsweiseauf der y-Achse. An den größeren dieser beiden Werte wird die Kamera angepasst. DasZiel dieser Anpassung besteht darin, dass die Kamera den kompletten Boden einfangensoll, ohne dass sie dabei zu groß / weit für den Boden wirkt. Das Minimum ist dabei einWert von 10000.

In show() wird außerdem camera.up.set( 0, 0, 1) festgelegt. Auf diese Weise wird derVektor verändert, um den sich die Kamera beim Verschieben der Maus bei gedrücktgehaltener linker Maustaste dreht. Diese Festlegung ist damit für die THREE.OrbitControlsrelevant. Nach dieser Festlegung dreht sich die Kamera um einen Vektor, der parallel zur

30

4.3. Implementierung

z-Achse verläuft und der durch die Ebene geht, auf der der Ozeanboden liegt.

4.3.5. Die Lookup-Table

Im nächsten Schritt muss die Lookup-Table aufgebaut werden. Auch dies geschieht inner-halb der show()-Funktion, da sich die Markierungen auf der Tafel nach dem Verlauf derBodenhöhen der jeweiligen Region richten. Deshalb muss sie nach jedem neuen Ladeneiner Region angepasst werden. Das Laden erfolgt in der Methode loadLut(), die in derDatei lut.js vorliegt. In der Funktion wird ein neues Lut-Objekt erzeugt und in der Variablelut gespeichert.

Abbildung 4.11 zeigt die Lookup-Table. Die Lookup-Table erhält eine Beschriftung,damit der Nutzer aus dem Farbverlauf die jeweilige Höhe des Bodens ablesen kann. DieseBeschriftung ist abhängig von der maximalen und der minimalen Höhe. Diese ergeben sichaus den Werten minheight und maxheight, die vom Server für die betreffende Region herun-tergeladen wurden. Diese Werte müssen gerundet werden, um ein angenehmes Ablesen zuermöglichen. Diese Rundung geschieht mithilfe der Funktionen roundToOverlyingHundredsund roundToUnderneathHundreds. Der kleinste Wert, den die Bodenhöhe hat, wird auf dendarunter liegenden Hunderter gerundet. Der größte Wert wird auf den über ihm liegendenHunderter gerundet.

Die Lookup-Table erhält ihre Beschriftung durch den folgenden Aufruf: labels = lut.setLegendLabels( ’title’: ’Height’, ’um’: ’m’, ’ticks’: 5 ). Der Nutzer erfährt damit, dass erdie Höhe in Metern ablesen kann. Außerdem besitzt die Lookup-Table fünf Ticks, alsoMarkierungen, an denen die zur angezeigten Farbe gehörende Höhe ablesbar ist.

4.3.6. Die Steuerung

Nach dem Aufruf von loadLut() wird die Steuerung initialisiert. Dies geschieht durch dieCode-Zeile controls = new THREE.OrbitControls( camera ). Der Steuerung liegen also dieTHREE.OrbitControls zugrunde. Hierbei handelt es sich um eine vorimplementierte Klasse,die im Three.js-Quellcode zu finden ist. Wie die Steuerung funktioniert, haben wir bereitsbesprochen.

4.3.7. Das sichtbare Koordinatensystem

Im nächsten Schritt ist es erforderlich, das sichtbare Koordinatensystem zu erzeugen. Aufdiesem befindet sich der Ozeanboden. Die Funktion, die das gewünschte Koordinatengittererzeugt, ist calculateGridDistancesAndAddGrid() in der Datei grid.js. Diese Funktion führtzunächst einige Berechnungen durch und ruft dann die Funktion addGrid() auf, die danndas Gitter der Darstellung hinzufügt. Die Berechnungen dienen dem Zweck, die Abständeder Markierungen zu berechnen. Diese sollen davon abhängen, wie groß (oder klein) derdargestellte Boden ist. In Abbildung 4.12 ist das Koordinatensystem zu sehen.

31

4. Implementierung der 3-D-Visualisierung

Ziel ist es, nur unter dem Boden ein Koordinatensystem anzuzeigen, da es nur hierbenötigt wird. Außerdem soll das Koordinatensystem nicht im Ursprung des Koordinaten-systems der Szene beginnen. Vielmehr sind die abgerundeten Minimalwerte von Latitudeund Longitude diejenigen Werte, die sich im Ursprung der Welt-Koordinaten befinden.

Ein weiteres Ziel besteht darin, die Abstände zwischen den einzelnen Markierungenauf der x-Achse (für die Longitude) und der y-Achse (für die Latitude) gleichgroß zusetzen. Auf diese Weise ergibt sich eine gitterförmige Unterteilung mit quadratischenGitterzellen. Die Markierungen sind eine gleichmäßige Einteilung der Fläche, die zwischendem Minimum und dem Maximum einer Achse stattfindet. Damit diese auf beidenAchsen gleichgroß ist, soll diejenige Achse den Maßstab bilden, bei dem der Abstandzwischen Minimum und Maximum kleiner ist. Diese Achse muss im ersten Schritt in derFunktion calculateGridDistancesAndAddGrid() ermittelt werden. Dazu erhält die Funktion diebeiden Parameter differenceBetweenMinAndMaxX und differenceBetweenMinAndMaxY. Diesebezeichnen die Abstände zwischen dem kleinsten und dem größten Wert jeweils auf der x-und auf der y-Achse. Diese Werte wurden in der aufrufenden Funktion show() berechnet.Vom Server wurden beim ersten Laden die Variablen biggestx, biggesty, smallestx undsmallesty mit Werten belegt. biggestx und smallestx sind die Grenzwerte der Longitude undsmallesty sowie biggesty die Grenzwerte der Latitude (in der Darstellung ist die Longitudeder x-Achse zugeordnet und die Latitude der y-Achse). In calculateGridDistancesAndAddGridgibt es eine Variable smallestDifferenceBetweenMinAndMax. Diese wird mit der kleinstenDifferenz belegt:

Listing 4.1. kleinste Differenz für Koordinatensystem

1 if ( differenceBetweenMinAndMaxX <= differenceBetweenMinAndMaxY ) {

2 smallestDifferenceBetweenMinAndMax = differenceBetweenMinAndMaxX;

3 }

4 else {

5 smallestDifferenceBetweenMinAndMax = differenceBetweenMinAndMaxY;

67 }

Diese kleinste Differenz bietet die Orientierung für den weiteren Aufbau des Koordina-tengitters.

Die nächste Aufgabe besteht darin, den Abstand der Gitterzellen im Koordinatengit-ter zu ermitteln. Dieser wird in der Variable calculatedGridDistance gespeichert, um ihn derFunktion addGrid() zu übergeben. Im Grundsatz gilt, dass der Abstand umso kleiner seinmuss, je kleiner der in smallestDifferenceBetweenMinAndMax gespeicherte Wert ist.

Für diesen Schritt werden die Vorkommastellen (predecimal) und die Nachkommastellen(decimal) der kleinsten Differenz (smallestDifferenceBetweenMinAndMax) berechnet. Für denErhalt der Vorkommastellen muss lediglich über Math.floor() abgerundet werden. DieNachkommastellen ergeben sich dann aus der Differenz zur gerundeten Zahl. Nun gibt es

32

4.3. Implementierung

zwei mögliche Ergebnisse.Der erste mögliche Fall besteht darin, dass die Vorkommastelle größer ist als 0. Ist

das der Fall, kann calculatedGridDistance berechnet werden. Der Wert ergibt sich daraus,dass auf die Anzahl der Stellen vor dem Komma abgestellt wird. Diese Anzahl wird alsExponent zur Basis 10 gesetzt. Das Ergebnis wird dann durch 100 geteilt.

Ergibt sich, dass smallestDifferenceBetweenMinAndMax eine 0 vor dem Komma hat, dannwird calculatedGridDistance auf eine andere Weise berechnet. Die hinter der Berechnungstehende Idee ist, dass der Abstand der Einteilungen des Koordinatensystems ebenfallseine Zahl sein soll, die eine 0 vor dem Komma hat. Die Anzahl der dem Komma unmittel-bar folgenden Nullen entspricht der von smallestDifferenceBetweenMinAndMax. Die darananschließende Zahl ist eine 1. Ist also etwa smallestDifferenceBetweenMinAndMax = 0.008, soist calculatedGridDistance = 0.001.

Zunächst wird sichergestellt, dass tatsächlich nur die Nachkommastellen betrachtetwerden. Hierzu wird die vor dem Punkt stehende 0 sowie der Punkt selbst abgeschnittenund das Ergebnis in der Variable decimalWithoutDot gespeichert. Danach wird die Anzahlder führenden Nullen festgestellt, die in der Nachkommastelle auftreten. Hierzu wird dieZahl als String betrachtet und es wird solange der erste Character des Strings entfernt,bis die erste Stelle ungleich 0 ist. Die Anzahl der Durchläufe, die für dieses schrittweiseAbtrennen der führenden Stelle erforderlich ist, entspricht dann der Anzahl der führendenNullen nach dem Komma. Das Ergebnis wird in zerosDirectlyAfterDot gespeichert. Es wirdbenötigt, um den Abstand der Markierungen im Koordinatensystem zu ermitteln.

Hierzu wird ein String erzeugt, der in der Variable gridDistanceString hinterlegt ist.Dieser String wird dann mittels der Funktion parseFloat() nach seiner Erzeugung in einFloat umgerechnet. Dieses entspricht dann der calculatedGridDistance. Erzeugt wird derString, indem zunächst durch var gridDistanceString = "0." eine 0 vor dem Komma ange-nommen wird. Daran schließt das Anfügen sovieler Nullen an, wie in zerosDirectlyAfterDotgespeichert ist. Zum Schluss steht die Anfügung einer 1.

In beiden Fällen liegt nach dem Durchlauf dieses Abschnitts also ein Wert in calculated-GridDistance vor.

Danach erfolgt der Funktionsaufruf addGrid(). Die Funktion erhält einige Parameter; unteranderem auch die gerade berechnete calculatedGridDistance. Hier gilt es zunächst, fest-zulegen, an welchen Punkten im Welt-Koordinatensystem das Koordinatensystem desBodens anfangen und enden soll. Gespeichert werden die vier Randpunkte des Boden-Koordinatensystems in den Parametern xStart, xEnd, yStart und yEnd. Diese besitzen einenAusgangswert, den sie von dem Aufruf in der Funktion calculateGridDistancesAndAddGriderhalten haben. xStart ist die Nachkommastelle von smallestx, dem kleinsten Wert des Bo-dens im Bereich der Longitude. xEnd ist die Nachkommastelle von biggestx, dem höchstenLongitude-Wert. Entsprechend verhält es sich mit smallesty und biggesty und der Longitude.

Der Grund dafür, die Nachkommastelle zu verwenden, liegt darin, dass der Wertvor dem Komma bei smallestx und smallesty als Ursprung des Welt-Koordinatensystems

33

4. Implementierung der 3-D-Visualisierung

angesehen und die Platzierung des sichtbaren Koordinatengitters entsprechend ausgelegtwird. Darin liegt auch der Grund für die Benennung der Variablen als zerox und zeroy – siesollen den Nullpunkt darstellen.

Im ersten Schritt der addGrid()-Funktion gilt es, gegebenenfalls xStart, xEnd, yStart undyEnd anzupassen. Das Grid soll nicht unmittelbar dort anfangen und enden, wo sich derBoden befindet. Start und Ende der Koordinatenebene sollen ein Vielfaches der berechnetenDistanz sein. Das Vielfache berechnen wir dabei vom Nullpunkt aus gesehen. Deshalbkann es sein, dass das Koordinatengitter auf der x-Achse ein Stück nach links vom Bodenausgesehen anfängt. Entsprechend kann es auf der y-Achse / Latitude-Achse tiefer reichen,als der Boden selbst reicht.

Die Funktion floatSafeRemainder in helpers.js berechnet den Wert, der xStart oder yStartabgezogen beziehungsweise xEnd oder yEnd hinzugefügt werden soll, damit das Gitter anVielfachen der Distanz auf beiden Achsen beginnt und endet. Es handelt sich hierbei umeine Funktion, die den Rest bei einer Division für Float-Werte berechnet. Sie funktioniertnach dem Prinzip, die Float-Werte als Integer zu betrachten, um hierauf den Operator %(Modulo) anwenden zu können. Dazu werden die Nachkommastellen der beiden Zahlenin ihrer Länge angepasst und anschließend der Dezimalpunkt entfernt. Nach der Berech-nung des Rests wird das Ergebnis wieder in einen Float-Wert umgerechnet, indem esdurch eine Zehnerpotenz geteilt wird. Der Exponent ist dabei die gemeinsame Anzahlder Nachkommastellen von Dividend und Divisor. Die Entfernung des Dezimalpunktskann als Multiplikation beider Zahlen mit dieser Zehnerpotenz angesehen werden; dieDivision macht sie wieder rückgängig. Im nächsten Schritt werden die berechneten Start-und Endwerte gerundet. Auch im späteren Verlauf erfolgt eine Rundung von Ergebnissen,um die erforderliche Genauigkeit von Rechnungen zu erreichen.

Wurden auf diese Weise alle vier Eckpunkte des Koordinatengitters bestimmt, wird alsnächstes in drawWhitePlane() die weiße Fläche berechnet, die sich unter dem Gitter befindensoll. Sie macht das Gitter besser sichtbar. Die weiße Fläche besteht aus zwei Dreiecken,die zu einem Rechteck zusammengelegt werden. Hierzu wird eine neue THREE.Geometryerzeugt, die als Vertices die vier Punkte erhält, die die Randpunkte des Koordinatensys-tems ausmachen sollen. Die Höhe, height, ist die minelevation. Es handelt sich hier umeine Information zum Ozeanboden, die vom Server heruntergeladen wurde. Sie gibt diegeringste Höhe an, die der Boden insgesamt erreicht. Sie ist der richtige Punkt, um dasKoordinatensystem auf der z-Achse beginnen zu lassen. Denn sie liegt in diesem Fallgenau unter dem Boden. Die vier Eckpunkte werden genutzt, um zwei weiße Faces zuerzeugen. Mit diesen wird das Koordinatengitter ausgelegt. Die entstandene planeGeometrymuss skaliert werden, damit sie den skalierten Werten des Ozeanbodens entspricht. Dasgeschieht über den Aufruf plane.scale.set( SCALE_VALUE,SCALE_VALUE, 1 ).

Nun wird die weiße Fläche mit dem Gitter belegt. Da es sich um ein Gitter aus gleichgroßen

34

4.3. Implementierung

Quadraten handelt, kann es mithilfe von for-Schleifen erzeugt werden. Genutzt werdenzwei geschachtelte for-Schleifen. Die äußere durchläuft die x-Achse (die Longitude) unddie innere die y-Achse (die Latitude). Die äußere Schleife beginnt bei xStart, also demBeginn des visualisierten Koordinatensystems auf der x-Achse. Bei jedem Durchlauf wirdsie um den Betrag von distance erhöht, wobei dieser als Parameter beim Funktionsaufrufübergeben wurde. Die Schleife endet, wenn newXEnd überschritten ist. Der Wert berechnetsich wie folgt: newXEnd = xEnd - distance. Der Grund für die Verwendung dieses Wertsliegt darin, dass während des einzelnen Durchlaufs einer Schleife einzelne Gitterzellenhinzugefügt werden. Damit die letzte Reihe genau auf dem Ende des Koordinatensystemsliegt, muss vom eigentlichen Endwert der Wert von distance abgezogen werden. Dieserwird beim letzten Durchlauf wieder hinzuaddiert. Entsprechend ist die innere Schleifeaufgebaut; hier mit den Variablen yStart und newYEnd. Bei jedem Durchlauf der innerenSchleife in jedem Durchlauf der äußeren Schleife wird eine THREE.Geometry erzeugt (bor-derGeometry). Dieser werden Vertices hinzugefügt, die die Punkte darstellen, durch diedie erzeugte Linie gezogen wird. Diese Linie ist bei jedem Durchlauf der Doppelschleifeein Quadrat, sodass die erzeugte weiße Ebene mit gleichgroßen Quadraten gepflastert wird.

Jedes dieser Quadrate befindet sich in derselben Höhe, die die kleinste Höhe des Bo-dens und damit die Höhe der schon gebildeten weißen Grundlage des Koordinatensystemsist (minheight). Die Vertices, hier also die Eckpunkte des Quadrats, sind (i, j), (iDis, j),(i, jDis) und (iDis, jDis). Die Werte iDis und jDis berechnen sich aus i oder j durch Hin-zuaddieren von distance. Der Vertex THREE.Vector3(i, j, height) kommt zweimal vor, da erStart- und Endpunkt der zu ziehenden Linie sein soll. Die Linie wird durch THREE.Line(borderGeometry, lineBorderMaterial ) mithilfe der Vertices gezogen.

Die so erzeugten Quadrate werden der THREE.Group lineGroup hinzugefügt und nichtdirekt der scene. Damit können sie beim Laden einer neuen Region einfach entfernt undneu berechnet werden. Die lineGroup ist ihrerseits Bestandteil der scene. Außerdem mussjedes so erzeugte Quadrat mit (SCALE_VALUE,SCALE_VALUE,1) skaliert werden, damitdie Größenverhältnisse mit denen des Bodens übereinstimmen.

Das Koordinatensystem benötigt außerdem noch Markierungen, an die dann die Zah-len geschrieben werden. Diese werden im Quellcode als Pins bezeichnet. Gesetzt werdendiese Markierungen an die Koordinatenachsen, die jeweils eine Seite der Fläche des Koor-dinatensystems darstellen. Es sind einfache Linien, deren Grenzwerte jeweils zwei Verticessind. Gesetzt werden die Markierungen über den Aufruf der Funktion drawPins mit den ge-wünschten Werten, die den Anfang und das Ende des Pins angeben. Sie sind so angeordnet,dass sie sich an der Unterseite und an der linken Seite der Fläche des Koordinatensystemsbefinden und durch ihre Beschriftung anzeigen, welcher Wert der jeweiligen Gitterzellezugeordnet ist.

Zum Koordinatensystem gehören außerdem noch zwei Pfeile, die die Richtungen der

35

4. Implementierung der 3-D-Visualisierung

Achsen (Latitude und Longitude) angeben. Diese werden mit dem THREE.ArrowHelpererzeugt.

Danach werden die Achsen beschriftet. Benötigt werden Beschriftungen für die x-Achse, sol-che für die y-Achse und die Angabe, welche Achse die Latitude und welche die Longitudedarstellt. Die x-Achse wird mit lon und die y-Achse mit lat beschriftet. Dies geschieht überden Aufruf von makeText. Für die Erzeugung von 3-D-Text wird der ein THREE.FontLoadergenutzt. Der gewünschte Text wird erzeugt und in der Variable textMesh gespeichert. Inder makeText()-Funktion gibt es eine Fallunterscheidung, bei der die Positionierung deserzeugten Textobjekts abhängig davon ist, ob es sich um eine Beschriftung der x-Achsehandelt – setX – ob es um die y-Achse geht – setY – oder ob mit lat / lon beschriftet wird –name.

makeText() erhält den content, also den gewünschten Text sowie Position und Größe desTexts. Der in textMesh gespeicherte erzeugte Text wird dann mit einer box umhüllt, diedabei hilft, die erzeugte Beschriftung richtig zu positionieren. Abhängig davon, welcherKategorie das Text-Objekt beim Aufruf der Funktion zugeordnet wurde, wird seine Positionberechnet. Es wird nach seiner Erzeugung der labelingGroup zugeordnet, damit es bei demLaden einer neuen Region problemlos gemeinsam mit allen anderen Objekten seiner Artentfernt werden kann.

Der Aufruf von lableAxis dient dazu, die beiden Achsen mit den Werten des Koor-dinatensystems zu beschriften. Auf diese Weise kann der Nutzer die Lage des Bodensinsgesamt und die Lage bestimmter Stellen ablesen. Die Funktion greift dabei ihrerseits aufdie makeText-Funktion zurück. Der Wert, mit dem die Achsen beschriftet wird, bestimmtdie Funktion oldXPositionBeforeNewZero beziehungsweise oldYPositionBeforeNewZero. Hierwird der Ausgangswert der Position berechnet.

4.3.8. Platzierung der Messstationen

Der nächste Schritt innerhalb der show()-Funktion besteht darin, die Messstationen an demfür sie vorgesehenen Ort auf dem Ozeanboden zu platzieren. Dies passiert durch einenAufruf von placeNewStations() in main.js. In dieser Methode wird zunächst im Rahmeneiner for-Schleife bestimmt, welche Stationen aus dem Array stations (das alle Stationen ausallen Regionen enthält) in der gerade zu ladenden Region vorkommen. Diese Informationkann durch stations[i].region abgefragt werden. Ein Vergleich zeigt, ob die in der Variableregion enthaltene Region (die die gerade dargestellte Region anzeigt) mit der Region derStation übereinstimmt. Ist das der Fall, wird sie für die Darstellung verwendet. In diesemFall wird die Station in das Array stationsOfCurrentRegionList aufgenommen. Dabei istallerdings zu beachten, dass Stationen eine Up- und eine Down-Richtung besitzen könnenund zwei vorhandene Richtungen separat in dem Array stations zu finden sind. Da zweiRichtungen nur eine einzige Station ausmachen sollen, ist es erforderlich, dass das Vorhan-densein einer der Richtungen abgefragt wird, bevor eine Station mit der anderen RichtungstationsOfCurrentRegionList hinzugefügt wird. Dieser Schritt wird ermöglicht durch die ID,

36

4.3. Implementierung

die jede Station besitzt und die bei der Up- und Down-Richtung identisch ist, falls beidein der Liste aller Stationen vorkommen. Hat die Untersuchung ergeben, dass die Stationmit der anderen Richtung bereits vorhanden ist, wird ihr die neue Richtung hinzugefügt.Falls die Station noch nicht vorhanden war, wird sie erzeugt. Es handelt sich hierbei umein JavaScript-Objekt der Klasse MeasuringStation. Die erzeugte Station wird nicht nurstationsOfCurrentRegionList, sondern auch der Three.js-Group stationsGroup hinzugefügt.Damit wird es möglich, alle Stationen unkompliziert aus der Darstellung zu entfernen,wenn eine neue Region geladen wird.

Eine Station ist ein Objekt der Klasse MeasuringStation. Wenn ein solches Objekt erzeugtwird, werden ihm einige Parameter übergeben.

Der Parameter adcpDirection enthält die Richtung der Bins, die für die Station hinterlegtist. Das bedeutet allerdings nicht, dass die Station nur Bins in dieser Richtung besitzt. Dennes kann sich ergeben, dass auf dem Server für dieselbe Station ein weiterer Datensatz fürdie andere Richtung gespeichert ist. Diese muss dem Objekt nachträglich hinzugefügtwerden. Es wird getestet, welche Richtung in adcpDirection gespeichert ist. Die Anzahl derBins der anderen Richtung wird dann auf 0 gesetzt. Das MeasuringStation-Objekt erhältdiverse Attribute, die sich aus den Werten ergeben, die für die Station auf dem Servergespeichert sind. Außerdem erhält jede Station vier Beschriftungen (frontName, rightName,backName, leftName). Außerdem besitzt jedes Objekt eine eigene Lookup-Table mit einemcooltowarm-Farbverlauf. Diese ermöglicht es, die Markierungen der Pfeile der Station mitunterschiedlichen Farben auszustatten.

Die Basis für die Darstellung der Stationen sind weiße Würfel. Diese wurden wegenihrer guten Sichtbarkeit für den Nutzer gewählt. Außerdem ist es bei Würfeln möglich, siean allen vier Seiten zu beschriften, sodass die Bezeichnung der Station immer gut lesbarbleibt. Die Würfel sind grundsätzlich weiß eingefärbt, an ihrer Ober- und Unterseite abertransparent. Erreicht wird dies, indem jede der sechs Seiten ein eigenes Material erhält.

Listing 4.2. Würfelmaterial

1 var cubeSides = [

2 new THREE.MeshBasicMaterial( { color:0xffffff, transparent:true, opacity

:1.0, side: THREE.DoubleSide } ),

3 new THREE.MeshBasicMaterial( { color:0xffffff, transparent:true, opacity

:1.0, side: THREE.DoubleSide } ),

4 new THREE.MeshBasicMaterial( { color:0xffffff, transparent:true, opacity

:1.0, side: THREE.DoubleSide } ),

5 new THREE.MeshBasicMaterial( { color:0xffffff, transparent:true, opacity

:1.0, side: THREE.DoubleSide } ),

6 new THREE.MeshBasicMaterial( { color:0xffffff, transparent:true, opacity

:0.0, side: THREE.DoubleSide } ), //upside

7 new THREE.MeshBasicMaterial( { color:0xffffff, transparent:true, opacity

37

4. Implementierung der 3-D-Visualisierung

:0.0, side: THREE.DoubleSide } ) //downside

8 ];

Aus diesen einzelnen Materialien wird dann das cubeMaterial erzeugt, das für denWürfel als geometrisches Objekt genutzt wird.

Der erzeugte Würfel wird dann an die Stelle gesetzt, die durch die übergebenen Pa-rameter festgelegt wurde. Diese müssen – entsprechend der Berechnung für den Boden –neu berechnet werden.

Jetzt ist ein Würfel vorhanden. Im nächsten Schritt werden an ihm die Bins befestigt,wobei zu diesem Zeitpunkt nur eine Kette von Bins für eine Richtung vorhanden ist.Welche Richtung dies ist, wird durch this.adcpDirection angegeben. Entsprechend derRichtung wird dann entweder die Funktion MeasuringStation.prototype.addDownBins oderMeasuringStation.prototype.addUpBins aufgerufen. Außerdem wird der maximale Wert derLookup-Table der Station festgelegt. Die Lookup-Table (in this.stationsLut) hat 0 als Mi-nimalwert – festgelegt durch this.stationsLut.setMin( 0 ). Der vorläufige Maximalwert istdie Anzahl der Bins in der vorhandenen Richtung. Die interne Lookup-Table der Station,die sich in der Visualisierung nicht wiederfindet, zeigt damit einen Farbverlauf von 0bis hin zur Anzahl der vorhandenen Bins. Auf diese Weise wird jedem Bin ein Farbwertzugeordnet. Diesen Farbwert tragen die Markierungen des Pfeils, der von dem Bin ausgeht,wenn diese Darstellung aktiviert ist.

Über den Aufruf der Funktion MeasuringStation.prototype.addDownBins beziehungsweiseMeasuringStation.prototype.addUpBins wird der Station die Kette mit den Bins hinzugefügt,deren Daten sie bei ihrer Erzeugung erhalten hat. Die Bins sitzen dabei an einer Kette über-beziehungsweise untereinander. Die Kette geht dabei vom Mittelpunkt des Würfels aus.Das ist der Punkt, an dem der Würfel platziert wurde (die Berechnung des Orts beziehtsich immer auf den Mittelpunkt des geometrischen Objekts). Um diese Kette zu erzeugen,wird mithilfe des THREE.LineBasicMaterial eine Linie implementiert. Neben dem Materialbenötigt die Linie eine THREE.Geometry. Dieser wird zunächst der new THREE.Vector3( 0,0, 0 ) hinzugefügt. Dieser Vektor stellt den Startpunkt der Linie dar. Basis hierfür ist dasKoordinatensystem des Würfels, auf dem die Linie später über this.cube.add( line ) platziertwird. Mit dieser Koordinate wird angegeben, dass die Linie / Kette im Mittelpunkt desWürfels beginnen soll.

Der Endpunkt der Linie wird dem Material über den Aufruf lineGeometry.vertices.push(new THREE.Vector3( 0, 0, ( firstDownBinHeight + ( nDownBins-1 ) * binDownHeight ) * -1 )) hinzugefügt (hier für die Down-Richtung). Da sich im Vergleich zum Startpunkt nurdie z-Komponente des Vektors ändert und diese negativ ist, zeigt die Linie also vomMittelpunkt des Würfels (dem Standort der Station) aus nach unten. Ihre Länge richtetsich nach Anzahl und Lage der Bins. Der erste Bin besitzt dabei immer eine eigene Höhe,sodass er bei der Berechnung gesondert betrachtet werden muss. Die anderen Bins liegen

38

4.3. Implementierung

in demselben Abstand zueinander.

Nachdem die Linie an der Ober- oder Unterseite des Würfels hinzugefügt wurde, sollen ihrdie Bins hinzugefügt werden. Das geschieht dadurch, dass die einzelnen Bins wiederumdem Würfel hinzugefügt werden (this.cube.add( sphere )), sodass dessen Koordinatensystemgilt. Ein Bin wird durch eine THREE.SphereGeometry dargestellt. Mit deren Hilfe lässt sichein kugelähnliches Aussehen erreichen. Die Zahl der Segmente ist mit 8 niedig gehalten,sodass die segmentierte Form bei einer größeren Darstellung der THREE.SphereGeometryauffallen würde. Aufgrund der geringen Größe der Bins ist diese Wahl ausreichend und hatkeine wahrnehmbar negativen Einflüsse auf die Geschwindigkeit des Programms. In Mea-suringStation.prototype.addDownBins beziehungsweise MeasuringStation.prototype.addUpBinswird zwischen der Platzierung des ersten Bins (mit seiner eigenen Höhe) und der Positio-nierung der anderen Bins unterschieden. Dies findet innerhalb einer Schleife statt. Hierwerden die Bins in festen Abständen über- beziehungsweise untereinander platziert.

Zusammen mit der Anlage der Bins werden auch die Pfeile initialisiert, die von den Bins aus-gehen sollen. Diese Pfeile dienen vor allem der erstmaligen Befüllung von this.arrowUpListund this.arrowDownList, die festlegt, wie groß diese Arrays sind. Da die Pfeile dieser In-itialisierung aber nicht sichtbar sein sollen, wird arrow.visible = false gesetzt. Die Pfeilewerden mithilfe von THREE.MarkedArrowHelper erzeugt. Dieser benötigt eine Richtung,die durch einen Einheitsvektor angegeben wird, der in der Form eines THREE.Vector)übergeben wird. Außerdem muss ein Ursprung genannt werden; ebenfalls in Gestalt einesTHREE.Vector3. Der Ursprung bezieht sich auf das Koordinatensystem von this.cube. Ange-geben wird jeweils die Position des zum Pfeil gehörenden Bins.

Nachdem in der Funktion placeNewStations in main.js alle Stationen erzeugt wurden, müssensie anschließend mit ihrem jeweiligen Namen beschriftet werden. Diesem Zweck dient dieFunktion writeNamesOnStations(). Diese verwendet einen THREE.FontLoader, der es erlaubt,mit einer ausgesuchten Schriftart einen 3-D-Text zu erzeugen. Die Schriftart ist in einerJSON-Datei hinterlegt. Neben der Schriftart, der font,(hier: helvetiker_bold, da diese von denverfügbaren am besten lesbar war), benötigt die erzeugte THREE.TextGeometry Angaben zursize, also zur Schriftgröße und zur Höhe der Schrift (height). Die Schrifthöhe bezieht sichauf die Breite, die die Schrift auf der z-Achse erreicht. Um eine flache Schrift zu erzeugen,wurde height: 1 gesetzt. Kennzeichnend für die Funktion writeNamesOnStations() ist ihrrekursiver Aufbau. Auf diese Weise wird erreicht, dass jede in stationsOfCurrentRegionListenthaltene Station ihre eigene Beschriftung erhält. Innerhalb dieses rekursiven Durchlaufswird die Methode MeasuringStation.prototype.makeNames aufgerufen. Nach dem Abschlussdes Durchlaufs wird die Stations Visible-Checkbox für die Bedienung freigeschaltet (docu-ment.getElementById( ’stationsVisibleCheckbox’ ).disabled = false).

MeasuringStation.prototype.makeNames nutzt die für die betreffende Station herunterge-

39

4. Implementierung der 3-D-Visualisierung

ladene 3-D-Schrift für die Beschriftung des Würfels. Die Beschriftung geschieht an vierSeiten des Würfels, wobei Ober- und Unterseite ausgespart werden. Der Funkion wird dieerzeugte Geometrie – die Struktur des 3-D-Texts – als Parameter übergeben. Mithilfe einesschwarzen THREE.MeshBasicMaterial werden vier Meshes erzeugt, die jeweils einer Seitedes Würfels hinzugefügt werden. Damit die Beschriftungen richtig positioniert werden,sind unterschiedliche Arten von Translation .position.set und Rotation .rotation erforderlich.Die Translation erfordert die Angabe neuer Koordinaten, wobei diese sich auf das Koordi-natensystem von this.cube beziehen. Der Ursprung liegt also im Mittelpunkt von this.cube.Für die Rotation wird immer eine Achse angegeben, um die die Drehung erfolgen soll. DerDrehwinkel wird im Bogenmaß notiert.

Weitere wesentliche Funktionen der MeasuringStation sind außerdem MeasuringStation.prototype. moveUpArrows und MeasuringStation. prototype. moveDownArrows. Diese dienendem Bewegen der Pfeile, was in der Visualisierung nach Betätigung des Time-Slidersoder bei einem Autoplay erfolgt. Auch hier lässt sich am Namen der Funktion ablesen, inwelcher Richtung die Pfeile verlaufen, die bewegt werden.

Die Funktionen besitzen einen analogen Aufbau. Die Pfeile werden bewegt, indemdie vorhandenen entfernt und neue mit einer neuen Richtung eingesetzt werden. ZumEntfernen wird die zugehörige Liste der Pfeile durchlaufen. Wenn an einer Stelle ein Eintragvorhanden ist, wird der dort befindliche Pfeil von this. cube entfernt. Dieser Schritt dient demEntfernen der Pfeile aus der Visualisierung. Sind alle Pfeile auf diese Weise durchlaufen,wird die Liste der Pfeile geleert, indem dem Attribut ein leeres Array zugeordnet wird.

Anschließend werden die neuen Pfeile erzeugt. Die Länge und die Richtung der Pfeilewerden ihnen in Form von zwei Arrays übergeben, die ihrerseits in der moveArrows-Funktion vom Server geladen wurden. Der Ursprung entspricht der Lage des zugehörigenBins. Die Richtung des Pfeils, dir, wird mithilfe von arrowDirectionX und arrowDirec-tionYfestgelegt. Da sich die Pfeile nur in der Latitude-Longitude-Ebene bewegen, wird diez-Komponente auf 0 gesetzt. Für die Berechnung der Komponenten gelten grundsätzlichdie Formeln

x = r ˚ cosα

y = r ˚ sinα

Da dir einen Einheitspfeil angibt, gilt r = 1. Math.cos und Math.sin benötigen die Angabedes Winkels als Bogenmaß. Da sich die Drehrichtung entgegengesetzt zur mathematischenDrehrichtung verhält, wird das geltende Bogenmaß über die Formel

bm1 = 2 ˚ Π ´ bmberechnet.Nun ist noch zu berücksichtigen, dass der Ursprung des Kreises gedreht werden muss,

damit die Fließrichtung der Strömungen richtig visualisiert wird. So entsteht die Formelbm1 = 0.5 ˚ Π ´ bm.

Der mit diesen Angaben erzeugte Pfeil wird der Liste der Pfeile (this.arrowUpList oder

40

4.3. Implementierung

this.arrowDownList) hinzugefügt.Dies gilt allerdings nur dann, wenn die enthaltene Länge des Pfeils größer als 0 ist.

Anderenfalls wird der Platz in dem Array mit ´1 belegt. In der Darstellung erscheint indiesem Fall kein Pfeil an dem betreffenden Bin.

Nachdem die Pfeile erzeugt wurden, müssen sie der Visualisierung hinzugefügt wer-den. Dies geschieht dadurch, dass die Liste der Pfeile durchlaufen und die einzelnen Pfeilethis.cube durch .add hinzugefügt werden. Mit der Hinzufügung zum Würfel gilt dessenKoordinatensystem für die Berechnung der Platzierung der Pfeile.

4.3.9. Die Pfeile

Für die Pfeile wurde eine eigene Klasse erzeugt – THREE. MarkedArrowHelper. THREE.MarkedArrowHelper erweitert die bereits vorhandene Klasse THREE. ArrowHelper, indem sieihr Markierungen hinzufügt. Diese Markierungen helfen dem Betrachter dabei, die Längeder Pfeile abzulesen. Auf diese Weise kann er die Stärke der Strömungen besser erkennen.THREE. MarkedArrowHelper erhält bei der Erzeugung eines Objekts einige Parameter.Übergeben wird die Richtung des Pfeils (dir), der Ursprung des Pfeils (origin), seine Länge(length), die Farbe der Markierungen (markColor), die Länge der Pfeilspitze (headLength), dieBreite der Pfeilspitze (headWith) und ownColorOfMarksNeeded gibt an, ob die Markierungender Pfeile die übergebene Farbe erhalten sollen oder ob sie den Default-Wert bekommen(in diesem Fall eine rote Färbung).

Das Attribut this.distance = 50 gibt die Abstände der Markierungen auf den Pfeilen an.In der Visualisierung entspricht dies 50mm/s in Bezug auf die Geschwindigkeit der Strö-mung, die der Pfeil anzeigen soll. Die auf dem Pfeil vorhandenen Markierungen werdenin this. markGroup hinterlegt, einer THREE. Group. Damit kann auf einfache Weise auf dieMarkierungen als solche zugegriffen werden.

Verwirklicht wird die Erweiterung der Klasse THREE. ArrowHelper durch THREE. ArrowHel-per. call mit den benötigten Parametern. Dieser Aufruf erzeugt einen herkömmlichen Pfeil,der im nächsten Schritt mit den Markierungen belegt wird. Hierzu wird dem Pfeil zunächstdie noch zu füllende markGroup hinzugefügt (this.add(this.markGroup)). Der add()-Befehlist ein Three.js-Funktionsaufruf, der die Mitglieder der markGroup in der Visualisierungauf dem Pfeil ablegt. Eine Markierung wird durch eine THREE.SphereGeometry dargestellt,wobei auch hier – wie bei den Bins der Messstationen – die Form durch die Segmentierungnur kugelähnlich ist.

Beim Hinzufügen der Markierungen kommt es auf den Abstand an, den diese aufdem Pfeil haben. Da die Markierungen dem Pfeil hinzugefügt werden, gilt bei ihrer Po-sitionsberechnung das Koordinatensystem des Pfeils. Die erforderliche Translation wirdausgeführt durch sphere.position.set( 0, i, 0 ), wobei sphere eine einzelne erzeugte Markierungist. Die Variable i wird in der Schleife in dem Abstand hochgezählt, der in this.distanceenthalten ist – also in Fünfzigerschritten. Hierbei ist die Länge des Pfeils der Grenzwert

41

4. Implementierung der 3-D-Visualisierung

der Hochzählung, sodass die Markierungen genau auf den Pfeil passen. Die einzelnenMarkierungen werden nach ihrer Erzeugung der markGroup hinzugefügt.

Zu diesem Zeitpunkt befinden sich die Markierungen lediglich in der markGroup, abernoch nicht auf dem Pfeil. Diesem werden sie durch den Aufruf this.addMarks() hinzu-gefügt. Diese Funktion, THREE.MarkedArrowHelper.prototype.addMarks, durchläuft die inmarkGroup gespeicherten Markierungen und fügt sie dem Pfeil hinzu. Dadurch, dass sphe-re.position.set( 0, i, 0 ) bei der Erzeugung des Pfeils bereits aufgerufen wurde, erhalten dieMarkierungen die gewünschte Position auf dem Pfeil. Dem Aufruf this.addMarks() folgtder Aufruf addOrRemoveOwnColorOfMarks(). Diese Funktion regelt, ob die Markierungenden übergebenen Farbwert erhalten sollen oder ob sie die Default-Farbe – Rot – bekom-men. Sie erhält bei ihrem Aufruf einen Parameter (ownColorOfMarksNeeded), der angibt,ob die Default-Farbe ausreichend ist, oder nicht. Wird diese Funktion aufgerufen, werdenzunächst über this.removeMarks() die Markierungen vom Pfeil entfernt. Der Ablauf dieserFunktion ist mit THREE.MarkedArrowHelper.prototype.addMarks analog – mit dem Unter-schied, dass hier this.remove() statt this.add() aufgerufen wird. Dieses Entfernen wäre bei derInitialisierung des Pfeils nicht erforderlich, falls er seine Markierungen erst nach der Farb-wahl erhalten würde. THREE.MarkedArrowHelper.prototype.addOrRemoveOwnColorOfMarkssoll allerdings das nachträgliche Umfärben ermöglichen. Der erzeugte Pfeil erscheint erstdann, wenn die Konstruktor-Funktion return function MarkedArrowHelper( dir, origin, length,markColor, headLength, headWidth, ownColorOfMarksNeeded ) vollständig durchlaufen wurde.Deshalb erscheint der unter Umständen am Anfang falsch eingefärbte Pfeil nicht in derVisualisierung.

THREE.MarkedArrowHelper.prototype.addOrRemoveOwnColorOfMarks durchläuft nachdem Entfernen der Markierungen alle in markGroup befindlichen Markierungen und färbtsie um. Dies geschieht, indem sie ein neues Material erhalten, das die entsprechendeFarbe trägt. Anschließend werden die Markierungen aus der Gruppe wieder dem Pfeilhinzugefügt – durch den Aufruf von this.addMarks().

THREE.MarkedArrowHelper besitzt eine weitere Funktion – THREE. MarkedArrowHelper.prototype. writeOn. Diese Funktion wird in der Implementierung dann relevant, wenn derMaßstabspfeil mit seiner Beschriftung versehen werden soll. Dazu erhält die Funktion dievorgefertigte 3-D-Text-Geometrie (textGeo) und die Position (yPos), die besagt, an welcherStelle auf dem Pfeil die Beschriftung zu sehen sein soll (die Position auf der y-Achsedes Koordinatensystems des Pfeils). Die Beschriftung wird gut lesbar, wenn sie sich ineinigem Abstand zum Pfeil befindet. Das geschieht hier, indem xPos ebenfalls übergebenwird. Dieser Wert wird als Parameter übergeben, weil es möglich sein soll, die Schriftauch in dieser Richtung nach Wunsch zu positionieren. Erzeugt wird die Beschriftung inder Variable textMesh, wobei die übergebene Text-Geometrie und ein schwarzes Materialverwendet werden.

Um den Text mittig an der angegebenen Stelle auf dem Pfeil zu positionieren, wird in

42

4.3. Implementierung

boxForGettingLength eine THREE.Box3 erzeugt. Diese umgibt mit dem Aufruf von .setFrom-Object( textMesh ) den Schriftzug und es ist einfach, seine Maße zu ermitteln. Die Länge der3-D-Schrift entspricht der Länge der Box, die durch boxForGettingLength.size().y ermitteltwird. Der Text wird nun mittig an die angegebene Position yPos gesetzt, indem von dieserder Betrag seiner Länge abgezogen wird. Der Text rückt also in die negative Richtungauf der y-Achse – in diesem Fall nach links auf dem Pfeil. Damit steht seine Mitte an dergewünschten Position.

Über textMesh.rotation.z = Math.PI/2 wird der Text außerdem um 90 Grad um die z-Achsegedreht, damit er lesbar wird.

4.3.10. Der Ozeanboden

Nun wird innerhalb der show()-Methode die in der Datei oceanFloor.js befindliche FunktioncreateOceanFloorMesh aufgerufen. Diese Funktion erzeugt ein Bild des Ozeanbodens derausgewählten Region. Hierzu werden die Vertices und Faces genutzt, die für die gerade ak-tuelle Region vom Server heruntergeladen und in den Arrays vertices und faces gespeichertwurden. Außerdem finden die Arrays lat und lon Verwendung.

Die geladenen Daten zur Elevation des Bodens stammen aus Messungen, die in derbetreffenden Region vorgenommen wurden. Sie wurden unter Anwendung des Nearest-Neighbor-Algorithmus bereinigt und zusammengefasst.

Die Vertices haben eine bestimmte Struktur. Ein Vertex besteht aus einem Array mitdrei Einträgen. Der erste Eintrag bezieht sich auf das lon-Array und gibt dort den Index desEintrags an, der den Longitude-Wert für den betreffenden Vertex enthält. Dabei entsprichtdieser Wert dem Wert auf der x-Achse in der Darstellung. Entsprechend bezieht sich derzweite Eintrag im Vertex auf die Latitude. Der dritte Wert im Tripel gibt die Elevation an.Aus diesem Tripel wird ein Three.js-Vertex erzeugt. Dieser Vertex wird der oceanBaseGeome-try hinzugefügt. Nachdem alle Vertices auf diese Weise Bestandteil der oceanBaseGeometrygeworden sind, erfolgt die Belegung mit Faces. Auch die Faces sind als Array von Tripelngespeichert. Dabei enthalten alle Tripel ausschließlich positive ganze Zahlen. Es handeltsich um Indizes, die auf das Array verweisen, das durch oceanBaseGeometry.vertices darge-stellt wird. Entsprechend der Struktur der Faces als Dreiecke werden die drei Eckpunkteeines Faces angegeben.

Die oceanBaseGeometry, die sich aus den hergestellten Vertices und Faces zusammen-setzt, bietet noch nicht die Möglichkeit, einen Farbverlauf zu erzeugen. Hierfür ist eineTHREE.BufferGeometry() erforderlich, die aus oceanBaseGeometry erzeugt wird.

Über den Aufruf von colorizeOceanFloorMesh() wird der Farbverlauf in der oceanMesh-Geometry erzeugt. Hierzu wird die Lookup-Table verwendet, bei der alle Höhenwertedes Bodens einem bestimmten Farbwert zugeordnet werden. Mit einer Farbe werden die

43

4. Implementierung der 3-D-Visualisierung

einzelnen Faces belegt. Um die Höhe eines Face herauszufinden, wird der erste der dreiVertices herangezogen, die das Face bilden. Von diesem Punkt wird der dritte Eintrag desArrays verwendet, das diesen Punkt definiert: (vertices[faces[ i ][0]][2]). Dieser dritte Eintragbeschreibt die Lage auf der z-Achse und damit die Höhe des Vertex. Diese Höhe kannin der Lookup-Table abgelesen und damit das Face mit der zugehörigen Farbe versehenwerden. Um der BufferGeometry die entsprechende Einfärbung zu ermöglichen, muss einArray erzeugt werden, dass die erforderlichen Farbwerte enthält und das der Geometryals Attribut zugeordnet wird. Kennzeichnend für dieses Array ist, dass es sich auf dieVertices bezieht, die die zur Geometry gehördenden Faces bilden. Das Array wird hier inlutColors erzeugt. Das Array ist so strukturiert, dass die Farbwerte für die Vertices, die daseinzelne Face bilden, hintereinander darin liegen müssen. Die Farbwerte bestehen dabeiaus der R-, der G- und der B-Komponente. Auch diese müssen ihrerseits hintereinanderim Array liegen. So ergibt sich, dass lutColors für jedes Face neun hintereinander liegen-de Einträge zum Farbwert des Face besitzen muss. Nachdem lutColors erzeugt wurde,wird es der BufferGeometry durch den Aufruf oceanMeshGeometry.addAttribute( ’color’, newTHREE.BufferAttribute( new Float32Array( lutColors ), 3 ) ) hinzugegeben.

Nachdem der Boden erzeugt ist, muss in show() die Kamera an seiner Lage ausgerichtetwerden. Um den Mittelpunkt des Bodens zu finden, wird eine Box um ihn herum erzeugt.Diese Box macht es leicht, den Mittelpunkt des Bodens zu finden – er entspricht ihremMittelpunkt. Hieran wird die Kamera ausgerichtet.

Listing 4.3. Ausrichtung der Kamera in show()

1 var bb = new THREE.Box3();

2 bb.setFromObject( oceanFloorMesh );

3 bb.center( camera.position );

45 camera.position.z = cameraZ;

6 bb.center( controls.target );

Nachdem die Kamera so gesetzt wurde, werden die controls ebenfalls neu ausgerichtet.Das macht es möglich, sie beim Klick auf den Reset-Button zu diesem Zustand zurückzu-setzen.

Listing 4.4. Ausrichtung der Kamera in show()

1 controls.target0 = controls.target.clone();

2 controls.position0 = controls.object.position.clone();

3 controls.zoom0 = controls.object.zoom;

Der Aufruf window.addEventListener( ’resize’, onWindowResize, false ) macht es möglich,die Darstellung bei einer Größenänderung des Fensters neu auszurichten. Zu diesemZeitpunkt können außerdem Checkboxen und Buttons wieder bedienbar werden. Ausge-nommen davon wird der Button, der die gerade angezeigte Region neu laden könnte, da

44

4.3. Implementierung

dies vermieden werden soll.

Die Methode render() wird in loadFirstRegion() nach show() aufgerufen. Sie sorgt für die Be-rechnung der Darstellung mithilfe des render-Objekts. Hier wird außerdem controls.update(delta ) aufgerufen, was der bei einer Steuerung nötigen Aktualisierung dient.

4.3.11. Die Checkboxen

Die Checkboxen sind ebenfalls mit Funktionen ausgestattet. Mit ihrer Hilfe kann derNutzer Einfluss auf die Darstellung bestimmter Elemente nehmen. Das hilft ihm dabei, diedargestellten Daten nachzuvollziehen.

Die Funktion oceanFloorVisibleCheck() dient dazu, den Ozeanboden unsichtbar und wiedersichtbar zu machen. Zum Beispiel kann der Boden als umfangreiches Objekt der Darstel-lung störend wirken, wenn der Nutzer einzelne Stationen genauer ansehen will. Deshalb istes für ihn in manchen Situationen hilfreich, den Boden unsichtbar zu machen. Bei der Funk-tion wird abgefragt, ob ein Haken bei der Checkbox gesetzt ist (document.getElementById(’OceanFloorVisibleCheckbox’ ).checked. Aufgerufen wird die Funktion immer, wenn der Nutzerden Haken bei der Checkbox setzt oder ihn entfernt. Ist der Haken gesetzt worden (document.getElementById( ’OceanFloorVisibleCheckbox’ ).checked ist true, dann wird der Bodensichtbar, indem oceanFloorMesh.visible auf true gesetzt wird. Für das Unsichtbarmachen desBodens funktioniert es analog mit dem Setzen auf false. Ein weiterer Bestandteil der Funk-tion ist der Aufruf von hideOrShowLut(). Hierdurch wird erreicht, dass die Lookup-Tablesynchron zum Boden unsichtbar und wieder sichtbar gemacht wird. Sie wird bei einemunsichtbaren Boden nicht benötigt und kann unnötig verwirrend sein, wenn der Nutzerden Farbverlauf auf den Pfeilen betrachten möchte.

hideOrShowLut() ist in der Datei lut.js enthalten. Sie funktioniert nach demselben Prinzip.Da die Lookup-Table aus verschiedenen Elementen besteht, muss einzeln auf das visible-Attribut dieser Elemente zugegriffen werden.

Bei stationsVisibleCheck() geht es darum, die weiße würfelförmige Umhüllung der Sta-tionen unsichtbar oder sichtbar zu machen. Auch hier wird der Status der Checkboxabgefragt und mit einer Fallunterscheidung darüber entschieden, welcher Programmablaufstattfindet. Die Basis für die Funktion liegt in der stationsOfCurrentRegionList, in der diein der Region vorhandenen Stationen enthalten sind. Die Stationen sind MeasuringStation-Objekte, die Funktionen besitzen, die es ermöglichen, die Stationen sichtbar oder unsichtbarzu machen. Die Liste wird mithilfe einer Schleife durchlaufen und für jede Station wirddie entsprechende Funktion aufgerufen. MeasuringStation.prototype.makeTransparent sorgtdafür, dass die Station unsichtbar wird. Zu diesem Zweck wird die Einfärbung des Würfelstransparent gemacht. Außerdem wird die visible-Eigenschaft der Beschriftungen an jederSeite der einzelnen Station auf false gesetzt. Analog funktioniert es für das Sichtbarmacheneiner Station mithilfe der Methode MeasuringStation.prototype.makeVisible. Hier wird die

45

4. Implementierung der 3-D-Visualisierung

Umhüllung des Würfels (also mit Ausnahme seiner Ober- und Unterseite) weiß eingefärbt.Die Beschriftungen werden wieder sichtbar, indem das visible-Attribut auf true gesetzt wird.

Die dritte Checkbox macht die Pfeile in der Visualisierung sichtbar oder unsichtbar. Dasbezieht sich auf die Pfeile, die von den Messstationen ausgehen und auf den Maßstabspfeil.Der Eingriff in die Sichtbarkeit der Pfeile an den Stationen erfolgt – wie bei stationsVi-sibleCheck() – durch ein Durchlaufen der Stationen der gerade angezeigten Region. Fürjedes in der Liste befindliche Objekt wird die Funktion showOrHideArrows aufgerufen.Hierbei wird jedem Funktionsaufruf die Information übergeben, ob der Haken in derCheckbox gesetzt ist oder nicht (document.getElementById( ’arrowsVisibleCheckbox’ ).checked).showOrHideArrows testet jeweils das Vorhandensein von Up- und Down-Bins (es existierenStationen, die nur Bins in einer Richtung besitzen). Um zu testen, ob die jeweilige Richtungvorhanden ist, ist die Abfrage this.nUpBins > 0 beziehungsweise this.nDownBins > 0 möglich.Diese Attribute enthalten die Anzahl der Bins in der jeweiligen Richtung. Beim Erzeugeneiner Station, bei dem nur eine einzige Richtung vorhanden ist, wird die Anzahl derBins in der anderen Richtung auf 0 gesetzt. Kommt später die andere Richtung hinzu,wird diese Anzahl vergrößert. Aus diesem Grund sind bei jedem MeasuringStation-ObjektDaten zu den Bins in beiden Richtungen vorhanden und die Abfrage funktioniert. Sindin der betreffenden Richtung Bins vorhanden, dann muss auf die Sichtbarkeit der daranbefindlichen Pfeile Einfluss genommen werden. Die Pfeile sind – soweit vorhanden – inden Listen this.arrowUpList und this.arrowDownList abgelegt. Mithilfe einer for-Schleife wirddas visible-Attribut dieser Pfeil-Objekte auf true oder false gesetzt – abhängig von dem Wert,der in checkboxChecked gespeichert ist.

Anschließend wird der scaleArrow durch einen Eingriff auf sein visible-Attribut synchronzu den Pfeilen an den Stationen sichtbar oder unsichtbar gemacht.

Die vierte Checkbox schließlich sorgt über den Aufruf von colorGradientOnArrowsCheck()dafür, dass die Einfärbung der Markierungen auf den Pfeilen verändert werden kann(wobei sich dies nur auf die Pfeile an den Stationen bezieht. Der Maßstabspfeil ist hiervonnicht betroffen). Auch hier wird die Liste aller Stationen durchlaufen. Aufgerufen wirdjeweils die colorizeMarks()-Funktion des MeasuringStation-Objekts. Diese trifft dieselbe Fall-unterscheidung, die bereits für MeasuringStation.prototype.showOrHideArrowsbeschriebenwurde, also einen Test der Anzahl der Bins in beiden Richtungen. Sind Bins vorhanden, istin der Methode addOrRemoveColorscaleMarks() der einzelnen THREE.MarkedArrowHelperder weitere Quellcode hinterlegt. Diese Methode erhält die Information darüber, ob dieCheckbox gerade markiert ist. Abhängig von dieser Information, die als true oder falsein der Variable checked hinterlegt ist, erhalten die Markierungen auf dem Pfeil ein neuesMaterial.

46

4.3. Implementierung

Abbildung 4.9. Architektur der Anwendung

47

4. Implementierung der 3-D-Visualisierung

Abbildung 4.10. Überlagerung durch Lookup-Table

Abbildung 4.11. Lookup-Table

48

4.3. Implementierung

Abbildung 4.12. Koordinatensystem

49

Kapitel 5

Evaluation

Wir beschäftigen uns nun mit der Evaluation der Nützlichkeit der hier entwickeltenAnwendung für wissenschaftliche Zwecke.

5.1. Ziel

Die im Rahmen dieser Bachelorarbeit entwickelte Anwendung dient dem Zweck, ozeano-graphische Daten zu visualisieren. Dabei verfolgt die Darstellung das Ziel, Wissenschaftlerbei ihrer Tätigkeit zu unterstützen. Deshalb muss ihre Eignung für die entsprechendewissenschaftliche Arbeit evaluiert werden. Die Evaluation soll dafür die folgenden grund-legenden Fragen beantworten:

1. Ist die Usability ausreichend?

2. Werden die übergebenden Daten sinnvoll dargestellt? Kann die Darstellung wissen-schaftlich genutzt werden?

3. Gibt es Vorschläge für Verbesserungen?

Die Antworten auf diese Fragen bieten eine Grundlage für die Weiterentwicklung undVerbesserung der Anwendung.

5.2. Versuchsaufbau

Basis der hier stattfindenden Evaluation sind qualitative Experteninterviews [Kaiser 2014].Diese bestanden in einem Ausprobieren der entwickelten Anwendung durch die befrag-ten Experten. Das Ausprobieren geschah unter Anleitung und mit dem Ziel, bestimmteAufgaben zu lösen oder Fragen zu beantworten. Die Aufgaben und Fragen wurden soausgewählt, dass ihre Auswertung die oben genannten drei Fragenkomplexe klärt.

Wichtigster Bestandteil des Versuchsaufbaus war eine fortgeschrittene Version derImplementierung, die alle in der vorliegenden schriftlichen Arbeit beschriebenen Kompo-nenten und Funktionalitäten enthielt. Diese wurde an einem Laptop mit Internetzugangüber den Browser Google Chrome zur Verfügung gestellt.

Die den Interviewpartnern vorgegebene Visualisierung zeigte das bereits erwähnteKaltwasserkorallenriff in Stjernsund in Nord-Norwegen.

51

5. Evaluation

5.2.1. Teilnehmer

Am Experteninterview nahmen zwei Versuchspersonen teil. Bei beiden handelt es sich umMitarbeiter des GEOMAR, die das im Rahmen dieser Bachelorarbeit entwickelte Programmvoraussichtlich in der Zukunft für ihre Arbeit nutzen werden. Beide brachten im Rahmendes Interviews zum Ausdruck, dass sie an der Sammlung der Daten zur visualisiertenRegion in Nord-Norwegen teilgenommen hatten.

5.2.2. Präsentierte Fragen und Aufgaben

Einer der beiden Probanden machte bereits bei Vereinbarung des Termins darauf aufmerk-sam, dass ihm lediglich etwa eine Viertelstunde zur Verfügung stehen würde. Der andereKandidat hatte ebenfalls weitere Verpflichtungen, konnte aber mehr Zeit entbehren. Ausdiesem Grund gab es zwei verschiedene Fragebögen. Der kürzere von beiden enthielt nurdie wesentlichen Fragen. Eine Anpassung der Länge des anderen Interviews wurde alsnicht erforderlich angesehen. Die im kürzeren Interview gestellten Fragen waren auchBestandteil der zweiten, längeren Befragung, sodass auch eine vergleichende Auswertungmöglich war.

Präsentiert wurden die in Tabelle 5.1. enthaltenen Fragen beziehungsweise Aufgaben:

Tabelle 5.1. Interviewfragen

Erster Proband Zweiter ProbandVor dem Ansehen des Programms: Welchewissenschaftlichen Daten möchtest du im Pro-gramm wiederfinden und welche Möglichkei-ten sollte es bieten?

-

Vor dem Ausprobieren: Kannst du alle Ele-mente gut erkennen und die Beschriftungengut lesen?

-

Vor dem Ausprobieren: Was erwartest du,was die Buttons und Checkboxen jeweils tun,wenn du sie anklickst?

Vor dem Ausprobieren: Was erwartest du,was die Buttons und Checkboxen jeweils tun,wenn du sie anklickst?

Ausprobieren der Steuerung (nicht erklären,sondern auf den Button verweisen): Gefälltdir die Steuerung? Sollte etwas anders sein?Ist der Text im Help-Button hilfreich?

Ausprobieren der Steuerung (nicht erklären,sondern auf den Button verweisen): Reichtder Text im Help-Button aus, um die Art derSteuerung schnell zu verstehen?

Weiter auf der nächsten Seite

52

5.2. Versuchsaufbau

Tabelle 5.1 – Fortsetzung von vorhergehender SeiteErster Proband Zweiter Proband

Ausprobieren der Steuerung: Kannst du unterZuhilfenahme der Steuerung alles problemloserkennen und erreichen? Gibt es Elemente,die durch andere verdeckt werden und stelltdas ein Problem dar?

-

Der Boden: Kannst du die Höhen des Bo-dens an einer von dir ausgewählten Stelledes LatLon-Koordinatensystems problemlosablesen? Oder wünschst du dir weitere Hil-fen?

Der Boden: Kannst du die Höhen des Bo-dens an einer von dir ausgewählten Stelledes LatLon-Koordinatensystems problemlosablesen? Oder wünschst du dir weitere Hil-fen?

Die Pfeile: Was sagen Länge und Winkel derPfeile deiner Meinung nach aus?

Die Pfeile: Was sagen Länge und Winkel derPfeile deiner Meinung nach aus? Findest duden fest positionierten Pfeil zum Ablesen hilf-reich?

Die Pfeile: Kannst du die Längen der Pfeilegut ablesen?

-

Slider: Probiere die Slider aus und teste dieAutoplay-Funktion. Funktioniert das so, wiedu es dir vorstellst?

Slider: Probiere die Slider aus und teste dieAutoplay-Funktion. Funktioniert das so, wiedu es dir vorstellst?

Probiere die Checkboxen und den Reset-Button aus. Findest du die Funktionen sinn-voll? Sollte etwas anders sein?

-

Nach dem Ausprobieren: Sind die Funktiona-litäten im Programm alle hilfreich oder fin-dest du welche davon überflüssig?

Hast du Anmerkungen oder Wünsche zumProgramm? Ist irgendwas überflüssig?

Nach dem Ausprobieren: Gibt es (jetzt nachdem Ausprobieren) Funktionen, die das Pro-gramm haben sollte und die noch nicht vor-handen sind?

-

5.2.3. Beschreibung der Durchführung

Die beiden Interviews fanden an zwei unterschiedlichen Tagen in Räumen der Arbeits-gruppe Software Engineering in der Christian-Albrechts-Universität zu Kiel statt. BeideInterviews waren mit einer zeitlichen Beschränkung verbunden, da beide Probanden ter-minliche Verpflichtungen hatten. Deshalb war es erforderlich, auf die Schwerpunktsetzung

53

5. Evaluation

des Gesprächs zu achten.Beide Versuchspersonen bedienten denselben Laptop und bekamen dieselbe Version

der Software zur Verfügung gestellt. Beide erhielten eine Maus als externes Eingabegerät.Die Aufzeichnung der Interviews fand – nach Einwilligung der Probanden – durch

einen Tonträger statt. Eine schriftliche Beantwortung der Fragen wurde als nicht erforder-lich angesehen. Die Abarbeitung eines schriftlichen Fragenkatalogs hätte die Bedienungunterbrochen und wäre für ein freies Gespräch hinderlich gewesen. Dieses Gespräch wardie Grundlage für die Entwicklung spontaner Ideen zur Weiterentwicklung der Softwareund zur Integration weiterer Komponenten in das Programm. Auch das nachträglicheschriftliche Ausfüllen eines Fragebogens wurde wegen der geringen Probandenzahl undder geringen zur Verfügung stehenden Zeit als nicht notwendig betrachtet.

Die Interviews begannen mit geöffnetem Programm im Browserfenster. Eine vorherge-hende Einweisung fand nicht statt. Es war eines der Ziele, herauszufinden, wie intuitivbedienbar die Software ist. Die Einarbeitung in die Bedienung war deshalb Bestandteilder Interviews. Die Interviewfragen waren strukturiert und dienten somit neben ihremeigentlichen Zweck auch als Anleitung in die schrittweise Einarbeitung in das Programm.

5.3. Ergebnisse und ihre Diskussion

Die bei der Befragung gewonnenen Erkenntnisse dienen unmittelbar als Hinweise darauf,ob die Implementierung nach dem aktuellen Stand bereits für wissenschaftliche Zweckenutzbar ist. Außerdem sind sie die Basis für die Entwicklung eines Konzepts zur späterenOptimierung der Software. Hier spielt die subjektive Ansicht der befragten Probandeneine gewichtige Rolle. Sie sind diejenigen, die die Anwendung in der Zukunft tatsächlichverwenden sollen. Ihre Meinung ist deshalb maßgeblich dafür, ob die 3-D-Visualisierungder ozeanographischen Daten einen sinnvollen Ansatz verfolgt hat.

Ziel war es, die erwähnten Fragestellungen zu beantworten.

5.3.1. Usability

Bei der Beurteilung der Usability einer Webseite geht es darum, wie einfach (im Sinne vonunkompliziert) es ist, sie zu benutzen. Maßgeblich dafür ist, wie schnell ihre Bedienungerlernt wird, wie effizient sie ist und wie lange sie im Gedächtnis bleibt. Alle Komponentenmüssen bedienbar sein und dürfen keine Fehler aufweisen. Es kommt auch darauf an, obdie Nutzer die Seite mögen; ob sie sie gern verwenden [Nielsen und Loranger 2006].

Tabelle 5.2 enthält Ergebnisse der Evaluation, die im Hinblick auf die Usability alspositiv oder als negativ gelten können.

Die Ergebnisse der Befragung zeigen, dass es bei der Usability Verbesserungsbedarfgibt. Vor allem die Verbindung von Play-Button und Speed-Slider wird dem Nutzer beimersten Ausprobieren wahrscheinlich nicht klar. Falls der Speed-Slider in seiner aktuellen

54

5.3. Ergebnisse und ihre Diskussion

Tabelle 5.2. Evaluation der Usability

Positive Aspekte Negative Aspekte

Beide Probanden konnten sich innerhalbkurzer Zeit in die Bedienung der Web-Anwendung einarbeiten und die Erfüllungder Aufgaben und Beantwortung der gestell-ten Fragen war für beide problemlos möglich.

Die Beschriftung des Koordinatensystemswurde als zu klein empfunden, wobei hier eingewisser Ausgleich dadurch entstand, dassdie Möglichkeit des Heranzoomens erkanntwurde.

Der Help-Button wurde als hilfreich empfun-den; der Text im Alert war verständlich unddie Anweisungen zur Steuerung konnten vonbeiden Probanden direkt umgesetzt werden.

Die Beschriftung der Buttons war nicht unmit-telbar verständlich. Hier ergab erst ein Aus-probieren weitere Klarheit.

Die Bedeutung des Speed-Sliders war nichtklar und musste ausführlich erläutert werden.

Es wurde als schwierig empfunden, auf demTime-Slider einen gewünschten Zeitpunkt di-rekt auszuwählen.

Einem Probanden fehlte die Beschreibung derBedeutung des Farbverlaufs an den Pfeilender Stationen.

Der Unterschied in der Farbgebung des Play-Buttons war nicht ausreichend, um zu erken-nen, ob gerade ein Autoplay läuft.

Form in der Zukunft beibehalten werden soll, bietet es sich zur Lösung an, im Help-Buttonweitere Hinweistexte zu hinterlegen (für die Steuerung hat sich herausgestellt, dass dieseals sehr nützlich empfunden wurden).

5.3.2. Nutzbarkeit für wissenschaftliche Zwecke

Die zweite für die Evaluation wesentliche Frage ist, ob die entwickelte Software tatsächlichfür wissenschaftliche Zwecke genutzt werden kann. Da sie der Visualisierung von For-schungsdaten dient, besteht der wissenschaftliche Zweck darin, diese Forschungsdaten aufsinnvolle Weise darzustellen. Es geht also darum, ob die Daten vollständig und korrektvisualisiert und in dieser Form durch den Nutzer ablesbar sind. Ergebnisse hierzu könnenwir in Tabelle 5.3 nachlesen.

Grundsätzlich haben sich bei der Frage nach der wissenschaftlichen Nutzbarkeit desProgramms keine schwerwiegenden Probleme ergeben. Beide Interviewpartner konntendie dargestellten Daten ablesen und dabei die im Programm zur Verfügung stehenden Hil-festellungen verwenden. Eine Ausnahme stellen die Messstationen dar, bei denen genauere

55

5. Evaluation

Tabelle 5.3. Evaluation der wissenschaftlichen Nutzbarkeit

Positive Aspekte Negative Aspekte

Der Farbverlauf an den Pfeilen ist hilfreichfür die Untersuchung der Strömungen.

Es fehlen wichtige Informationen zu denMessstationen

Die Höhen des Bodens lassen sich im Unge-fähren ablesen.

Der Farbverlauf des Bodens ist nicht fein ge-nug. Verschiedene Höhen können nicht gutgenug voneinander unterschieden werden.

Die Markierungen an den Pfeilen ermögli-chen tatsächlich das Ablesen der Längen.

Bereits beim Interview fielen Besonderheitenin der Strömungsentwicklung auf.

Informationen zu wichtigen Eigenschaften vermisst wurden. Diese Eigenschaften stehenzum Zeitpunkt der Entstehung dieser Bachelorarbeit auf dem Server zum Download zurVerfügung und können über diesen heruntergeladen und in das Programm eingebundenwerden.

5.3.3. Vorschläge für Verbesserungen

Die Evaluation dient auch dem Ziel, die zukünftige Entwicklung der Visualisierung zuplanen. Die Expertenmeinungen sind hier entscheidend und bieten deshalb wertvolleErkenntnisse. Tabelle 5.4 enthält Vorschläge und Ideen, die während der Interviews aufka-men.

Die Evaluation hat im Hinblick auf zukünftige Erweiterungen und Verbesserungenergeben, dass es vielfältige Möglichkeiten gibt, die Software noch mehr an die Bedürfnisseder Wissenschaftler anzupassen. Hier scheint es sinnvoll, das Programm auch in derZukunft in enger Zusammenarbeit mit Wissenschaftlern am GEOMAR weiterzuentwickeln.Es ist vorauszusehen, dass sich während dieses Prozesses immer neue Ideen ergebenwerden, bis schließlich eine endgültige Version der Software erarbeitet ist.

5.4. Bedrohungen der Validität

Es gibt Faktoren, die sich möglicherweise nachteilig auf die Validität der Evaluationauswirken.

5.4.1. Anzahl der Probanden

Die Untersuchung hatte mit lediglich zwei Personen eine geringe Probandenzahl. Daskönnte sich nachteilig auf die Verwertbarkeit der Ergebnisse auswirken, Dem gegenüber

56

5.4. Bedrohungen der Validität

Tabelle 5.4. Hinweise für mögliche Verbesserungen

Verbesserungsvorschläge

Der Speed-Slider ist unnötig.

Auswahl einer Zeitspanne (Ein Tag, eine Stunde) für das Autoplay.

Über neues Menü Datum und Zeit für den Time-Slider über Tastatur eingeben.

Einfarbige Markierungen der Pfeile sind nicht sinnvoll.

Nicht jeden Pin im Koordinatensystem beschriften, dafür Schrift größer machen.

Der Farbverlauf des Bodens soll mehr Farben haben.

Höhenlinien für den Boden.

Die Stationsbeschriftung an allen vier Seiten und der Würfel sind unnötig. Besser wäreeine einzelne Schrift, die sich mit der Kamera mitbewegt.

Stationen einzeln entfernen und hinzufügen.

Genauere Beschreibung der Messstationen.

Ein interaktiver Zeiger, der, wenn gewünscht, Latitude, Longitude und Höhe eines Boden-punkts ausgeben lässt.

Beim Autoplay soll stunden- oder tageweise gesprungen werden können.

steht allerdings der hohe Expertenstatus der Teilnehmer. Die Ergebnisse der Befragung bie-ten aus diesem Grund einen hohen Mehrwert. Der Erkenntnisgewinn durch die Befragungdieser Experten ist deutlich größer als bei der Befragung einer fachfremden Zielgruppe.Hinzu kommt, dass der Umfang der gewonnenen Erkenntnisse ausreichend ist, um diezukünftige Weiterentwicklung des Programms über einen längeren Zeitraum hinweg zuplanen.

5.4.2. Zeitliche Beschränkung

Zudem waren beide Interviews mit einer zeitlichen Beschränkung verbunden; insbeson-dere eines davon. Hier stellt sich die Frage, ob sich die zeitliche Beschränkung negativausgewirkt haben könnte. Hier ist vor allem fraglich, ob Einfälle / freie Assozationen zuden Fragen durch die zeitliche Beschränkung behindert wurden. Grundsätzlich ist davonauszugehen, dass die zeitliche Einschränkung keine wesentlichen nachteiligen Folgen hatte.Die gestellten Fragen wurden vollständig und durchdacht beantwortet. Beide Teilnehmerhatten außerdem bereits im Vorfeld bei der Präsentation einzelner Zwischenstände einenEinblick in die Entwicklung erhalten. Sie brachten dabei selbst Vorschläge für die weitereEntwicklung ein.

57

Kapitel 6

Verwandte Arbeiten

Im folgenden Kapitel widmen wir uns Arbeiten, die der in dieser Bachelorarbeit entwickel-ten Anwendung ähnlich sind.

6.1. Fledermaus

Fledermaus1 ist eine von Quality Positioning Services B.V. entwickelte kommerzielle Software.Auch hier ist es möglich, die Daten zeitabhängig darzustellen. Eine Visualisierung einerBathymetrie mit Fledermaus geschieht hier ebenfalls dadurch, dass ermittelte Bodendatenaufbereitet und in die Software geladen werden. Hier ist es möglich, eine eigene Color-Mapzu definieren und den Boden nach eigenem Wunsch einzufärben. Auch die Beleuchtungobliegt der Auswahl des Nutzers. Ihren Namen erhalten hat die Software durch dieMöglichkeit des Nutzers, sich mittels einfacher Handbewegungen mit einer six degree offreedom mouse durch die Darstellung zu bewegen [Wright 2002]. Abbildung 6.1 zeigt eineBeispielanwendung.

6.2. ExplorViz

Eine weitere verwandte Arbeit ist ExplorViz2. Auch hier findet Daten-Visualisierung imWeb-Browser statt. Bei den visualisierten Daten handelt es sich um Programmzustände, diewährend der Laufzeit der visualisierten Software eingenommen werden. Die Visualisierungunterstützt den Anwender, das Verhalten des Softwaresystems nachzuvollziehen. Das wirdinsbesondere bei komplexem Programmcode relevant [Fittkau u. a. 2013] [Fittkau u. a. 2015].Abbildung 6.2 zeigt eine Landschaftsperspektive in der Anwendung.

1http://www.qps.nl/display/fledermaus/main.2http://www.explorviz.net.

59

6. Verwandte Arbeiten

Abbildung 6.1. Fledermaus (Quelle: deepref.orga)

ahttp://www.deepreef.org/technology/44-fledermaus.html.

60

6.2. ExplorViz

Abbildung 6.2. ExplorViz (Quelle: ExplorViza)

ahttps://www.explorviz.net/media_screenshots.php.

61

Kapitel 7

Fazit und Ausblick

Zum Abschluss beschäftigen wir uns mit dem Fazit und einem Ausblick.

7.1. Fazit

In der vorliegenden Bachelorarbeit haben wir eine 3-D-Visualisierung ozeanographischerDaten implementiert, die Bestandteil der Web-Anwendung OceanTEA geworden ist. DieseAnwendung basiert auf dem JavaScript-API Three.js und stellt verschiedene ozeanogra-pische Forschungsdaten dar. Für die gewünschte Region werden die Struktur des Mee-resbodens, die Position von Messstationen auf ihm sowie der zeitabhängige Verlauf vonStrömungen dargestellt. Das Programm wurde in der Endphase seiner Entwicklung mittelsqualitativer Experteninterviews beurteilt. Die damit verbundene Evaluation sollte ermitteln,ob sich das Programm zur Unterstützung wissenschaftlicher Tätigkeit einsetzen lässt. Diesehat ergeben, dass die Software in ihrem derzeitigen Stand bereits in der Forschung gewinn-bringend eingesetzt werden kann. Dennoch gibt es weiteren Optimierungsbedarf, der vorallem die Usability betrifft. Das Arbeiten mit der Software wird umso gewinnbringendersein, je mehr Hilfsmittel der Nutzer zum Ablesen der dargestellten Daten zur Verfügungstehen hat.

7.2. Ausblick

Die Ergebnisse der Evaluation bieten einen Ansatzpunkt für die zukünftige Entwicklungder Software. Gewünscht wurden einige zusätzliche Funktionen, die den Umgang desNutzers mit dem Programm und die wissenschaftliche Untersuchung der gezeigten Datenweiter vereinfachen können. Dabei gibt es bereits Ansätze in der vorhandenen Implemen-tierung für die Umsetzung dieser späteren Ziele. So stellt die Funktion testOceanFloorPo-sition() aus tests.js die Möglichkeit zur Verfügung, die genaue Lage eines ausgewähltenBodenpunkts ausgeben zu lassen. Für einige der gewünschten Funktionen muss die Nutze-roberfläche über zusätzliche oder auch andere HTML-Elemente verändert werden. Hierkönnte bei fortlaufender Entwicklung des Programms das Problem des Platzmangelsauftreten. Eine mögliche Lösung dafür wäre, Elemente der Nutzeroberfläche erst nacheinem Button-Klick erscheinen zu lassen. Eine Einfärbung des Bodens mit einer größe-ren Anzahl von Farben könnte über eine Erweiterung der THREE.Lut-Klasse geschehen.

63

7. Fazit und Ausblick

Ein anderer denkbarer Weg wäre der Einsatz von WebGL-Shadern, wobei diese eine neueLookup-Table erhalten müssten. Andere gewünschte Erweiterungen – etwa der Ablaufdes Autoplays über eine Zeitspanne oder die leichtere Auswahl eines Zeitpunkts – könnenvoraussichtlich über eine Anpassung des Quellcodes ohne Schwierigkeiten erreicht werden.Ziel der Entwicklung sollte dabei immer sein, die Software in Abstimmung mit denjenigenzu entwickeln, die sie verwenden.

64

Literaturverzeichnis

[Ashastina 2013] K. Ashastina. Water Mass Dynamics and Biogeochemistry of the Cold-Water Coral Reef, Stjernsund, Northern Norway. Magisterarbeit. Saint Petersburg StateUniversity / University of Hamburg, 2013. (Siehe Seite 17)

[Brüderlin u. a. 2013] B. Brüderlin, M. Johnson und A. Meier. Computergrafik undGeometrisches Modellieren. XLeitfäden der Informatik. Vieweg+Teubner Verlag, 2013.(Siehe Seiten 7 und 10)

[Comninos 2010] P. Comninos. Mathematical and Computer Programming Techniques forComputer Graphics. Springer London, 2010. (Siehe Seite 22)

[Dirksen 2015] J. Dirksen. Learning Three.js – the JavaScript 3D Library for WebGL. PacktPublishing, 2015. (Siehe Seiten 4 und 6)

[Fittkau u. a. 2015] F. Fittkau, S. Roth und W. Hasselbring. ExplorViz: Visual RuntimeBehavior Analysis of Enterprise Application Landscapes. In: 23rd European Conferenceon Information Systems (ECIS 2015). 2015. (Siehe Seite 59)

[Fittkau u. a. 2013] F. Fittkau, J. Waller, C. Wulf und W. Hasselbring. Live Trace Visualizationfor Comprehending Large Software Landscapes: The ExplorViz Approach. In: 1st IEEEInternational Working Conference on Software Visualization (VISSOFT 2013). 2013. (SieheSeite 59)

[Fowler und Lewis 2015] M. Fowler und J. Lewis. Microservices: Nur ein weiteres Konzeptin der Softwarearchitektur oder mehr? OBJEKTspektrum (2015). (Siehe Seite 3)

[Hughes u. a. 2013] J. F. Hughes, A. van Dam, M. McGuire, D. F. Sklar, J. D. Foley, S. K.Feiner und K. Akeley. Computer Graphics: Principles and Practice. Addison-WesleyProfessional, 2013. (Siehe Seite 6)

[Johanson u. a. ohne Datum] A. N. Johanson, S. Flögel, W.-C. Dullo und W. Hasselbring.OceanTEA: Exploring Ocean-Derived Climate Data Using Microservices. (Siehe Seiten 1und 3)

[Kaiser 2014] R. Kaiser. Qualitative Experteninterviews. Springer VS, 2014. (Siehe Seite 51)

[Kraus u. a. 2013] S. Kraus, G. Steinacker und O. Wegner. Teile und herrsche: KleineSysteme für grosse Architekturen. OBJEKTspektrum (2013). (Siehe Seite 3)

[Mukherjee 2004] D. Mukherjee. Fundamentals Of Computer Graphics And Multimedia.Prentice-Hall of India, 2004. (Siehe Seiten 6–8)

[Nielsen und Loranger 2006] J. Nielsen und H. Loranger. Prioritizing Web Usability.Pearson Education, 2006. (Siehe Seite 54)

65

Literaturverzeichnis

[Nischwitz u. a. 2012] A. Nischwitz, M. Fischer, P. Haberäcker und G. Socher. Computer-grafik und Bildverarbeitung: Band I: Computergrafik. Vieweg+Teubner Verlag, 2012.(Siehe Seiten 8, 10, 11)

[Nischwitz und Haberäcker 2013] A. Nischwitz und P. Haberäcker. Masterkurs Computer-grafik und Bildverarbeitung: Alles für Studium und Praxis. Vieweg+Teubner Verlag,2013. (Siehe Seiten 6, 7 und 11)

[Parisi 2012] T. Parisi. WebGL: Up and Running. O’Reilly Media, 2012. (Siehe Seiten 4, 5)

[Telea 2007] A. Telea. Data Visualization: Principles and Practice. CRC Press, 2007. (SieheSeite 1)

[Wright 2002] D. Wright. Undersea with GIS. Bd. 1. ESRI Press, 2002. (Siehe Seite 59)

66

Anhang

Der Bachelorarbeit liegt ein Datenträger bei.

Im Ordner Implementierung befindet sich der Quellcode.

Im Ordner Arbeit liegt eine digitale Version der schriftlichen Ausarbeitung.

Der Quellcode ist zudem online verfügbar unter https://build.se.informatik.uni-kiel.de/thesis/Patricia-Beier-BSc-2/tree/master/Implementierung

67