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

@ -1,7 +1,7 @@
# 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
@ -20,7 +20,7 @@ Validierung, Exceptions (S. 110-123).
- [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!
@ -122,7 +122,7 @@ müssen diese Klasse nicht weiter verändern, können aber eigene Testfälle hin
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.

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;
}
} }