5 Commits

Author SHA1 Message Date
708515ee4f AB8/5 2022-06-07 14:40:54 +02:00
a951b5c14a AB8/3 + AB8/4 2022-06-07 14:36:07 +02:00
150eb7aa49 AB8/2 2022-06-04 13:30:20 +02:00
ac40ada302 AB8/1 2022-06-03 16:46:03 +02:00
cfba0106a9 Refacotr code for AB8 2022-06-03 14:23:51 +02:00
19 changed files with 589 additions and 302 deletions

View File

@ -10,32 +10,32 @@ Diese Aufgabenstellung ist ein vollständiges IntelliJ-Projekt, das Sie bereits
- Einstellen des _Project SDK_: Öffnen Sie dazu in IntelliJ die Projekteinstellungen (_File_ -> _Project Structure..._) und wählen Sie ein JDK unter _Project | Project SDK_ aus. - Einstellen des _Project SDK_: Öffnen Sie dazu in IntelliJ die Projekteinstellungen (_File_ -> _Project Structure..._) und wählen Sie ein JDK unter _Project | Project SDK_ aus.
## Thema ## Thema
Das allgemeine Thema dieses und der kommenden Aufgabenblätter ist der Weltraum und die Simulation der physikalischen Gesetze, die für Himmelskörper gelten. Obwohl ein möglichst exaktes physikalisches Modell wünschenswert ist, ist bei der Implementierung die Genauigkeit der physikalischen Modelle sekundär. Konzeptuelle Fehler bei den physikalischen Berechnungen spielen keine Rolle bei der Bewertung. Schwerpunkt sind die Konzepte der Programmiersprache. Das allgemeine Thema dieses und der kommenden Aufgabenblätter ist der Weltraum und die Simulation der physikalischen Gesetze, die für Himmelskörper gelten. Obwohl ein möglichst exaktes physikalisches Modell wünschenswert ist, ist bei der Implementierung die Genauigkeit der physikalischen Modelle sekundär. Konzeptuelle Fehler bei den physikalischen Berechnungen spielen keine Rolle bei der Bewertung. Schwerpunkt sind die Konzepte der Programmiersprache.
## Ziel ## Ziel
Ziel der Aufgabe ist die Anwendung der Konzepte: Objekt- vs. Klassenmethode, Datensatz, Data Hiding, Konstruktoren (siehe Skriptum Seiten 31-50). Ziel der Aufgabe ist die Anwendung der Konzepte: Objekt- vs. Klassenmethode, Datensatz, Data Hiding, Konstruktoren (siehe Skriptum Seiten 31-50).
## Aufgaben ## Aufgaben
1. Lesen Sie sich die Kommentare in den Dateien durch und führen Sie die Klasse `Simulation` aus. 1. Lesen Sie sich die Kommentare in den Dateien durch und führen Sie die Klasse `Simulation` aus.
2. Data hiding: 2. Data hiding:
1. Machen Sie in den Klassen `Vector3` und `Body` alle Objektvariablen `private`. 1. Machen Sie in den Klassen `Vector3` und `Body` alle Objektvariablen `private`.
2. Definieren Sie entsprechende Konstruktoren, um die Objektvariablen zu initialisieren. `Simulation` soll nur noch diese nutzen und nicht mehr direkt auf die Objektvariablen zugreifen dürfen. Testen Sie zunächst die vervollständigten Klassen `Vector3` und `Body` mit der Klasse `Aufgabe1Test`. Entfernen Sie dazu die Kommentarzeichen in der Klassendefinition. 2. Definieren Sie entsprechende Konstruktoren, um die Objektvariablen zu initialisieren. `Simulation` soll nur noch diese nutzen und nicht mehr direkt auf die Objektvariablen zugreifen dürfen. Testen Sie zunächst die vervollständigten Klassen `Vector3` und `Body` mit der Klasse `Aufgabe1Test`. Entfernen Sie dazu die Kommentarzeichen in der Klassendefinition.
3. Datenkapselung: Anstelle der gegebenen statischen Methoden in der Datei `Simulation.java` sollen nur noch entsprechende Objektmethoden der Klassen `Body` und `Vector3` benutzt werden. (Ausnahme ist die Methode `main`. Die statischen Methoden der Klasse `SpaceDraw` müssen auch nicht verändert werden.) Implementieren Sie dazu die spezifizierten Methoden und bauen Sie `Simulation` so um, dass anstelle der Aufrufe statischer Methoden Objektmethoden genutzt werden. Sie sollen alle in `Body` und `Vector3` spezifizierten Methoden implementieren, auch wenn nicht alle von `Simulation` genutzt werden. Die in `Simulation.java` gegebenen statischen Methoden können dann entfernt werden (natürlich bis auf die erwähnten Ausnahmen). Nutzen Sie die implementierten Methoden auch in `Simulation.java`, um die Himmelskörper zu bewegen und zu zeichnen. 3. Datenkapselung: Anstelle der gegebenen statischen Methoden in der Datei `Simulation.java` sollen nur noch entsprechende Objektmethoden der Klassen `Body` und `Vector3` benutzt werden. (Ausnahme ist die Methode `main`. Die statischen Methoden der Klasse `SpaceDraw` müssen auch nicht verändert werden.) Implementieren Sie dazu die spezifizierten Methoden und bauen Sie `Simulation` so um, dass anstelle der Aufrufe statischer Methoden Objektmethoden genutzt werden. Sie sollen alle in `Body` und `Vector3` spezifizierten Methoden implementieren, auch wenn nicht alle von `Simulation` genutzt werden. Die in `Simulation.java` gegebenen statischen Methoden können dann entfernt werden (natürlich bis auf die erwähnten Ausnahmen). Nutzen Sie die implementierten Methoden auch in `Simulation.java`, um die Himmelskörper zu bewegen und zu zeichnen.
## Zusatzfragen ## Zusatzfragen
Beantworten Sie folgende Zusatzfragen als Kommentar in `Simulation.java`: Beantworten Sie folgende Zusatzfragen als Kommentar in `Simulation.java`:
1. Was versteht man unter _Datenkapselung_? Geben Sie ein Beispiel, wo dieses Konzept in dieser Aufgabenstellung angewendet wird. 1. Was versteht man unter _Datenkapselung_? Geben Sie ein Beispiel, wo dieses Konzept in dieser Aufgabenstellung angewendet wird.
2. Was versteht man unter _Data Hiding_? Geben Sie ein Beispiel, wo dieses Konzept in dieser Aufgabenstellung angewendet wird. 2. Was versteht man unter _Data Hiding_? Geben Sie ein Beispiel, wo dieses Konzept in dieser Aufgabenstellung angewendet wird.
3. Was steht bei einem Methodenaufruf links vom `.` (z.B. bei `SpaceDraw.massToColor(1e30)` oder 3. Was steht bei einem Methodenaufruf links vom `.` (z.B. bei `SpaceDraw.massToColor(1e30)` oder
`body.radius()`)? Woran erkennt man dabei Objektmethoden? `body.radius()`)? Woran erkennt man dabei Objektmethoden?
### Denkanstöße (ohne Bewertung) ### Denkanstöße (ohne Bewertung)
Folgende Fragen sind als Denkanstöße gedacht und bilden die Grundlage für eine Diskussion in der Übungseinheit zu diesem Aufgabenblatt. Folgende Fragen sind als Denkanstöße gedacht und bilden die Grundlage für eine Diskussion in der Übungseinheit zu diesem Aufgabenblatt.
1. Welche anderen oder weiteren Objektmethoden hätten Sie zur Verfügung gestellt, wenn es keine Vorgaben gegeben hätte? 1. Welche anderen oder weiteren Objektmethoden hätten Sie zur Verfügung gestellt, wenn es keine Vorgaben gegeben hätte?
2. Wann wäre es sinnvoll, die Klasse `SpaceDraw` so zu ändern, dass diese ebenfalls Objektmethoden 2. Wann wäre es sinnvoll, die Klasse `SpaceDraw` so zu ändern, dass diese ebenfalls Objektmethoden
zur Verfügung stellt? zur Verfügung stellt?
#### _Punkteaufteilung_ #### _Punkteaufteilung_

View File

@ -1,7 +1,7 @@
# Aufgabenblatt 2 # Aufgabenblatt 2
## Allgemeine Anmerkungen ## Allgemeine Anmerkungen
Ihre Lösung für dieses Aufgabenblatt ist bis Montag, 28.3. 11h durch `git commit` und `push` Ihre Lösung für dieses Aufgabenblatt ist bis Montag, 28.3. 11h durch `git commit` und `push`
abzugeben. Mit der Angabe werden folgende Dateien mitgeliefert: `BodyQueue.java`, `BodyForceMap.java` und `Aufgabe2Test.java`. Diese Klassen dürfen nur an den Stellen verändert werden, die mit `TODO` markiert sind. Zusätzliche Klassen, Interfaces, Methoden und Variablen dürfen aber eingefügt werden. Wenn Sie zusätzlich zu den gefragten Klassen, weitere Klassen definieren, achten Sie darauf, dass die Klassennamen mit `My` beginnen, um Konflikte mit späteren Aufgabenblättern zu vermeiden. abzugeben. Mit der Angabe werden folgende Dateien mitgeliefert: `BodyQueue.java`, `BodyForceMap.java` und `Aufgabe2Test.java`. Diese Klassen dürfen nur an den Stellen verändert werden, die mit `TODO` markiert sind. Zusätzliche Klassen, Interfaces, Methoden und Variablen dürfen aber eingefügt werden. Wenn Sie zusätzlich zu den gefragten Klassen, weitere Klassen definieren, achten Sie darauf, dass die Klassennamen mit `My` beginnen, um Konflikte mit späteren Aufgabenblättern zu vermeiden.
## Ziel ## Ziel
@ -10,10 +10,10 @@ Ziel der Aufgabe ist die Implementierung einer linearen und einer assoziativen D
## Beschreibung der gegebenen Dateien ## Beschreibung der gegebenen Dateien
- `BodyQueue` ist das Gerüst für eine Implementierung einer linearen Datenstruktur zur Verwaltung - `BodyQueue` ist das Gerüst für eine Implementierung einer linearen Datenstruktur zur Verwaltung
von Objekten des Typs `Body`. von Objekten des Typs `Body`.
- `BodyForceMap` ist das Gerüst für eine Implementierung einer assoziativen Datenstruktur, die - `BodyForceMap` ist das Gerüst für eine Implementierung einer assoziativen Datenstruktur, die
einen Himmelskörper mit der auf ihn wirkenden Kraft assoziiert. einen Himmelskörper mit der auf ihn wirkenden Kraft assoziiert.
- `Aufgabe2Test` ist eine vorgegebene Klasse, die Sie zum Testen Ihrer Implementierung verwenden - `Aufgabe2Test` ist eine vorgegebene Klasse, die Sie zum Testen Ihrer Implementierung verwenden
sollten. Bei einer fehlerfreien Implementierung sollten bei der Ausführung dieser Klasse keine Exceptions geworfen werden und alle Tests als erfolgreich ("successful") ausgegeben werden. Sie müssen diese Klasse nicht verändern, können aber eigene Testfälle hinzufügen. sollten. Bei einer fehlerfreien Implementierung sollten bei der Ausführung dieser Klasse keine Exceptions geworfen werden und alle Tests als erfolgreich ("successful") ausgegeben werden. Sie müssen diese Klasse nicht verändern, können aber eigene Testfälle hinzufügen.
## Aufgaben ## Aufgaben
@ -27,10 +27,10 @@ Ihre Aufgaben sind folgende:
Body[] keys; // assume descending order according to mass Body[] keys; // assume descending order according to mass
Body toInsert; Body toInsert;
... ...
int left = 0; int left = 0;
int right = size - 1; int right = size - 1;
while (left <= right) { while (left <= right) {
int middle = left + ((right - left) / 2); int middle = left + ((right - left) / 2);
if (keys[middle].mass() < toInsert.mass()) { if (keys[middle].mass() < toInsert.mass()) {
@ -39,14 +39,14 @@ Ihre Aufgaben sind folgende:
left = middle + 1; left = middle + 1;
} }
} }
// index where to insert: right + 1 // index where to insert: right + 1
``` ```
4. Bauen Sie die bereits bestehende Klasse `Simulation` so um, dass keine Kollisionen von Himmelskörpern mehr berücksichtigt werden. Dadurch soll der Programmcode vereinfacht werden. Die Anzahl der Himmelskörper ändert sich im Laufe der Simulation somit nicht. Testen Sie die Simulation. 4. Bauen Sie die bereits bestehende Klasse `Simulation` so um, dass keine Kollisionen von Himmelskörpern mehr berücksichtigt werden. Dadurch soll der Programmcode vereinfacht werden. Die Anzahl der Himmelskörper ändert sich im Laufe der Simulation somit nicht. Testen Sie die Simulation.
5. Ändern Sie nun die Klasse `Simulation` so, dass zur Verwaltung der Himmelskörper anstelle des Arrays Objekte der Klassen `BodyQueue` und `BodyForceMap` verwendet werden. Das heißt beispielsweise, dass die Zugriffe auf die Himmelskörper der Simulation über Methoden von `BodyQueue` erfolgen müssen. Anstelle des Arrays `forceOnBody` soll ein Objekt des Typs `BodyForceMap` benutzt werden. 5. Ändern Sie nun die Klasse `Simulation` so, dass zur Verwaltung der Himmelskörper anstelle des Arrays Objekte der Klassen `BodyQueue` und `BodyForceMap` verwendet werden. Das heißt beispielsweise, dass die Zugriffe auf die Himmelskörper der Simulation über Methoden von `BodyQueue` erfolgen müssen. Anstelle des Arrays `forceOnBody` soll ein Objekt des Typs `BodyForceMap` benutzt werden.
6. Testen Sie die Simulation wieder. Das Verhalten der Simulation sollte unverändert sein. Je nach Implementierung der Klassen `BodyQueue` und `BodyForceMap` ist es möglich (und kein Problem), dass die Simulation jetzt langsamer läuft, als nach dem Umbau in Schritt 4. 6. Testen Sie die Simulation wieder. Das Verhalten der Simulation sollte unverändert sein. Je nach Implementierung der Klassen `BodyQueue` und `BodyForceMap` ist es möglich (und kein Problem), dass die Simulation jetzt langsamer läuft, als nach dem Umbau in Schritt 4.
7. (Freiwillige Zusatzaufgabe ohne Bewertung:) Testen Sie die Simulation mit den folgenden fünf 7. (Freiwillige Zusatzaufgabe ohne Bewertung:) Testen Sie die Simulation mit den folgenden fünf
Himmelskörpern: Himmelskörpern:
``` ```
Body sun = new Body(1.989e30,new Vector3(0,0,0),new Vector3(0,0,0)); Body sun = new Body(1.989e30,new Vector3(0,0,0),new Vector3(0,0,0));
Body earth = new Body(5.972e24,new Vector3(-1.394555e11,5.103346e10,0),new Vector3(-10308.53,-28169.38,0)); Body earth = new Body(5.972e24,new Vector3(-1.394555e11,5.103346e10,0),new Vector3(-10308.53,-28169.38,0));
@ -60,4 +60,4 @@ Himmelskörpern:
- Implementierung von `BodyQueue`: 2 Punkte - Implementierung von `BodyQueue`: 2 Punkte
- Implementierung von `BodyForceMap`: 2 Punkte - Implementierung von `BodyForceMap`: 2 Punkte
- Anpassung von `Simulation`: 1 Punkt - Anpassung von `Simulation`: 1 Punkt
- Gesamt: 5 Punkte - Gesamt: 5 Punkte

View File

@ -2,15 +2,15 @@
## Allgemeine Anmerkungen ## Allgemeine Anmerkungen
Ihre Lösung für dieses Aufgabenblatt ist bis Montag, 2.5. 11h durch `git commit` und `push` Ihre Lösung für dieses Aufgabenblatt ist bis Montag, 2.5. 11h durch `git commit` und `push`
abzugeben. Mit der Angabe werden die Dateien `CosmicSystem.java`, `Drawable.java`, abzugeben. Mit der Angabe werden die Dateien `CosmicSystem.java`, `Drawable.java`,
`NamedBodyForcePair.java`, `HierarchicalSystem.java`, `Simulation4.java` und `Aufgabe4Test.java` `NamedBodyForcePair.java`, `HierarchicalSystem.java`, `Simulation4.java` und `Aufgabe4Test.java`
mitgeliefert. mitgeliefert.
Wenn Sie zusätzlich zu den gefragten Klassen weitere Klassen definieren, achten Sie darauf, dass Wenn Sie zusätzlich zu den gefragten Klassen weitere Klassen definieren, achten Sie darauf, dass
die Klassennamen mit `My` beginnen, um Konflikte mit späteren Aufgabenblättern zu vermeiden. die Klassennamen mit `My` beginnen, um Konflikte mit späteren Aufgabenblättern zu vermeiden.
## Ziel ## Ziel
Ziel der Aufgabe ist die Anwendung der Konzepte: Interfaces, dynamisches Binden, toString() Ziel der Aufgabe ist die Anwendung der Konzepte: Interfaces, dynamisches Binden, toString()
(siehe Skriptum Seite 75-84). (siehe Skriptum Seite 75-84).
## Beschreibung der gegebenen Dateien ## Beschreibung der gegebenen Dateien
@ -20,7 +20,7 @@ Ziel der Aufgabe ist die Anwendung der Konzepte: Interfaces, dynamisches Binden,
Hierarchie von Systemen und Subsystemen beschreiben. Unser Sonnensystem ist ein Beispiel eines Systems, Hierarchie von Systemen und Subsystemen beschreiben. Unser Sonnensystem ist ein Beispiel eines Systems,
das mehrere Teilsysteme beinhaltet. Ein solches Teilsystem ist beispielsweise das System Erde und Erdmond. das mehrere Teilsysteme beinhaltet. Ein solches Teilsystem ist beispielsweise das System Erde und Erdmond.
Ein anderes Teilsystem wäre Jupiter mit seinen Monden. Verändern Sie dieses Interface nicht. Ein anderes Teilsystem wäre Jupiter mit seinen Monden. Verändern Sie dieses Interface nicht.
- [Drawable](../src/Drawable.java) wird von `CosmicSystem` verwendet. Verändern Sie dieses Interface - [Drawable](../src/Drawable.java) wird von `CosmicSystem` verwendet. Verändern Sie dieses Interface
nicht. nicht.
- [NamedBodyForcePair](../src/NamedBodyForcePair.java) ist das Gerüst für eine Klassendefinition. - [NamedBodyForcePair](../src/NamedBodyForcePair.java) ist das Gerüst für eine Klassendefinition.
Die Klasse implementiert `CosmicSystem` und repräsentiert einen einzelnen benannten Himmelskörper Die Klasse implementiert `CosmicSystem` und repräsentiert einen einzelnen benannten Himmelskörper
@ -34,8 +34,8 @@ die Simulation analog zur Klasse `Simulation` implementiert werden (damit Sie Ih
Datei](../src/Simulation.java) nicht überschreiben müssen). Datei](../src/Simulation.java) nicht überschreiben müssen).
- [Aufgabe4Test](../src/Aufgabe4Test.java) ist eine vorgegebene Klasse, die Sie zum Testen Ihrer - [Aufgabe4Test](../src/Aufgabe4Test.java) ist eine vorgegebene Klasse, die Sie zum Testen Ihrer
Implementierung verwenden sollten. Bei einer fehlerfreien Implementierung sollten bei der Implementierung verwenden sollten. Bei einer fehlerfreien Implementierung sollten bei der
Ausführung dieser Klasse keine Exceptions geworfen werden und alle Tests als erfolgreich ("successful") Ausführung dieser Klasse keine Exceptions geworfen werden und alle Tests als erfolgreich ("successful")
ausgegeben werden. Entfernen Sie die Kommentarzeichen, um diese Klasse verwenden zu können. Sie ausgegeben werden. Entfernen Sie die Kommentarzeichen, um diese Klasse verwenden zu können. Sie
müssen diese Klasse nicht weiter verändern, können aber eigene Testfälle hinzufügen. müssen diese Klasse nicht weiter verändern, können aber eigene Testfälle hinzufügen.
## Aufgaben ## Aufgaben
@ -45,7 +45,7 @@ Ihre Aufgaben sind folgende:
**1. Implementierung von `CosmicSystem` in `NamedBodyForcePair`:** **1. Implementierung von `CosmicSystem` in `NamedBodyForcePair`:**
Fügen Sie in der Klasse `Body` eine öffentliche Methode `massCenter()` hinzu, die die Fügen Sie in der Klasse `Body` eine öffentliche Methode `massCenter()` hinzu, die die
Position des Himmelskörpers liefert. Position des Himmelskörpers liefert.
Definieren Sie die Klasse `NamedBodyForcePair` so, dass sie das Interface `CosmicSystem` Definieren Sie die Klasse `NamedBodyForcePair` so, dass sie das Interface `CosmicSystem`
implementiert. Die Methoden `getMass()` und `getMassCenter()` geben lediglich die Masse bzw. implementiert. Die Methoden `getMass()` und `getMassCenter()` geben lediglich die Masse bzw.
Position des Himmelskörpers zurück. Position des Himmelskörpers zurück.
@ -84,14 +84,14 @@ Kraft, indem alle Kräfte die von Körpern aus `this` auf das `NamedBodyForcePai
ausgeübt werden, zur Kraft im Objekt hinzuaddiert werden. Beispiel: Die ausgeübt werden, zur Kraft im Objekt hinzuaddiert werden. Beispiel: Die
Anweisung `cs.addForce(cs)` aktualisiert alle wechselseitigen im System `cs` wirkenden Kräfte. Anweisung `cs.addForce(cs)` aktualisiert alle wechselseitigen im System `cs` wirkenden Kräfte.
- `update()` führt auf Basis der gespeicherten Kräfte alle Bewegungen im System `this` durch und - `update()` führt auf Basis der gespeicherten Kräfte alle Bewegungen im System `this` durch und
setzt danach alle Kräfte wieder auf den null-Vektor zurück. setzt danach alle Kräfte wieder auf den null-Vektor zurück.
- `getBodies()` liefert eine Liste (Typ: `BodyLinkedList`) mit allen Himmelskörpern aus `this`. - `getBodies()` liefert eine Liste (Typ: `BodyLinkedList`) mit allen Himmelskörpern aus `this`.
**3. Implementierung von `Simulation4`:** **3. Implementierung von `Simulation4`:**
Implementieren Sie die Simulationsschleife unter Verwendung eines Objekts vom Typ Implementieren Sie die Simulationsschleife unter Verwendung eines Objekts vom Typ
`HierachicalSystem`. Alle Berechnungen sollen mittels Methoden von `CosmicSystem` durchgeführt `HierachicalSystem`. Alle Berechnungen sollen mittels Methoden von `CosmicSystem` durchgeführt
werden. werden.
@ -110,7 +110,7 @@ die einzelnen Körper in `cs` dadurch erreicht werden, dass `this` für alle sei
und Untersysteme `addForceTo(cs)` aufruft. Wird beim rekursiven Abstieg ein einzelner Himmelskörper und Untersysteme `addForceTo(cs)` aufruft. Wird beim rekursiven Abstieg ein einzelner Himmelskörper
erreicht (Blattknoten) ruft dieser `cs.addForceFrom(this)` auf. erreicht (Blattknoten) ruft dieser `cs.addForceFrom(this)` auf.
- Achten Sie bei der Berechnung der Kräfte in `addForceFrom(Body b)` darauf, dass die Kraft nicht - Achten Sie bei der Berechnung der Kräfte in `addForceFrom(Body b)` darauf, dass die Kraft nicht
verändert wird, wenn `this` und `b` derselbe Himmelskörper sind. verändert wird, wenn `this` und `b` derselbe Himmelskörper sind.
#### _Punkteaufteilung_ #### _Punkteaufteilung_

View File

@ -58,7 +58,7 @@ Ihre Aufgaben sind folgende:
**3. Vervollständigen von `MassiveLinkedList`:** **3. Vervollständigen von `MassiveLinkedList`:**
Definieren Sie `MassiveLinkedList`. Die Klasse ist wie `BodyLinkedList` aufgebaut, mit dem Definieren Sie `MassiveLinkedList`. Die Klasse ist wie `BodyLinkedList` aufgebaut, mit dem
Unterschied, dass der Elementtyp statt `Body` nun der Typ `Massive` ist. Die Methode `indexOf` Unterschied, dass der Elementtyp statt `Body` nun der Typ `Massive` ist. Die Methode `indexOf`
vergleicht Objekte mittels `equals`. vergleicht Objekte mittels `equals`.
**4. Implementierung von `MassiveForceHashMap`:** **4. Implementierung von `MassiveForceHashMap`:**
@ -98,5 +98,5 @@ Ihre Aufgaben sind folgende:
- Implementierung von `MassiveForceHashMap`: 2 Punkte - Implementierung von `MassiveForceHashMap`: 2 Punkte
- Implementierung von `MassiveLinkedList`: 0.5 Punkte - Implementierung von `MassiveLinkedList`: 0.5 Punkte
- Implementierung von `Simulation5`: 1 Punkte - Implementierung von `Simulation5`: 1 Punkte
- Gesamt: 5 Punkte - Gesamt: 5 Punkte

View File

@ -3,8 +3,8 @@
## Allgemeine Anmerkungen ## Allgemeine Anmerkungen
Ihre Lösung für dieses Aufgabenblatt ist bis Montag, 23.5. 11h durch `git commit` und `git push` Ihre Lösung für dieses Aufgabenblatt ist bis Montag, 23.5. 11h durch `git commit` und `git push`
abzugeben. Mit der Angabe werden die Dateien `MassiveIterable.java`, `MassiveIterator.java`, abzugeben. Mit der Angabe werden die Dateien `MassiveIterable.java`, `MassiveIterator.java`,
`MassiveSet.java`, `MassiveForceTreeMap.java`, `Simulation6.java` und `Aufgabe6Test.java` `MassiveSet.java`, `MassiveForceTreeMap.java`, `Simulation6.java` und `Aufgabe6Test.java`
mitgeliefert. mitgeliefert.
Wenn Sie zusätzlich zu den gefragten Klassen weitere Klassen definieren, achten Sie darauf, dass Wenn Sie zusätzlich zu den gefragten Klassen weitere Klassen definieren, achten Sie darauf, dass
@ -21,7 +21,7 @@ Ziel der Aufgabe ist die Anwendung der Konzepte: Iterator, Kopie vs. Sichtweise,
Elementen vom Typ `Massive` spezifiziert. Verändern Sie diese Datei bitte nicht. Elementen vom Typ `Massive` spezifiziert. Verändern Sie diese Datei bitte nicht.
- [MassiveIterator](../src/MassiveIterator.java) ist ein Interface, das einen Iterator über - [MassiveIterator](../src/MassiveIterator.java) ist ein Interface, das einen Iterator über
Elemente vom Typ `Massive` spezifiziert. Verändern Sie diese Datei bitte nicht. Elemente vom Typ `Massive` spezifiziert. Verändern Sie diese Datei bitte nicht.
- [MassiveSet](../src/MassiveSet.java) ist ein Interface, das iterierbare Mengen mit - [MassiveSet](../src/MassiveSet.java) ist ein Interface, das iterierbare Mengen mit
`Massive`-Elementen spezifiziert. Verändern Sie diese Datei bitte nicht. `Massive`-Elementen spezifiziert. Verändern Sie diese Datei bitte nicht.
- [MassiveForceTreeMap](../src/MassiveForceTreeMap.java) ist das Gerüst für eine Implementierung - [MassiveForceTreeMap](../src/MassiveForceTreeMap.java) ist das Gerüst für eine Implementierung
einer assoziativen Datenstruktur, die ein `Massive`-Objekt mit der auf das Objekt wirkenden Kraft einer assoziativen Datenstruktur, die ein `Massive`-Objekt mit der auf das Objekt wirkenden Kraft
@ -41,25 +41,25 @@ Ihre Aufgaben sind folgende:
**1. Implementieren Sie die Klasse `MassiveForceTreeMap`.** **1. Implementieren Sie die Klasse `MassiveForceTreeMap`.**
Implementieren Sie die Klasse `MassiveForceTreeMap`. `MassiveForceTreeMap` ist wie Implementieren Sie die Klasse `MassiveForceTreeMap`. `MassiveForceTreeMap` ist wie
`BodyForceTreeMap` aufgebaut, mit dem Unterschied, dass der Typ des Schlüssels statt `Body` nun `BodyForceTreeMap` aufgebaut, mit dem Unterschied, dass der Typ des Schlüssels statt `Body` nun
der Typ `Massive` ist. Weiters soll die Klasse Methode `getKeys()` zur Verfügung stellen, der Typ `Massive` ist. Weiters soll die Klasse Methode `getKeys()` zur Verfügung stellen,
die eine `MassiveSet`-Sichtweise auf die Menge der Schlüssel liefert. Änderungen an dem die eine `MassiveSet`-Sichtweise auf die Menge der Schlüssel liefert. Änderungen an dem
zurückgelieferten `MassiveSet`-Objekt wirken sich auf das zugrunde zurückgelieferten `MassiveSet`-Objekt wirken sich auf das zugrunde
liegende `MassiveForceTreeMap`-Objekt aus. Die Methode `toList()` liefert dagegen eine liegende `MassiveForceTreeMap`-Objekt aus. Die Methode `toList()` liefert dagegen eine
unabhängige Liste (Kopie) mit allen Schlüsseln der Map. Für die Implementierung von unabhängige Liste (Kopie) mit allen Schlüsseln der Map. Für die Implementierung von
`MassiveSet` können Sie einen eigenen Klassennamen beginnend mit `My` wählen. Die Definition kann `MassiveSet` können Sie einen eigenen Klassennamen beginnend mit `My` wählen. Die Definition kann
in einer eigenen Datei oder in der Datei `MassiveForceTreeMap.java` erfolgen. in einer eigenen Datei oder in der Datei `MassiveForceTreeMap.java` erfolgen.
**2. Adaptieren Sie die Klasse `HierarchicalSystem`:** **2. Adaptieren Sie die Klasse `HierarchicalSystem`:**
Die Klasse `HierarchicalSystem` soll so geändert werden, dass sie das gegebene Die Klasse `HierarchicalSystem` soll so geändert werden, dass sie das gegebene
Interface `MassiveIterable` implementiert. Die Reihenfolge der vom Iterator gelieferten Interface `MassiveIterable` implementiert. Die Reihenfolge der vom Iterator gelieferten
Elemente ist nicht festgelegt. Sie dürfen für die Implementierung bei Bedarf Ihren Klassen Elemente ist nicht festgelegt. Sie dürfen für die Implementierung bei Bedarf Ihren Klassen
`NamedBodyForcePair` und `HierarchicalSystem` neue, nicht angegebene Methoden hinzufügen. `NamedBodyForcePair` und `HierarchicalSystem` neue, nicht angegebene Methoden hinzufügen.
Die Verwendung von Klassen des Java-Collection-Frameworks (z.B. java.util.Stack) ist erlaubt Die Verwendung von Klassen des Java-Collection-Frameworks (z.B. java.util.Stack) ist erlaubt
(aber nicht notwendig). (aber nicht notwendig).
**3. Implementierung von `Simulation6`:** **3. Implementierung von `Simulation6`:**
Implementieren Sie die Simulationsschleife unter Verwendung eines Objekts vom Typ Implementieren Sie die Simulationsschleife unter Verwendung eines Objekts vom Typ
@ -71,5 +71,5 @@ Ihre Aufgaben sind folgende:
- Implementierung von `MassiveForceTreeMap`: 3 Punkte - Implementierung von `MassiveForceTreeMap`: 3 Punkte
- Implementierung von `MassiveIterable` in `HierarchicalSystem`: 1.5 Punkte - Implementierung von `MassiveIterable` in `HierarchicalSystem`: 1.5 Punkte
- Implementierung von `Simulation6`: 0.5 Punkte - Implementierung von `Simulation6`: 0.5 Punkte
- Gesamt: 5 Punkte - Gesamt: 5 Punkte

View File

@ -1,43 +1,43 @@
# Aufgabenblatt 8 # Aufgabenblatt 8
## Allgemeine Anmerkungen ## Allgemeine Anmerkungen
Ihre Lösung für dieses Aufgabenblatt ist bis Dienstag, 13.6., 11h durch `git commit` und `git push` Ihre Lösung für dieses Aufgabenblatt ist bis Montag, 13.6., 11h durch `git commit` und `git push`
abzugeben. abzugeben.
Wenn Sie zusätzlich zu den gefragten Klassen und Interfaces weitere Klassen oder Wenn Sie zusätzlich zu den gefragten Klassen und Interfaces weitere Klassen oder
Interfaces definieren, achten Sie darauf, dass die Klassennamen mit `My` beginnen, um Konflikte Interfaces definieren, achten Sie darauf, dass die Klassennamen mit `My` beginnen, um Konflikte
mit späteren Aufgabenblättern zu vermeiden. mit späteren Aufgabenblättern zu vermeiden.
Weiters werden die Dateien `StateFileNotFoundException.java`, Weiters werden die Dateien `StateFileNotFoundException.java`,
`StateFileFormatException.java`, `ReadDataUtil.java`, `Simulation8.java`, `Simulation9.java`, `StateFileFormatException.java`, `ReadDataUtil.java`, `Simulation8.java`, `Simulation9.java`,
`Aufgabe8Test.java` und das Verzeichnis `states` mit `txt`-Dateien mitgeliefert. `Aufgabe8Test.java` und das Verzeichnis `states` mit `txt`-Dateien mitgeliefert.
## Ziel ## Ziel
Ziel der Aufgabe ist das Verständnis und die Anwendung der Konzepte: Java-Collections, Eingabe mit Ziel der Aufgabe ist das Verständnis und die Anwendung der Konzepte: Java-Collections, Eingabe mit
Validierung, Exceptions (S. 110-123). Validierung, Exceptions (S. 110-123).
## Beschreibung der gegebenen Dateien ## Beschreibung der gegebenen Dateien
- [states](../states) ist ein Verzeichnis, in dem mehrere Dateien mit der Endung `.txt` - [states](../states) ist ein Verzeichnis, in dem mehrere Dateien mit der Endung `.txt`
mitgeliefert werden. Diese enthalten Daten von je einem Himmelskörper sowie dessen Positionen und mitgeliefert werden. Diese enthalten Daten von je einem Himmelskörper sowie dessen Positionen und
Geschwindigkeitsvektoren für alle Tage der Jahre 2019-2021. Die Angaben sind wie gewohnt in Geschwindigkeitsvektoren für alle Tage der Jahre 2019-2021. Die Angaben sind wie gewohnt in
kartesischen Koordinaten, wobei die Sonne den Urspung des Koordinatensystems bildet und die kartesischen Koordinaten, wobei die Sonne den Ursprung des Koordinatensystems bildet und die
Ekliptik die x-y-Ebene darstellt. Die Daten stammen von [https://ssd.jpl.nasa.gov/horizons.cgi#top](https://ssd.jpl.nasa.gov/horizons.cgi#top). Ekliptik die x-y-Ebene darstellt. Die Daten stammen von [https://ssd.jpl.nasa.gov/horizons.cgi#top](https://ssd.jpl.nasa.gov/horizons.cgi#top).
**ACHTUNG**: Die Werte sind in km bzw. km/sec angegeben! **ACHTUNG**: Die Werte sind in km bzw. km/sec angegeben!
- [StateFileNotFoundException](../src/StateFileNotFoundException.java) enthält die Definition - [StateFileNotFoundException](../src/StateFileNotFoundException.java) enthält die Definition
der Klasse `StateFileNotFoundException`. Diese sollen Sie vervollständigen. der Klasse `StateFileNotFoundException`. Diese sollen Sie vervollständigen.
- [StateFileFormatException](../src/StateFileFormatException.java) enthält die Definition - [StateFileFormatException](../src/StateFileFormatException.java) enthält die Definition
der Klasse `StateFileFormatException`. Diese sollen Sie vervollständigen. der Klasse `StateFileFormatException`. Diese sollen Sie vervollständigen.
- [ReadDataUtil](../src/ReadDataUtil.java) ist eine Klasse mit einer statischen Methode zum - [ReadDataUtil](../src/ReadDataUtil.java) ist eine Klasse mit einer statischen Methode zum
Einlesen von Position- und Bewegungsvektoren von Himmelskörpern aus Dateien. Einlesen von Position- und Bewegungsvektoren von Himmelskörpern aus Dateien.
Diese sollen Sie vervollständigen. Diese sollen Sie vervollständigen.
- [Simulation8](../src/Simulation8.java) ist ein Gerüst für eine ausführbare Klasse. Hier soll - [Simulation8](../src/Simulation8.java) ist ein Gerüst für eine ausführbare Klasse. Hier soll
die Simulation analog zur Klasse `Simulation` implementiert werden (damit Sie Ihre [ursprüngliche die Simulation analog zur Klasse `Simulation` implementiert werden (damit Sie Ihre [ursprüngliche
Datei](../src/Simulation.java) nicht überschreiben müssen). Datei](../src/Simulation.java) nicht überschreiben müssen).
- [Simulation9](../src/Simulation9.java) ist eine leere Datei. Hier soll eine weitere Simulation - [Simulation9](../src/Simulation9.java) ist eine leere Datei. Hier soll eine weitere Simulation
implementiert werden, die so wie `Simulation8` funktioniert, mit dem Unterschied, dass anstelle implementiert werden, die so wie `Simulation8` funktioniert, mit dem Unterschied, dass anstelle
der selbst implementierten Datenstrukturen nur vorgefertigte Klassen aus dem der selbst implementierten Datenstrukturen nur vorgefertigte Klassen aus dem
Java-Collection-Framework benutzt werden sollen. Java-Collection-Framework benutzt werden sollen.
- [Aufgabe8Test](../src/Aufgabe8Test.java) ist eine vorgegebene Klasse, die Sie zum Testen Ihrer - [Aufgabe8Test](../src/Aufgabe8Test.java) ist eine vorgegebene Klasse, die Sie zum Testen Ihrer
Implementierung verwenden sollten. Bei einer fehlerfreien Implementierung sollten bei der Implementierung verwenden sollten. Bei einer fehlerfreien Implementierung sollten bei der
@ -48,44 +48,44 @@ müssen diese Klasse nicht weiter verändern, können aber eigene Testfälle hin
## Aufgaben ## Aufgaben
1. Ändern Sie Ihre Implementierung, sodass ein `MassiveIterator` eine Exception 1. Ändern Sie Ihre Implementierung, sodass ein `MassiveIterator` eine Exception
vom Typ `java.util.NoSuchElementException` wirft, falls `next()` aufgerufen wird, vom Typ `java.util.NoSuchElementException` wirft, falls `next()` aufgerufen wird,
jedoch der Iterator keine weitere Iteration hat (`hasNext()` liefert `false`). jedoch der Iterator keine weitere Iteration hat (`hasNext()` liefert `false`).
2. Ändern Sie den Iterator von der von `getKeys()` zurückgelieferten 2. Ändern Sie den Iterator von der von `getKeys()` zurückgelieferten
Sichtweise auf `MassiveForceTreeMap` so, dass `remove()` überschrieben wird Sichtweise auf `MassiveForceTreeMap` so, dass `remove()` überschrieben wird
([siehe API Dokumentation](https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html#remove--)), ([siehe API Dokumentation](https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html#remove--)),
sodass der Iterator Einträge in Objekten von `MassiveForceTreeMap` löschen kann. Achten Sie sodass der Iterator Einträge in Objekten von `MassiveForceTreeMap` löschen kann. Achten Sie
darauf, dass hier in bestimmten Fällen eine `java.lang.IllegalStateException` geworfen werden darauf, dass hier in bestimmten Fällen eine `java.lang.IllegalStateException` geworfen werden
soll. Der Iterator von `HierarchicalSystem` muss nicht geändert werden. soll. Der Iterator von `HierarchicalSystem` muss nicht geändert werden.
3. Validierung von Eingabedaten: 3. Validierung von Eingabedaten:
- Implementieren Sie in der Klasse `ReadDataUtil.java` die Methode `readConfiguration`. - Implementieren Sie in der Klasse `ReadDataUtil.java` die Methode `readConfiguration`.
Es soll ein gepufferter Stream zum Einlesen genutzt werden (siehe Skriptum Seite 128). Es soll ein gepufferter Stream zum Einlesen genutzt werden (siehe Skriptum Seite 128).
Erstellen Sie zum Testen auch Varianten der txt-Dateien mit Formatfehlern. Erstellen Sie zum Testen auch Varianten der txt-Dateien mit Formatfehlern.
- Fügen Sie der Klasse `NamedBody` bei Bedarf - Fügen Sie der Klasse `NamedBody` bei Bedarf
eine Methode `setState(Vector3 position, Vector3 velocity)` zum Setzen der Position eine Methode `setState(Vector3 position, Vector3 velocity)` zum Setzen der Position
und des Geschwindigkeitsvektors des Himmelskörpers hinzu. und des Geschwindigkeitsvektors des Himmelskörpers hinzu.
- Definieren Sie die beiden angegebenen Exceptionklassen in den entsprechenden - Definieren Sie die beiden angegebenen Exceptionklassen in den entsprechenden
mitgelieferten Dateien. mitgelieferten Dateien.
4. Ausnahmebehandlung: 4. Ausnahmebehandlung:
In der Klasse `Simulation8` sollen nun die Himmelskörper mit Daten aus den gegebenen In der Klasse `Simulation8` sollen nun die Himmelskörper mit Daten aus den gegebenen
txt-Dateien initialisiert werden. Dabei sollen zumindest die Sonne sowie die txt-Dateien initialisiert werden. Dabei sollen zumindest die Sonne sowie die
inneren Planeten inneren Planeten
Merkur, Venus, Erde und Mars vorkommen. Sie können weitere Himmelskörper (siehe txt-Dateien) Merkur, Venus, Erde und Mars vorkommen. Sie können weitere Himmelskörper (siehe txt-Dateien)
hinzufügen. Nutzen Sie die Klasse `MassiveForceTreeMap` und ihre Iteratoren, um die hinzufügen. Nutzen Sie die Klasse `MassiveForceTreeMap` und ihre Iteratoren, um die
Himmelskörper der Simulation zu verwalten. (Kollisionen von Himmelskörpern müssen nicht Himmelskörper der Simulation zu verwalten. (Kollisionen von Himmelskörpern müssen nicht
berücksichtigt werden.) berücksichtigt werden.)
Ändern Sie die Klasse `Simulation8` so, dass sie zwei Kommandozeilenargumente verarbeitet. Ändern Sie die Klasse `Simulation8` so, dass sie zwei Kommandozeilenargumente verarbeitet.
Das erste Argument ist ein String mit der Angabe des Pfades zum Verzeichnis, wo die Das erste Argument ist ein String mit der Angabe des Pfades zum Verzeichnis, wo die
entsprechenden txt-Dateien (z.B. `Venus.txt`,`Mercury.txt`,`Earth.txt`) mit den Konfigurationen entsprechenden txt-Dateien (z.B. `Venus.txt`,`Mercury.txt`,`Earth.txt`) mit den Konfigurationen
der Himmelskörper zu finden sind. Die Dateien haben die Namen der Himmelskörper mit Endung ` der Himmelskörper zu finden sind. Die Dateien haben die Namen der Himmelskörper mit Endung `
.txt`. Für die Sonne gibt es keine txt-Datei (es wird die Position (0,0,0) angenommen). .txt`. Für die Sonne gibt es keine txt-Datei (es wird die Position (0,0,0) angenommen).
Das zweite Argument ist ein String mit einer Datumsangabe der Form YYYY-MMM-DD, also z.B. Das zweite Argument ist ein String mit einer Datumsangabe der Form YYYY-MMM-DD, also z.B.
2020-Dec-04, die den Tag der auszulesenden Position und Bewegungsvektor bestimmt. Die Klasse 2020-Dec-04, die den Tag der auszulesenden Position und Bewegungsvektor bestimmt. Die Klasse
soll beim Auftreten von Problemen bei der Ausführung entsprechende Fehlermeldungen ausgeben und soll beim Auftreten von Problemen bei der Ausführung entsprechende Fehlermeldungen ausgeben und
die Ausführung in bestimmten Fällen beenden. Beispiele für Aufrufe im Kommandozeileninterpreter die Ausführung in bestimmten Fällen beenden. Beispiele für Aufrufe im Kommandozeileninterpreter
mit entsprechenden Fehlermeldungen (Sie können zum Ausführen das Terminal in IntelliJ nutzen mit entsprechenden Fehlermeldungen (Sie können zum Ausführen das Terminal in IntelliJ nutzen
oder die Programmargumente unter `Edit Configurations` angeben): oder die Programmargumente unter `Edit Configurations` angeben):
``` ```
@ -101,52 +101,52 @@ müssen diese Klasse nicht weiter verändern, können aber eigene Testfälle hin
Running simulation without Venus. Running simulation without Venus.
... ...
$ java Simulation8 ../states-altered 2021-May-28 $ java Simulation8 ../states-altered 2021-May-28
Warning: File ../states-altered/Venus.txt does not have required format. Warning: File ../states-altered/Venus.txt does not have required format.
Running simulation without Venus. Running simulation without Venus.
Warning: File ../states-altered/Mars.txt not found. Warning: File ../states-altered/Mars.txt not found.
Running simulation without Mars. Running simulation without Mars.
Running simulation ... Running simulation ...
$ java Simulation8 ../states -17 $ java Simulation8 ../states -17
Error: State has wrong format (requires YYYY-MM-DD), aborting. Error: State has wrong format (requires YYYY-MM-DD), aborting.
$ java Simulation8 blah 2021-May-28 $ java Simulation8 blah 2021-May-28
Warning: File blah/Earth.txt not found. Warning: File blah/Earth.txt not found.
Running simulation without Earth. Running simulation without Earth.
Warning: File blah/Venus.txt not found. Warning: File blah/Venus.txt not found.
Running simulation without Venus. Running simulation without Venus.
... ...
``` ```
5. Kopieren Sie den Inhalt der Datei `Simulation8.java` in die Datei `Simulation9.java` und bauen 5. Kopieren Sie den Inhalt der Datei `Simulation8.java` in die Datei `Simulation9.java` und bauen
Sie `Simulation9` so um, dass anstelle der selbst implementierten Datenstrukturen nur Sie `Simulation9` so um, dass anstelle der selbst implementierten Datenstrukturen nur
vorgefertigte Klassen aus dem Java-Collection-Framework benutzt werden. vorgefertigte Klassen aus dem Java-Collection-Framework benutzt werden.
6. Freiwillige Zusatzaufgabe (ohne Bewertung): 6. Freiwillige Zusatzaufgabe (ohne Bewertung):
Ändern Sie die Klasse `Simulation8` so um, dass ein drittes optionales Kommandozeilenargument Ändern Sie die Klasse `Simulation8` so um, dass ein drittes optionales Kommandozeilenargument
verarbeitet werden kann. Dieses gibt an, wieviele Tage simuliert werden sollen. Beispielsweise verarbeitet werden kann. Dieses gibt an, wie viele Tage simuliert werden sollen. Beispielsweise
kann eine zweite Datumsangabe möglich sein, oder die Anzahl an Tagen. kann eine zweite Datumsangabe möglich sein, oder die Anzahl an Tagen.
Sobald dieser Zeitpunkt in der Simulation erreicht wurde, können die aktuellen Positionen der Sobald dieser Zeitpunkt in der Simulation erreicht wurde, können die aktuellen Positionen der
Himmelskörper mit den in den txt-Dateien angegebenen Positionen verglichen werden (z.B. Himmelskörper mit den in den txt-Dateien angegebenen Positionen verglichen werden (z.B.
durch erneutem Aufruf von `readConfiguration` und `draw`). Wie groß sind die Abweichungen durch erneutem Aufruf von `readConfiguration` und `draw`). Wie groß sind die Abweichungen
der von NASA errechneten Positionen zu den Positionen, die Ihre Simulation liefert? der von NASA errechneten Positionen zu den Positionen, die Ihre Simulation liefert?
### Denkanstöße (ohne Bewertung) ### Denkanstöße (ohne Bewertung)
1. Haben Sie die remove-Methode des Iterators so implementiert, dass der Aufruf keine 1. Haben Sie die remove-Methode des Iterators so implementiert, dass der Aufruf keine
zusätzliche Suche nach dem zu löschenden Eintrag benötigt? zusätzliche Suche nach dem zu löschenden Eintrag benötigt?
2. Wie verhalten sich die von der Methode `toList()` der Klasse `MassiveForceTreeMap` 2. Wie verhalten sich die von der Methode `toList()` der Klasse `MassiveForceTreeMap`
zurückgelieferten Listen, wenn deren enthaltene Himmelskörper durch `setState` verändert werden? zurückgelieferten Listen, wenn deren enthaltene Himmelskörper durch `setState` verändert werden?
Werden dadurch die Himmelskörper der ursprünglichen `MassiveForceTreeMap`-Objekte auch geändert? Werden dadurch die Himmelskörper der ursprünglichen `MassiveForceTreeMap`-Objekte auch geändert?
(Anmerkung: diesbezüglich gibt es im Aufgabenblatt 6 keine Vorgaben). (Anmerkung: diesbezüglich gibt es im Aufgabenblatt 6 keine Vorgaben).
3. Wie verhalten sich Ihre Iteratoren, wenn Objekte geändert werden? 3. Wie verhalten sich Ihre Iteratoren, wenn Objekte geändert werden?
4. Wie kann man durch Einfügen von Zeichen `,` und newlines (`\n`) aus den `txt`-Dateien eine 4. Wie kann man durch Einfügen von Zeichen `,` und newlines (`\n`) aus den `txt`-Dateien eine
"fehlerhafte" Datei machen, die trotzdem von der Methode akzeptiert wird? Kann man solche Probleme "fehlerhafte" Datei machen, die trotzdem von der Methode akzeptiert wird? Kann man solche Probleme
verhindern? verhindern?
#### _Punkteaufteilung_ #### _Punkteaufteilung_
- Änderung von `next()` von `MassiveIterator`: 0.5 Punkte - Änderung von `next()` von `MassiveIterator`: 0.5 Punkte
- Implementierung der Methode `remove()` im Iterator der `MassiveSet`-Sichtweise - Implementierung der Methode `remove()` im Iterator der `MassiveSet`-Sichtweise
von `MassiveForceTreeMap`: 2 Punkte von `MassiveForceTreeMap`: 2 Punkte
- Implementierung der Exceptionklassen und Implementierung von `readConfiguration` - Implementierung der Exceptionklassen und Implementierung von `readConfiguration`
in `ReadDataUtil`: 1.5 Punkte in `ReadDataUtil`: 1.5 Punkte
- Implementierung von `Simulation8` und `Simulation9`: 1 Punkt - Implementierung von `Simulation8` und `Simulation9`: 1 Punkt

View File

@ -1,100 +1,50 @@
import org.junit.jupiter.api.Test;
import java.util.HashSet;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import static org.junit.jupiter.api.Assertions.*;
public class Aufgabe8Test { public class Aufgabe8Test {
public static void main(String[] args) { @Test
public void testEP2() {
/* //TODO: uncomment for testing
MassiveForceTreeMap map = new MassiveForceTreeMap(); MassiveForceTreeMap map = new MassiveForceTreeMap();
NamedBody mars; NamedBody mars;
map.put(new NamedBody("Oumuamua", 8e6, new Vector3(0, 0, 0), new Vector3(0, 0, 0)), map.put(new NamedBody("Oumuamua", 8e6, new Vector3(), new Vector3()), new Vector3());
new Vector3(0, 0, 0)); map.put(new NamedBody("Earth", 5.972E24, new Vector3(), new Vector3()), new Vector3());
map.put(new NamedBody("Earth", 5.972E24, new Vector3(0, 0, 0), new Vector3(0, 0, 0)), map.put(new NamedBody("Moon", 7.349E22, new Vector3(), new Vector3()), new Vector3());
new Vector3(0, 0, 0)); map.put(mars = new NamedBody("Mars", 6.41712E23, new Vector3(), new Vector3()), new Vector3());
map.put(new NamedBody("Moon", 7.349E22, new Vector3(0, 0, 0), new Vector3(0, 0, 0)), map.put(new NamedBody("Deimos", 1.8E20, new Vector3(), new Vector3()), new Vector3());
new Vector3(0, 0, 0)); map.put(new NamedBody("Phobos", 1.08E20, new Vector3(), new Vector3()), new Vector3());
map.put(mars = new NamedBody("Mars", 6.41712E23, new Vector3(0, 0, 0), map.put(new NamedBody("Mercury", 3.301E23, new Vector3(), new Vector3()), new Vector3());
new Vector3(0, 0, 0)), map.put(new NamedBody("Venus", 4.86747E24, new Vector3(), new Vector3()), new Vector3());
new Vector3(0, 0, 0)); map.put(new NamedBody("Vesta", 2.5908E20, new Vector3(), new Vector3()), new Vector3());
map.put(new NamedBody("Deimos", 1.8E20, new Vector3(0, 0, 0), new Vector3(0, 0, 0)), map.put(new NamedBody("Pallas", 2.14E20, new Vector3(), new Vector3()), new Vector3());
new Vector3(0, 0, 0)); map.put(new NamedBody("Hygiea", 8.32E19, new Vector3(), new Vector3()), new Vector3());
map.put(new NamedBody("Phobos", 1.08E20, new Vector3(0, 0, 0), new Vector3(0, 0, 0)), map.put(new NamedBody("Ceres", 9.394E20, new Vector3(), new Vector3()), new Vector3());
new Vector3(0, 0, 0));
map.put(new NamedBody("Mercury", 3.301E23, new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
new Vector3(0, 0, 0));
map.put(new NamedBody("Venus", 4.86747E24, new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
new Vector3(0, 0, 0));
map.put(new NamedBody("Vesta", 2.5908E20, new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
new Vector3(0, 0, 0));
map.put(new NamedBody("Pallas", 2.14E20, new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
new Vector3(0, 0, 0));
map.put(new NamedBody("Hygiea", 8.32E19, new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
new Vector3(0, 0, 0));
map.put(new NamedBody("Ceres", 9.394E20, new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
new Vector3(0, 0, 0));
assertEquals(12, map.size());
System.out.println("Test1:");
MassiveIterator iterator = map.getKeys().iterator(); MassiveIterator iterator = map.getKeys().iterator();
int count = 0; int count;
while(iterator.hasNext()) { for (count = 0; iterator.hasNext(); count++) {
if (iterator.next().equals(mars)) { if (iterator.next().equals(mars)) {
iterator.remove(); iterator.remove();
} }
count++;
} }
testValue(count, 12); assertEquals(12, count);
testValue(map.getKeys().size(), 11); assertEquals(11, map.getKeys().size());
testValue(map.getKeys().contains(mars), false); assertEquals(11, map.size());
assertFalse(map.getKeys().contains(mars));
System.out.println("Test2:"); assertThrows(NoSuchElementException.class, iterator::next);
try {
iterator.next();
// this statement must not be reached
testValue(true, false);
} catch (NoSuchElementException e) {
testValue(true, true);
}
System.out.println("Test3:");
iterator = map.getKeys().iterator(); iterator = map.getKeys().iterator();
while(iterator.hasNext()) { while (iterator.hasNext()) {
iterator.next(); iterator.next();
iterator.remove(); iterator.remove();
} }
testValue(map.getKeys().size(),0); assertEquals(0, map.getKeys().size());
*/ //TODO: uncomment
} }
public static void testComparison(Object first, Object second, boolean expected) {
boolean real = first == second;
if (real == expected) {
System.out.println("Successful comparison");
} else {
System.out.println("Comparison NOT successful! Expected value: " + expected + " / Given value: " + real);
}
}
public static void testValue(Object given, Object expected) {
if (given == expected) {
System.out.println("Successful test");
} else {
System.out.println("Test NOT successful! Expected value: " + expected + " / Given value: " + given);
}
}
public static void testValue(double given, double expected) {
if (given < expected + (expected + 1) / 1e12 && given > expected - (expected + 1) / 1e12) {
System.out.println("Successful test");
} else {
System.out.println("Test NOT successful! Expected value: " + expected + " / Given value: " + given);
}
}
} }

View File

@ -20,6 +20,19 @@ public class Body implements Massive {
this.currentMovement = new Vector3(other.currentMovement); this.currentMovement = new Vector3(other.currentMovement);
} }
public Body(double mass) {
this(mass, new Vector3(), new Vector3());
}
public Body() {
this(0);
}
public void setState(Vector3 position, Vector3 velocity) {
this.massCenter = new Vector3(position);
this.currentMovement = new Vector3(velocity);
}
/** /**
* Returns the distance between the mass centers of this body and the specified body 'b'. * Returns the distance between the mass centers of this body and the specified body 'b'.
*/ */

View File

@ -87,14 +87,14 @@ public class BodyForceTreeMap {
} }
private String toString(Item item) { private String toString(Item item) {
String s = ""; StringBuilder s = new StringBuilder();
if (item == null) { if (item == null) {
return s; return s.toString();
} }
s += this.toString(item.right); s.append(this.toString(item.right));
s += String.format("{%s: %s}\n", item.key, item.value); s.append(String.format("{%s: %s}\n", item.key, item.value));
s += this.toString(item.left); s.append(this.toString(item.left));
return s; return s.toString();
} }
/** /**

View File

@ -1,5 +1,7 @@
import codedraw.CodeDraw; import codedraw.CodeDraw;
import java.util.NoSuchElementException;
/** /**
* A cosmic system that is composed of a central named body (of type 'NamedBodyForcePair') * A cosmic system that is composed of a central named body (of type 'NamedBodyForcePair')
* and an arbitrary number of subsystems (of type 'CosmicSystem') in its orbit. * and an arbitrary number of subsystems (of type 'CosmicSystem') in its orbit.
@ -136,6 +138,7 @@ public class HierarchicalSystem implements CosmicSystem, MassiveIterable {
@Override @Override
public Massive next() { public Massive next() {
if (!hasNext()) throw new NoSuchElementException();
if (cur != null && cur.hasNext()) return cur.next(); if (cur != null && cur.hasNext()) return cur.next();
while (i < all.length) { while (i < all.length) {

View File

@ -1,5 +1,7 @@
import codedraw.CodeDraw; import codedraw.CodeDraw;
import java.util.NoSuchElementException;
/** /**
* A map that associates an object of 'Massive' with a Vector3. The number of key-value pairs * A map that associates an object of 'Massive' with a Vector3. The number of key-value pairs
* is not limited. * is not limited.
@ -86,14 +88,14 @@ public class MassiveForceTreeMap implements MassiveSet {
} }
private String toString(Item item) { private String toString(Item item) {
String s = ""; StringBuilder s = new StringBuilder();
if (item == null) { if (item == null) {
return s; return s.toString();
} }
s += this.toString(item.right); s.append(this.toString(item.right));
s += String.format("{%s: %s}\n", item.key, item.value); s.append(String.format("{%s: %s}\n", item.key, item.value));
s += this.toString(item.left); s.append(this.toString(item.left));
return s; return s.toString();
} }
/** /**
@ -120,25 +122,36 @@ public class MassiveForceTreeMap implements MassiveSet {
@Override @Override
public MassiveIterator iterator() { public MassiveIterator iterator() {
return new MassiveIterator() { return new MassiveIterator() {
private Item last = null;
private Item next = root.getLeftLeaf(); private Item next = root.getLeftLeaf();
@Override @Override
public Massive next() { public Massive next() {
if (next == null) return null; if (!hasNext()) throw new NoSuchElementException();
Massive m = next.key;
last = next;
Item newNext = (next.right != null) ? next.right.getLeftLeaf() : next.parent; Item newNext = (next.right != null) ? next.right.getLeftLeaf() : next.parent;
while (newNext != null && newNext.right == next) { while (newNext != null && newNext.right == next) {
next = newNext; next = newNext;
newNext = newNext.parent; newNext = newNext.parent;
} }
next = newNext; next = newNext;
return m; return last.key;
} }
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return next != null; return next != null;
} }
@Override
public void remove() {
if (last == null) throw new IllegalStateException();
removeItem(last);
last = null;
}
}; };
} }
@ -152,18 +165,7 @@ public class MassiveForceTreeMap implements MassiveSet {
Item item = root; Item item = root;
while (item != null) { while (item != null) {
if (item.key.equals(element)) { if (item.key.equals(element)) {
Item newP = null; removeItem(item);
if (item.left != null) {
newP = item.left.getRightLeaf();
} else if (item.right != null) {
newP = item.right.getLeftLeaf();
}
if (item.parent.left == item) {
item.parent.setLeft(newP);
} else {
item.parent.setRight(newP);
}
size--;
return; return;
} else if (item.key.mass() > element.mass()) { } else if (item.key.mass() > element.mass()) {
item = item.left; item = item.left;
@ -171,6 +173,44 @@ public class MassiveForceTreeMap implements MassiveSet {
item = item.right; item = item.right;
} }
} }
throw new NoSuchElementException();
}
private void removeItem(Item item) {
size--;
Item newP = null;
if (item.left != null) {
newP = item.left.getRightLeaf();
if (newP != item.left) {
newP.parent.setRight(newP.left);
newP.setLeft(item.left);
}
newP.setRight(item.right);
} else if (item.right != null) {
newP = item.right.getLeftLeaf();
if (newP != item.right) {
newP.parent.setLeft(newP.right);
newP.setRight(item.right);
}
newP.setLeft(item.left);
}
if (newP == null) {
root = null;
return;
}
if (item.parent != null) {
if (item.parent.left == item) {
item.parent.setLeft(newP);
} else {
item.parent.setRight(newP);
}
} else {
root = newP;
newP.parent = null;
}
} }
@Override @Override
@ -217,17 +257,13 @@ public class MassiveForceTreeMap implements MassiveSet {
public Item getLeftLeaf() { public Item getLeftLeaf() {
Item cur = this; Item cur = this;
while (cur.left != null) { while (cur.left != null) cur = cur.left;
cur = cur.left;
}
return cur; return cur;
} }
public Item getRightLeaf() { public Item getRightLeaf() {
Item cur = this; Item cur = this;
while (cur.right != null) { while (cur.right != null) cur = cur.right;
cur = cur.right;
}
return cur; return cur;
} }
} }

View File

@ -1,4 +1,5 @@
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException;
/** /**
* A list of massive objects implemented as a linked list. * A list of massive objects implemented as a linked list.
@ -184,6 +185,7 @@ public class MassiveLinkedList implements MassiveIterable {
@Override @Override
public Massive next() { public Massive next() {
if (!hasNext()) throw new NoSuchElementException();
if (!yieldedFirst) { if (!yieldedFirst) {
yieldedFirst = true; yieldedFirst = true;
} else { } else {

View File

@ -1,43 +1,41 @@
import codedraw.CodeDraw;
public class NamedBody implements Massive { public class NamedBody extends Body {
private final String name; private final String name;
private final Body body;
/** /**
* Initializes this with name, mass, current position and movement. * Initializes this with name, mass, current position and movement.
*/ */
public NamedBody(String name, double mass, Vector3 massCenter, Vector3 currentMovement) { public NamedBody(String name, double mass, Vector3 massCenter, Vector3 currentMovement) {
this(name, new Body(mass, massCenter, currentMovement)); super(mass, massCenter, currentMovement);
this.name = name;
}
public NamedBody(String name, double mass) {
super(mass);
this.name = name;
}
public NamedBody(String name) {
super();
this.name = name;
} }
public NamedBody(String name, Body body) { public NamedBody(String name, Body body) {
super(body);
this.name = name; this.name = name;
this.body = body;
} }
public NamedBody(NamedBody other) { public NamedBody(NamedBody other) {
this(other.name, new Body(other.body)); super(other);
this.name = other.name;
} }
/** /**
* Returns the name of the body. * Returns the name of the body.
*/ */
public String getName() { public String getName() {
return name; return this.name;
}
public Body getBody() {
return body;
}
public Vector3 getMassCenter() {
return body.getMassCenter();
}
public double getMass() {
return body.getMass();
} }
/** /**
@ -66,14 +64,4 @@ public class NamedBody implements Massive {
public String toString() { public String toString() {
return this.getName(); return this.getName();
} }
@Override
public void move(Vector3 force) {
body.move(force);
}
@Override
public void draw(CodeDraw cd) {
body.draw(cd);
}
} }

View File

@ -30,7 +30,7 @@ public class NamedBodyForcePair implements CosmicSystem {
} }
public Body getBody() { public Body getBody() {
return body.getBody(); return body;
} }
/** /**
@ -72,13 +72,13 @@ public class NamedBodyForcePair implements CosmicSystem {
@Override @Override
public void addForceTo(CosmicSystem cs) { public void addForceTo(CosmicSystem cs) {
cs.addForceFrom(body.getBody()); cs.addForceFrom(body);
} }
@Override @Override
public BodyLinkedList getBodies() { public BodyLinkedList getBodies() {
BodyLinkedList list = new BodyLinkedList(); BodyLinkedList list = new BodyLinkedList();
list.addFirst(body.getBody()); list.addFirst(body);
return list; return list;
} }

View File

@ -1,27 +1,127 @@
import java.io.*; import java.io.*;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ReadDataUtil { public class ReadDataUtil {
// Reads the position and velocity vector on the specified 'day' from the file with the private static final Pattern LINE_FORMAT = Pattern.compile("^\\d+(\\.\\d+)?, *[A-Za-z \\d:.-]+(, *[-+]?\\d+(\\.\\d+)?([eE][+-]?\\d+)?){6}, *$");
// specified 'path', and sets position and current velocity of 'b' accordingly. If private static final Pattern DATE_COLUMN_FORMAT = Pattern.compile("^A\\.D\\. (?<year>\\d{4})-(?<month>[A-Z][a-z]{2})-(?<day>[0-3]\\d) \\d{2}:\\d{2}:\\d{2}(\\.\\d+)?$");
// successful the method returns 'true'. If the specified 'day' was not found in the file, private static final Pattern DATE_FORMAT_YYYY_MMM_DD = Pattern.compile("^(?<year>\\d{4})-(?<month>[A-Z][a-z]{2})-(?<day>[0-3]\\d)$");
// 'b' is unchanged and the method returns 'false'.
// The file format is validated before reading the state.
// Lines before the line "$$SOE" and after the line "$$EOE" the are ignored. Each line of the
// file between the line "$$SOE" and the line "$$EOE" is required to have the following format:
// JDTDB, TIME, X, Y, Z, VX, VY, VZ
// where JDTDB is interpretable as a 'double' value, TIME is a string and X, Y, Z, VX, VY and
// VZ are interpretable as 'double' values. JDTDB can be ignored. The character ',' must only
// be used as field separator. If the file is not found, an exception of the class
// 'StateFileNotFoundException' is thrown. If it does not comply with the format described
// above, the method throws an exception of the class 'StateFileFormatException'. Both
// exceptions are subtypes of 'IOException'.
// Precondition: b != null, path != null, day != null and has the format YYYY-MM-DD.
public static boolean readConfiguration(NamedBody b, String path, String day)
throws IOException {
// TODO: implement this method. /**
return false; * Reads the position and velocity vector on the specified 'day' from the file with the
* specified 'path', and sets position and current velocity of 'b' accordingly. If
* successful the method returns 'true'. If the specified 'day' was not found in the file,
* 'b' is unchanged and the method returns 'false'.
* The file format is validated before reading the state.
* Lines before the line "$$SOE" and after the line "$$EOE" the are ignored. Each line of the
* file between the line "$$SOE" and the line "$$EOE" is required to have the following format:
* JDTDB, TIME, X, Y, Z, VX, VY, VZ
* where JDTDB is interpretable as a 'double' value, TIME is a string and X, Y, Z, VX, VY and
* VZ are interpretable as 'double' values. JDTDB can be ignored. The character ',' must only
* be used as field separator. If the file is not found, an exception of the class
* 'StateFileNotFoundException' is thrown. If it does not comply with the format described
* above, the method throws an exception of the class 'StateFileFormatException'. Both
* exceptions are subtypes of 'IOException'.
* Precondition: b != null, path != null, day != null and has the format YYYY-MM-DD.
*/
public static boolean readConfiguration(NamedBody b, String path, String day) throws IOException {
State state = State.Pre;
try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(path))) {
Scanner lines = new Scanner(in);
long lineNum = 0;
while (lines.hasNextLine() && state != State.Post) {
lineNum++;
String line = lines.nextLine();
State nextState = state.next(line);
if (state == State.In && nextState == State.In) {
Matcher m = LINE_FORMAT.matcher(line);
if (!m.matches()) {
throw new StateFileFormatException(path, lineNum);
}
String[] rows = line.split(", *");
String date;
try {
date = convertDateColumn(rows[1]);
} catch (IllegalArgumentException e) {
throw new StateFileFormatException(path, lineNum);
}
if (date.equals(day)) {
try {
double x = Double.parseDouble(rows[2]); // [km]
double y = Double.parseDouble(rows[3]); // [km]
double z = Double.parseDouble(rows[4]); // [km]
double vx = Double.parseDouble(rows[5]); // [km/s]
double vy = Double.parseDouble(rows[6]); // [km/s]
double vz = Double.parseDouble(rows[7]); // [km/s]
b.setState(new Vector3(x * 1000, y * 1000, z * 1000), new Vector3(vx * 1000, vy * 1000, vz * 1000));
} catch (NumberFormatException e) {
throw new StateFileFormatException(path, lineNum);
}
return true;
}
}
state = nextState;
}
} catch (IOException e) {
if (e instanceof FileNotFoundException) {
throw new StateFileNotFoundException(path);
} else {
throw e;
}
} }
return false;
} }
private static String convertDateColumn(String column) {
Matcher m = DATE_COLUMN_FORMAT.matcher(column);
if (!m.matches()) {
throw new IllegalArgumentException();
}
return m.group("year") + "-" + convertMonth(m.group("month")) + "-" + m.group("day");
}
public static String convertDate(String date) {
Matcher m = DATE_FORMAT_YYYY_MMM_DD.matcher(date);
if (!m.matches()) {
throw new IllegalArgumentException();
}
return m.group("year") + "-" + convertMonth(m.group("month")) + "-" + m.group("day");
}
private static String convertMonth(String month) {
return switch (month) {
case "Jan" -> "01";
case "Feb" -> "02";
case "Mar" -> "03";
case "Apr" -> "04";
case "May" -> "05";
case "Jun" -> "06";
case "Jul" -> "07";
case "Aug" -> "08";
case "Sep" -> "09";
case "Oct" -> "10";
case "Nov" -> "11";
case "Dec" -> "12";
default -> throw new IllegalArgumentException();
};
}
private enum State {
Pre, In, Post;
public State next(String line) {
switch (this) {
case Pre: if (line.equals("$$SOE")) return In; break;
case In: if (line.equals("$$EOE")) return Post; break;
case Post: break;
}
return this;
}
}
}

View File

@ -1,7 +1,11 @@
import codedraw.CodeDraw; import codedraw.CodeDraw;
// Simulates the solar system. import java.awt.*;
// import java.io.IOException;
/**
* Simulates the solar system.
*/
public class Simulation8 { public class Simulation8 {
// gravitational constant // gravitational constant
@ -17,44 +21,100 @@ public class Simulation8 {
// The main simulation method using instances of other classes. // The main simulation method using instances of other classes.
public static void main(String[] args) { public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Error: wrong number of arguments.");
System.exit(1);
}
String statePath = args[0];
String date;
try {
date = ReadDataUtil.convertDate(args[1]);
} catch (IllegalArgumentException e) {
System.err.println("Error: State has wrong format (requires YYYY-MMM-DD), aborting.");
System.exit(2);
return;
}
// simulation // simulation
CodeDraw cd = new CodeDraw(); CodeDraw cd = new CodeDraw();
// create solar system with 13 bodies // create solar system with 13 bodies
MassiveForceTreeMap map = new MassiveForceTreeMap(); MassiveForceTreeMap forceOnBody = new MassiveForceTreeMap();
map.put(new NamedBody("Oumuamua", 8e6, new Vector3(0, 0, 0), new Vector3(0, 0, 0)), forceOnBody.put(new NamedBody("Oumuamua", 8e6), new Vector3());
new Vector3(0, 0, 0)); forceOnBody.put(new NamedBody("Earth", 5.972E24), new Vector3());
map.put(new NamedBody("Earth", 5.972E24, new Vector3(0, 0, 0), new Vector3(0, 0, 0)), forceOnBody.put(new NamedBody("Moon", 7.349E22), new Vector3());
new Vector3(0, 0, 0)); forceOnBody.put(new NamedBody("Mars", 6.41712E23), new Vector3());
map.put(new NamedBody("Moon", 7.349E22, new Vector3(0, 0, 0), new Vector3(0, 0, 0)), forceOnBody.put(new NamedBody("Deimos", 1.8E20), new Vector3());
new Vector3(0, 0, 0)); forceOnBody.put(new NamedBody("Phobos", 1.08E20), new Vector3());
map.put(new NamedBody("Mars1", 6.41712E23, new Vector3(0, 0, 0), new Vector3(0, 0, 0)), forceOnBody.put(new NamedBody("Mercury", 3.301E23), new Vector3());
new Vector3(0, 0, 0)); forceOnBody.put(new NamedBody("Venus", 4.86747E24), new Vector3());
map.put(new NamedBody("Deimos", 1.8E20, new Vector3(0, 0, 0), new Vector3(0, 0, 0)), forceOnBody.put(new NamedBody("Vesta", 2.5908E20), new Vector3());
new Vector3(0, 0, 0)); forceOnBody.put(new NamedBody("Pallas", 2.14E20), new Vector3());
map.put(new NamedBody("Phobos", 1.08E20, new Vector3(0, 0, 0), new Vector3(0, 0, 0)), forceOnBody.put(new NamedBody("Hygiea", 8.32E19), new Vector3());
new Vector3(0, 0, 0)); forceOnBody.put(new NamedBody("Ceres", 9.394E20), new Vector3());
map.put(new NamedBody("Mercury", 3.301E23, new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
new Vector3(0, 0, 0));
map.put(new NamedBody("Venus", 4.86747E24, new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
new Vector3(0, 0, 0));
map.put(new NamedBody("Vesta", 2.5908E20, new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
new Vector3(0, 0, 0));
map.put(new NamedBody("Pallas", 2.14E20, new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
new Vector3(0, 0, 0));
map.put(new NamedBody("Hygiea", 8.32E19, new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
new Vector3(0, 0, 0));
map.put(new NamedBody("Ceres1", 9.394E20, new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
new Vector3(0, 0, 0));
MassiveIterator iter = forceOnBody.getKeys().iterator();
while (iter.hasNext()) {
Massive a = iter.next();
if (a instanceof NamedBody b) {
boolean remove = false;
//TODO: implementation of this method according to 'Aufgabenblatt8.md'. try {
boolean found = ReadDataUtil.readConfiguration(b, statePath + "/" + b.getName() + ".txt", date);
if (!found) {
System.err.println("Warning: State not available for " + b.getName() + ".");
remove = true;
}
} catch (IOException e) {
if (e instanceof StateFileNotFoundException notFound) {
System.err.println("Warning: " + notFound.getMessage());
} else if (e instanceof StateFileFormatException format) {
System.err.println("Warning: " + format.getMessage());
} else {
System.err.println("Error: " + e.getMessage());
System.exit(3);
}
remove = true;
}
if (remove) {
System.err.println("Running simulation without " + b.getName());
iter.remove();
}
}
}
// add sun after states have been read from files. // add sun after states have been read from files.
map.put(new NamedBody("Sun", 1.989E30, new Vector3(0, 0, 0), new Vector3(0, 0, 0)), forceOnBody.put(new NamedBody("Sun", 1.989E30), new Vector3());
new Vector3(0, 0, 0));
System.out.println("Starting simulation");
long seconds = 0;
while (true) {
seconds++;
for (Massive b1 : forceOnBody.getKeys()) {
Vector3 force = new Vector3();
for (Massive b2 : forceOnBody.getKeys()) {
if (b1 != b2) {
force = force.plus(b1.gravitationalForce(b2));
}
}
forceOnBody.put(b1, force);
}
for (Massive body : forceOnBody.getKeys()) {
body.move(forceOnBody.get(body));
}
if ((seconds % 3600) == 0) {
cd.clear(Color.BLACK);
for (Massive body : forceOnBody.getKeys()) {
body.draw(cd);
}
cd.show();
}
}
} }
} }

View File

@ -1,7 +1,122 @@
// Simulates the solar system. import codedraw.CodeDraw;
//
import java.awt.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
/**
* Simulates the solar system.
*/
public class Simulation9 { public class Simulation9 {
// TODO: Implement the simulation using the Java-Collections framework. // gravitational constant
public static final double G = 6.6743e-11;
// one astronomical unit (AU) is the average distance of earth to the sun.
public static final double AU = 150e9; // meters
// set some system parameters
public static final double SECTION_SIZE = 10 * AU; // the size of the square region in space
// all quantities are based on units of kilogram respectively second and meter.
// The main simulation method using instances of other classes.
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Error: wrong number of arguments.");
System.exit(1);
}
String statePath = args[0];
String date;
try {
date = ReadDataUtil.convertDate(args[1]);
} catch (IllegalArgumentException e) {
System.err.println("Error: State has wrong format (requires YYYY-MMM-DD), aborting.");
System.exit(2);
return;
}
// simulation
CodeDraw cd = new CodeDraw();
// create solar system with 13 bodies
HashMap<Massive, Vector3> forceOnBody = new HashMap<>();
forceOnBody.put(new NamedBody("Oumuamua", 8e6), new Vector3());
forceOnBody.put(new NamedBody("Earth", 5.972E24), new Vector3());
forceOnBody.put(new NamedBody("Moon", 7.349E22), new Vector3());
forceOnBody.put(new NamedBody("Mars", 6.41712E23), new Vector3());
forceOnBody.put(new NamedBody("Deimos", 1.8E20), new Vector3());
forceOnBody.put(new NamedBody("Phobos", 1.08E20), new Vector3());
forceOnBody.put(new NamedBody("Mercury", 3.301E23), new Vector3());
forceOnBody.put(new NamedBody("Venus", 4.86747E24), new Vector3());
forceOnBody.put(new NamedBody("Vesta", 2.5908E20), new Vector3());
forceOnBody.put(new NamedBody("Pallas", 2.14E20), new Vector3());
forceOnBody.put(new NamedBody("Hygiea", 8.32E19), new Vector3());
forceOnBody.put(new NamedBody("Ceres", 9.394E20), new Vector3());
Iterator<Massive> iter = forceOnBody.keySet().iterator();
while (iter.hasNext()) {
Massive a = iter.next();
if (a instanceof NamedBody b) {
boolean remove = false;
try {
boolean found = ReadDataUtil.readConfiguration(b, statePath + "/" + b.getName() + ".txt", date);
if (!found) {
System.err.println("Warning: State not available for " + b.getName() + ".");
remove = true;
}
} catch (IOException e) {
if (e instanceof StateFileNotFoundException notFound) {
System.err.println("Warning: " + notFound.getMessage());
} else if (e instanceof StateFileFormatException format) {
System.err.println("Warning: " + format.getMessage());
} else {
System.err.println("Error: " + e.getMessage());
System.exit(3);
}
remove = true;
}
if (remove) {
System.err.println("Running simulation without " + b.getName());
iter.remove();
}
}
}
// add sun after states have been read from files.
forceOnBody.put(new NamedBody("Sun", 1.989E30), new Vector3());
System.out.println("Starting simulation");
long seconds = 0;
while (true) {
seconds++;
for (Massive b1 : forceOnBody.keySet()) {
Vector3 force = new Vector3();
for (Massive b2 : forceOnBody.keySet()) {
if (b1 != b2) {
force = force.plus(b1.gravitationalForce(b2));
}
}
forceOnBody.put(b1, force);
}
for (Massive body : forceOnBody.keySet()) {
body.move(forceOnBody.get(body));
}
if ((seconds % 3600) == 0) {
cd.clear(Color.BLACK);
for (Massive body : forceOnBody.keySet()) {
body.draw(cd);
}
cd.show();
}
}
}
} }

View File

@ -1,7 +1,20 @@
import java.io.IOException; import java.io.IOException;
public class StateFileFormatException extends IOException { public class StateFileFormatException extends IOException {
private final String fileName;
private final long lineNum;
// TODO: implement class public StateFileFormatException(String fileName, long lineNum) {
super("File " + fileName + " has illegal format (line " + lineNum + ")");
this.fileName = fileName;
this.lineNum = lineNum;
}
public String getFileName() {
return this.fileName;
}
public long getLineNum() {
return this.lineNum;
}
} }

View File

@ -1,7 +1,14 @@
import java.io.IOException; import java.io.IOException;
public class StateFileNotFoundException extends IOException { public class StateFileNotFoundException extends IOException {
private final String fileName;
// TODO: implement class public StateFileNotFoundException(String fileName) {
super("File " + fileName + " not found.");
this.fileName = fileName;
}
public String getFileName() {
return this.fileName;
}
} }