13
Ruprecht-Karls-Universität Heidelberg Sommersemester 2005 Fakultät für Mathematik und Informatik Institut für Informatik Softwarepraktikum für Anfänger Leitung: Dr. Michael J. Winckler EXCAVE Ein 3D Modell eines archäologischen Grabungsquadranten Matthias Guth Eichendorffstr. 5 69221 Dossenheim Email: [email protected]

Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

Embed Size (px)

Citation preview

Page 1: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

Ruprecht-Karls-Universität HeidelbergSommersemester 2005Fakultät für Mathematik und InformatikInstitut für InformatikSoftwarepraktikum für AnfängerLeitung: Dr. Michael J. Winckler

EXCAVEEin 3D Modell eines archäologischen

Grabungsquadranten

Matthias GuthEichendorffstr. 569221 DossenheimEmail: [email protected]

Page 2: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

Eine Archäologische Ausgrabung ist weit mehr, als nur das schiere Graben nach Funden. EineGrabung beginnt mit dem Einteilen des Areals in mehrere Quadranten von zumeist vier auf vierMetern. Anschließend wird die Humusdecke abgetragen, unter welcher dann das erste Planumangelegt wird. Ein Planum bezeichnet den eingeebneten Boden eines Quadranten. Nach dergroben Arbeit mit Spaten und Schaufel wird das Planum mit Kellen abgezogen - man spricht hiervom "Putzen des Planums". Bei diesem Vorgang wird die beim groben Aushub festgetretene Erdeentfernt und die darunterliegende, unberührte Erde freigelegt. Dadurch werden die Konturen vonBodenverfärbungen sichtbar, die für die weitere Vorgehensweise ausschlaggebend ist. Denn ebenanhand dieser Bodenverfärbungen entscheidet der Archäologe, wie der nächste Grabungsschrittauszusehen hat. Eine dunklere runde Verfärbung beispielsweise könnte auf eine Pfostengrubehindeuten. Um einen Pfosten im Boden zu verankern, wurde zunächst die Pfostengrubeausgehoben, der Pfosten dann dort hineingesetzt und anschließend die Grube wieder aufgefüllt –vorzugsweise mit Müll.Stößt man auf eine solche Pfostengrube im Profil, wird diese je nach Größe durch einen,beziehungsweise zwei Schnitte geteilt. Jedes zweite Segment wird dann ausgehoben und nebendem Planum auch die dadurch entstandenen Profile geputzt. Aus den Profilen kann man dann,sofern die Grube nicht durch Erosion, erdgrabende Tiere oder ähnliches gestört wurde, denursprünglichen Grubenverlauf erkennen und bei mehrstufiger Auffüllung möglicherweise dieunterschiedlichen Schichten.Schnitte sind das gängige Mittel um möglichst viel Informationen während der Ausgrabung zusammeln. Allerdings bedeutet jeder Schnitt einen immensen Zeitaufwand, weshalb dieser immerwohlbedacht anzubringen ist. Auf das Putzen des Planums und der Schnitte folgt das Dokumentieren der Grabungsschritte.Dies ist der zeitaufwendigste und auch wichtigste Teil der Grabung. Jeder Schnitt, jedes Planum,jedes Profil wird in einer zentimetergenauen Zeichnung festgehalten. Auf Millimeterpapier wirdzunächst das Planum oder Profil gezeichnet und koloriert, und anschließend werden die einzelnenObjekte wie Funde, Krotowinen (Gänge erdgrabender Tierchen) oder Wurzeln in die Zeichnungeingefügt. Funde wie Knochen, Keramik oder Hüttenlehm bekommen dabei eine festgelegteFarbe, bei den Bodenverfärbungen wird versucht, den Ton der vorgefundenen Verfärbung zutreffen.Da man in den seltensten Fällen eine exakt vier auf vier Meter große Grube vorfindet, werdensämtliche Koordinaten vom Mittelpunkt der Grube aus eingemessen. Zu Beginn der Grabungwird ein Raster auf das Terrain gelegt und die Mittelpunkte sind somit feste Anhaltspunkte.Neben den x- und y- Koordinaten sind selbstverständlich auch Höhen vermerkt, damit dieZeichnungen auch der richtigen Position zugewiesen werden können.Besondere Funde werden gesondert verwaltet und mit x-, y- und z-Koordinaten notiert.

Da es nun nicht allzu einfach ist, sich durch Zeichnungen zu arbeiten und sich die dritteDimension vorstellen zu müssen, kam mir die Idee eines dreidimensionalen Modells einesGrabungsquadranten. Der Nutzen, den man aus einem solchen Programm ziehen kann, istimmens. Während der Ausgrabung kann man dadurch auf einfachste Weise überprüfen, welcheZusammenhänge zwischen den einzelnen Befunden bestehen. Die Schnittplanung wird somitvereinfacht und unterstützt.Den größten Nutzen hat ein solches Programm allerdings bei der Auswertung der Grabung.Anstelle von Unmengen von Blättern in Größen von DIN A5 bis DIN A3, mit Zeichnungenunterschiedlichen Maßstabs, hat man hiermit die Möglichkeit, alles im korrekten Zusammenhangund im richtigen Größenverhältnis zu betrachten.

2

Page 3: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

Der Zeitaufwand für das Einfügen einer Zeichnung vom Scan bis zur Darstellung im Programmbeträgt momentan etwa 45 Minuten. Durch eine GUI wird sich der Prozess allerdings nocherheblich beschleunigen lassen.Hat man einmal ein solches Modell erstellt, kann man jederzeit darauf zurückgreifen und einerneutes Eindenken in die Zusammenhänge der Pläne entfällt.

Mein Programm "Excave" basiert auf der OpenGL-Engine JAFV von Herrn Dr. MichaelWinckler und Herrn Jörg Huber. Programmiert wurde in ANSI-C. Da ich mit dieserProgrammiersprache noch nicht in Berührung kam, nutzte ich das Praktikum auch dazu, mich indiese Sprache einzuarbeiten.

Im Folgenden werden nun die einzelnen Entwicklungsschritte erläutert.

3

Page 4: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

1) Koordinatensystem, Achsenkreuz

Zunächst war es nötig, ein Größenverhältnis zu wählen. Ich entschied mich der Einfachheit halberdafür, das Größenverhältnis der Engine beizubehalten. Ein Meter der Grabung entspricht einerLängeneinheit der Engine. Durch die Definition des Array als

GLFloat koordinaten[3][2]

war es problemlos möglich, auch Fließkommazahlen anzugeben.Als Hilfe für meine Arbeit erstellte ich zunächst eine Funktion, die mir ein Achsenkreuz zeichnet.Anhand dessen kann ich dann erkennen, ob später die Flächen auch an der richtigen Positiongezeichnet werden. Als Ursprung wählte ich die Koordinate (0.0 / 0.0 / Höhe über Adria). Imkonkreten Beispiel befinden wir uns etwa 187.00m über Adria, weshalb der Nullpunkt den Wert(0.0 / 0.0 / 187.00) bekommt. Alle Höhenangaben im Programm stehen in Abhängigkeit von derHöhe über Adria: y = y – Höhe über AdriaDie y-Achse entspricht dem geografischen Norden, die x-Achse demnach dem Osten.

Da sich das Koordinatenkreuz im Nachhinein auch als Anhaltspunkt für die Auswertung derGrabung als nützlich erwiesen hat, habe ich beschlossen, das Koordinatenkreuz als Feature imProgramm zu lassen.

2) Flächen

Die Koordinaten der einzelnen Flächen werden von den Zeichnungen abgelesen. Durch dasMillimeterpapier ist dies problemlos möglich. Als Reihenfolge der Koordinaten, die man von derZeichnung abliest, ist folgende vorgeschrieben:

Unten Links -> Oben Links -> Oben Rechts -> Unten RechtsFür ein Planum bedeutet dies:Süd-Westen -> Nord-Westen -> Nord-Osten -> Süd-Osten

Dementsprechend sind die Vorzeichen zu wählen:

(NW) (NO)oben links y oben rechts

x

unten links unten rechts(SW) (SO)

4

Page 5: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

Im Programm zeichnet die Funktion DrawTriangles das Rechteck mithilfe vonGL_TRIANGLE_STIP. Die Rechtecke werden hierzu durch die Diagonale in zwei Dreieckezerlegt, wodurch die korrekte Darstellung gewährleistet ist, denn durch die Ausgrabungspraxispraktisch unvermeidbare Höhenunterschiede werden somit ausgeglichen. Drei Punkte spannenimmer eine ebene Fläche auf. Die Punktreihenfolge wird durch die Funktion wie folgtumgewandelt:

Der Aufruf der Funktion „DrawTriangles“ erfolgt mit diesen Argumenten:DrawTriangles (Glfloat Koordinate1[3], Glfloat Koordinate2[3], GLfloat Koordinate3[3],Glfloat Koordinate4[3], tex_number)

Durch das Argument tex_number wird die zur Ebene passende Textur mittels glBindTexture(GL_TEXTURE_2D, tex_number) innerhalb der Funktion an die Ebene gebunden.

3) Belegen der Flächen mit TexturBevor die Scans als Texturen verwendet werden können, sollte man die Bilder noch etwaszurechtschneiden. Sinnvollerweise sollte nur der tatsächlich benötigte Bereich des Bildes auch alsTextur dienen. Als Dateiformat wird das „portable pixmap format“ verwendet, da dies für einespäter erklärte Funktion hervorragend geeignet ist. Das PPM-Bildformat besteht aus 4 ZeilenKopfinformationen gefolgt von RGB-Triplets für jeden Bildpunkt, d.h. jeder Bildpunkt wirddurch 3 Zeilen Rot-, Grün- und Blauwert repräsentiert. Die Routine ReadMyPPM verarbeitet dievorbereiteten Bilder.Da die Koordinaten wie schon erwähnt aus den Scans der Zeichnungen abgelesen werden, spieltes keine Rolle, ob das Verhältnis Höhe:Breite des Bildes auch dem Verhältnis der Koordinatenentspricht. Ich habe bei den Bildern das Verhältnis 1:1 gewählt, zumeist entweder 1024 : 1024oder 512 : 512. Durch Zuweisen an die entsprechende OpenGL Fläche wird das Bild beim Zeichenvorgangwieder auf die korrekte Größe gestreckt. Der User brauch dies bei der Umwandlung der Bilder indas PPM Format folglich nicht beachten.

5

Page 6: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

4) Transparenz (Alpha-Wert)

Ein weiteres Feature des Programms ist die Transparenz der Ebenen. Hierzu wird der bereitseingelesenen PPM-Datei ein weiteres Byte hinzugefügt – der Alpha-Wert. Ein Alpha-Wert von 0bedeutet Volltransparenz, eine undurchsichtige Textur besitzt einen Alpha-Wert von 255. Dieser Alpha-Wert wird nicht in der Bilddatei an sich gespeichert, sondern wird in denEbeneneigenschaften definiert (mehr dazu unter Punkt 8 – Erstellen der Structs). Diese einstellbare Transparenz ermöglicht das „Durchleuchten“ der Ebenen und somit dasgleichzeitige Betrachten mehrerer übereinanderliegenden Ebenen. Für die Interpretation derGrabungsbefunde ist dies von immensem Vorteil.Die Funktion AlphaChannel durchläuft das Bild Pixel für Pixel und fügt hinter den drei Bytes fürRot, Grün und Blau das eine Byte für den Alpha Wert ein:

for(y = 1; y <= hei; y++){ for (x = 1; x <= wid; x++){

Folgende vier Bilder zeigen zwei übereinanderliegende Ebenen mit verschiedenem Alpha-Wert: Alpha 255 Alpha 150

6

Page 7: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

Alpha 70 Alpha 0

5) transparente Polygone

Gibt es nun einen Bereich einer Ebene, der für die Interpretation nicht relevant ist, so besteht dieMöglichkeit, in jeder Ebene Polygone zu definieren, die ständig volltransparent sind. Die Pixel,die im Bereich dieser Polygone sind, bekommen folglich den Alpha-Wert 0, unabhängig vomdefinierten Alpha-Wert der Ebene. Zunächst werde ich die Vorgehensweise des Programms für ein einzelnes Polygon erklären:Wie schon unter Punkt 4 erklärt, wird das Bild Zeilenweise, Pixel für Pixel durchlaufen. Nun istzu klären, ob das aktuelle Pixel sich im Polygon befindet, oder außerhalb liegt. Hierzu habe ichim Internet folgende Idee gefunden: um zu überprüfen, ob sich ein Punkt innerhalb einesPolygons befindet, zieht man einen Strahl vom betreffenden Punkt in beliebige Richtung. DieAnzahl der Schnittpunkte des Strahls mit den Polygonseiten zeigt, ob der Punkt Element desPolygons ist. Bei einer geraden Anzahl an Schnittpunkten liegt er außerhalb, bei einer ungeradenAnzahl innerhalb des Polygons:

Zu Beginn der Routine AlphaChannelPoly wird der Bereich des Bildes ausgewählt, in welchemsich das Polygon befindet.

7

Page 8: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

Dadurch wird die notwendige Abfrage, ob sich das beim Durchlaufen des Bildes momentangeprüfte Pixel innerhalb des Polygons befindet, auf einen Bereich beschränkt. Somit muss nichtjedes Pixel des Bildes überprüft werden, sondern nur die wirklich relevanten:

Sind Polygone auf einer Fläche definiert, so wird die Funktion AlphaChannelPoly aufgerufen.Durch diese werden zunächst Pmin und Pmax ermittelt, die das zu überprüfende Rechteckaufspannen. Da die Punkte ja aus der pixelweisen Ausleseroutine heraus ermittelt werden, habenwir zunächst Pixelkoordinaten vor uns. Da das Polygon allerdings im Koordinatenraster derZeichnungen definiert wird, müssen die Pixel-Koordinaten zuerst in Zeichnungs-Koordinatenumgewandelt werden. Dies übernimmt die Funktion PointToPix:Um die Koordinaten umzuwandeln, muss ein Faktor berechnet werden. Hierzu wird zunächst derUrsprung des Zeichnungs-Koordinatensystems auf das Pixel-Koordinatensystem projiziert. Esmuss die Höhe und die Breite der Ebene ermittelt werden. Teilt man nun die Höhe der Ebenedurch die Anzahl der Zeilen der Textur, also die Höhe des Bildes, erhält man den Faktor für diey-Achse. Durch den gleichen Vorgang mit der Breite der Ebene und die Breite des Bildesbekommt man dementsprechend den Faktor für die x-Achse. Nun können die Pixel-Koordinatenumgerechnet werden und somit mit den Koordinaten des Polygons verglichen werden.

Befindet sich nun das aktuelle Pixel im Bereich, der durch die Punkte Pmin und Pmax, prüft dieFunktion PolyCheck , ob sich der Punkt innerhalb oder außerhalb der Polygons befindet. Liegt eraußerhalb, so liefert die Funktion 0 als Ergebnis. Das Pixel bekommt dann den Alpha-Wert, derfür die Ebene definiert ist. Ist die Rückgabe der Funktion >0, liegt der Punkt innerhalb desPolygons und bekommt den Alpha-Wert 0 – volltransparent.

Da nun aber die Möglichkeit bestehen sollte, mehrere Polygone auf der Ebene zu definieren,muss das Programm die Überprüfung für n Polygone vornehmen. Eine Variable check bekommtim Falle einer erfolgreichen Überprüfung die Nummer des Polygons zugewiesen, in dessenBereich sich der Punkt befindet:

int check=-1;for (j = 0; j < anzahl_polygone; j++){

if ( ((x >= range[j][0][0]) && (x <= range[j][1][0])) && (( y >= range[j][0][1]) && (y <= range [j][1][1])) )check=j;

Ist check also >= 0, befindet sich das Pixel im Bereich von Polygon[check]. Anschließend wirddann die oben bereits erläuterte Funktion PolyCheck aufgerufen.

8

Page 9: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

Das Definieren von volltransparenten Polygonen funktioniert momentan nur bei Ebenen. Wobeiman sich überlegen muss, ob eine Erweiterung auf Schnitte und Profile überhaupt sinnvoll ist.

6) Tastaturbelegung

Zur komfortablen Bedienung des Programms wurden verschiedene Tastaturbefehle eingerichtet:

Druck auf Tasten: Reaktion

1 Auswahl der Profile3 Auswahl der Plana5 Auswahl der Schnitte7 Objekte ein- bzw. ausschaltenSHIFT + 7 Volltransparenz der ausgewählten EbeneSHIFT + ß Nicht-Transparenz der ausgewählten EbeneSHIFT + 8 Verringern des Alpha-Werts um 10 (ausblenden)SHIFT + 9 Erhöhen des Alpha-Werts um 10 (einblenden)

Die ausgewählte Textur wird in der Konsole angezeigt, ebenso der aktuelle Alpha-Wert derTextur.

7) Objekte

Besondere Objekte, also z.B. Funde, die besonders hervorzuheben sind, können mit eineruntexturierten Sphäre markiert werden. Diese Sphären werden im Folgenden „Objekte“ genannt.Die Farbe der Objekte ist frei wählbar. Damit diese „Markierungen“ möglichst schnell gesetztwerden können, werden lediglich der Mittelpunkt sowie deren Länge, Breite und Höheangegeben.

Gezeichnet werden die Objekte durch die Funktion DrawObject . Wie unter Punkt 6 schonfestgehalten, können diese auch ein- und ausgeschalten werden.

9

Page 10: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

8) Erstellen der Structs

Die Daten der Plana, Profile und Schnitte werden in Structs gespeichert. Hierbei ist die Strukturfür alle drei Ebenenarten gleich und lediglich in anderen Variablen gespeichert. Dies dient inerster Linie der Übersicht und wird das Editieren der Daten, das in einer späterenProgrammversion folgen wird, ungemein erleichtern. Mehr dazu unter Punkt 9.Hier die Struktur des Ebenenstructs:

typedef struct planum_str { char texturename[50]; GLubyte global_trans; GLubyte alpha; GLfloat coords[4][3]; unsigned int polygone; unsigned int punkte[10]; GLfloat polygon_koords[10][2][2]; GLfloat faktor[2][2];} Plane;

Hier sind zwei Einschränkungen festzuhalten: der Texturname darf nicht mehr als 50 Zeichengroß sein und es dürfen maximal zehn Polygone pro Ebene definiert sein.

9) Laden und Speichern der Daten

Bevor das Laden/Speichern der Ebenendaten erfolgt, muss die Anzahl der Profile, Plana, Schnitteund Objekte feststehen, die verarbeitet werden sollen. Hierzu legt das Programm koordinaten.ceine Header-Datei an, in der alle zum Start relevanten Daten gesichert sind. Die Struktur derHeader-Datei sieht wie folgt aus:

typedef struct header_struct { char dir[150]; GLfloat over_adria; unsigned int anzahl_profile, anzahl_plana, anzahl_schnitte,anzahl_objekte;} HDR;

Die Variable dir erlaubt es, verschiedene Modelle zu realisieren. Sämtliche Dateien einesModells werden im Unterverzeichnis dir gespeichert. Diese Modelle sollen in einer späterenProgrammversion über eine GUI verwaltet werden können.Sind nun alle notwendigen Daten geladen, werden die Profile, Plana und Schnitte in eigeneStructs geladen. Der folgende Programmcode legt den Struct an (hier im Beispiel für die Profile):

Profile = (Plane *)malloc(anzahl_profile * sizeof(Plane));

10

Page 11: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

Ist dies geschehen, können die Daten der einzelnen Ebenen aus Binärdateien geladen werden.Angelegt werden diese durch koordinaten.c :

prof=fopen(fileloc, "w+b"); if(fwrite(&Profile[0],sizeof(Plane),Header.anzahl_profile,prof) == Header.anzahl_profile)printf("Daten für %i Profile geschrieben!!!!\n\n",Header.anzahl_profile);

else printf ("Fehler beim Schreiben der Datei!!!\n\n");fclose (prof);

Die manuelle Eingabe in die koordinaten.c – Datei soll in einer späteren Version mit einer GUIerledigt werden.

Das Speicherprogramm erstellt im konkreten Beispiel folgende Dateien:- K19.HDR – Die Header-Datei für das Modell K19- K19/plana.str - Die binären Struct- Daten für die Plana- K19/schnitte.str - Die binären Struct- Daten für die Schnitte- K19/profile.str - Die binären Struct- Daten für die Profile- K19/objekte.str - Die binären Struct- Daten für die Objekte

Der Objekt-Struct hat eine von den Ebenen abweichende Struktur:

typedef struct obj { char name[150]; GLfloat color[3]; GLfloat center[3]; GLfloat laenge; GLfloat breite; GLfloat hoehe;} Objects;

Die Variable center enthält die Koordinaten des Mittelpunkts der Sphäre, die anderen Variablensollten selbsterklärend sein. Die Variable name wird in dieser Programmversion zwar noch nichtverwendet, sie ist jedoch zum Verwalten der Objekte notwendig. Mit einer weiteren Taste soll ineiner späteren Programmversion auch durch die verschiedenen Objekte geschaltet werdenkönnen. Das aktive Objekt wird dann optisch hervorgehoben und der Name in der Konsoleausgegeben. Denkbar wäre auch eine Beschreibung zu den Objekten hinzuzufügen, die dann beiBedarf angezeigt wird.

11

Page 12: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

10) Screenshots

12

Page 13: Eine Archäologische Ausgrabung ist weit mehr, als nur das ...pille.iwr.uni-heidelberg.de/~grabung01/ressourcen/bericht.pdf · Programmiert wurde in ANSI-C. Da ich mit dieser Programmiersprache

13