Sitzung: Jeden Freitag in der Vorlesungszeit ab 16 Uhr c. t. im MAR 0.005. In der vorlesungsfreien Zeit unregelmäßig (Jemensch da?). Macht mit!

Javakurs/Übungsaufgaben/Multiarray

Mehrdimensionale Arrays

Mehrdimensionale Arrays in Java werden gewöhnlich als Arrays von Arrays gespeichert. Je höher die Dimension und je größer die Arrays, desto höher ist der zusätzliche Speicherbedarf für diese Arrays. So kann es beispielsweise die Speicherung großer Bilder (dreidimensional: Pixelposition in x-Richtung, Pixelposition in y-Richtung, RGB-Farbwert) nötig machen, eine andere Strategie einzuschlagen: Die Daten werden in ein einzelnes Array in besonderer Reihenfolge abgespeichert, und eine Methode rechnet den dreidimensionalen Index in einen eindimensionalen um. Dies lässt uns auf dieses eine Array so zugreifen, als handle es sich um eine komplexere Struktur. Das ist praktisch, da die Daten dann einerseits in der Form vorliegen, in der wir sie direkt der Grafikkarte „füttern“ können, nämlich eindimensional, wir sie aber gleichzeitig benutzen können wie ein zweidimensionales Bild von RGB(Rot-, Grün-, Blau-Anteil)-Pixeln.

Diese Aufgabe kann bereits nach dem 2. Vortrag in Angriff genommen werden und nimmt mit jeder weiteren Unteraufgabe an Schwierigkeit und benötigtem Wissen zu. Die Aufgabe ist besonders für Leute geeignet, die schon Erfahrungen mit anderen (imperativen/objektorientierten) Programmiersprachen haben.


Aufgaben:

1. Wieviel Speicherbedarf benötigt die konventionelle Speicherung zusätzlich für die inneren Arrays im Vergeich zu unserem Ansatz für ein RGB-Bild der Größe 256x256? (Annahme: ein Array benötigt 1 Speichereinheit)

2. Lies dir folgende Website durch: http://webster.cs.ucr.edu/AoA/Windows/HTML/Arraysa2.html. Was bedeuten die Begriffe column-major und (fortgeschritten) row-major? Nach welcher Formel werden im zwei- bzw dreidimensionalen Fall die Offsets berechnet?

3. Erstelle eine Klasse Bild. Ein Bild soll seine Breite und seine Höhe kennen. Erstelle hierzu zwei private Variablen. Die dritte Dimension, die (Farb-)Tiefe ist mit 3 fest, da wir annehmen, dass es sich ausschliesslich um RGB-Bilder handelt.

4. Fortgeschritten: Erstelle für die 3 eine finale statische Konstante (Farb-)Tiefe, um die 3 nicht immer explizit in den Code schreiben zu müssen.

5. Zusätzlich soll eine Variable pixels die eigentlichen Pixeldaten enthalten. Erstelle hierzu ein Character-Array pixels der Größe Breite*Höhe*3 und initialisiere die RGB-Werte einheitlich mit fortlaufenden Nummern. Wie sind Breite und Höhe zu setzen, wenn es sich um ein quadratisches Bild handelt und der volle Datenumfang des characters (8 bit) ausgenutzt werden soll?

6. Es soll Getter-Methoden für die Höhe und die Breite sowie für das Datenarray geben.

7. Fortgeschritten: Schreibe einen Konstruktor, der die Höhe, die Breite, und eindimensionales Array als Parameter bekommt.

8. Erstelle eine allgemeine Getter- Methode die ein Character zurückgibt, und eine setter-Methode. Beide sollen auf unser eindimensionales Pixeldatenarray so zugreifen, als wäre es ein dreidimensionales.

9. Fortgeschritten: Wirf eine Exception, wenn einer der übergebenen Indizes über die im Objekt gespeicherte Höhe, Breite oder (Farb-)Tiefe hinausgehen! Was passiert, wenn beim Zugriff der aus dem falschen dreidimensionalen Index berechnete eindimensionale Index innerhalb, was ausserhalb des Arrays pixels liegt?
Überprüfe zudem im Konstruktor, dass Höhe*Breite*3 gleich pixels.length (by the way eine finale Instanzvariable. Was heißt das?) ist! Wirf ebenfalls eine Exception. Was wäre über Alternativen mit speziellen Rückgebewerten, die einen Fehler anzeigen zu sagen?

10. Erstelle eine Methode float setPixel(int x, int y, char R, char G, char B) und Methoden, die die Rot- Grün- und Blauwerte auslesen. Nutze hierbei die bereits implementierten, allgemeineren Setter- und Getter-Methoden.

11. Implementiere eine Methode, die das Pixelarray traversiert und die Rot-Grün-und Blauwerte auf den Bildschirm ausgibt. Nutze hierbei die bereits implementierten Getter-Methoden.

12. In der Bildbearbeitung werden auf zweidimensionale Bilder verschiedene Filter angewandt. Wir möchten hier einen einfachen Glättungsfilter implementieren, der harte Kanten weichzeichnet. Der funktioniert so: Nimm den oberen, den unteren, den linken, und den rechten Pixelwert plus den Wert des Pixels selbst, teile das durch 5 und setze das Pixel mit dem entsprechenden Wert. Hinweis: Pixel, die ausserhalb des Bildes liegen, werden als schwarz (0, 0, 0) angenommen. Fortgeschritten: Als Randbedingung kann man auch annehmen, dass sich das Bild an den Ränder so fortsetzt, wie es geendet hat.

13. Fortgeschritten: Verschiedene Grafik-APIs benutzen column-major oder row-major-Format. Ein Bild soll „wissen“, ob es column-major oder row-major ist. Implementiere Setter- und Getter-Methoden!

14. Fortgeschritten: Erweitere die Setter-Methode derart, dass sie das Pixelarray in die jeweils andere Speicherungsform konvertiert! Was zeigt dies über die Sinnhaftigkeit von privaten Attributen und den Gebrauch von Setter- und Getter-Methoden?

15. Fortgeschritten: Wie könnte man unsere Klasse Bild verfeinern, um auch Grauwertbilder und Bilder mit Alphakanal abspeichern zu können? Welche Attribute und Methoden kann man in eine gemeinsame Superklasse zentralisieren?

16. Fortgeschritten: Zelluläre Automaten werden in der Computergraphik eingesetzt, um komplexes Verhalten wie etwa Rauch, Feuer, aber auch Staubildung zu simulieren. Es gibt sogar ernstzunehmende Wissenschaftler, die behaupten, unsere gesamte Welt wäre ein zellulärer Automat. Zelluläre Automaten basieren auf dem Prinzip, dass Zellen lokal Informationen austauschen, d.h. dass der Zustand einer Zelle vom Zustand der direkten Nachbarzellen abhängt. Hatten wir nicht sowas ähnliches schon? Richtig, der Glättungsfilter aus Aufgabe 12 arbeitete auch so ähnlich.
Für Zelluläre Automaten, besonders dreidimensionale, ist Speichereffizienz besonders wichtig, da für realistische Animationen mehrere hundert mal hundert mal hundert Zellen angelegt werden müssen.
Lest diese Website über Conways Game of Life und habt Spaß: http://www.bitstorm.org/gameoflife/

Kommentare

Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf "bearbeiten" und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)

Robert

Na mal schauen, ob irgendjemand diese Funktion wirklich benutzt. Ich fände es jedenfalls toll.

Kai

Wohl kaum, viel zu viele Aufgaben ;)