Files
EP2/src/HierarchicalSystem.java

180 lines
4.8 KiB
Java

import codedraw.CodeDraw;
/**
* 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.
* This class implements 'CosmicSystem'.
*/
public class HierarchicalSystem implements CosmicSystem, MassiveIterable {
private final NamedBodyForcePair central;
private CosmicSystem[] orbit;
private CosmicSystem[] all;
/**
* Initializes this system with a name and a central body.
*/
public HierarchicalSystem(NamedBodyForcePair central, CosmicSystem... inOrbit) {
this.central = central;
this.orbit = inOrbit;
this.all = new CosmicSystem[this.orbit.length + 1];
this.all[0] = central;
System.arraycopy(this.orbit, 0, this.all, 1, this.orbit.length);
}
@Override
public Vector3 getMassCenter() {
double mass = this.getMass();
Vector3 massCenter = new Vector3();
for (CosmicSystem sys : all) {
massCenter.add(sys.getMassCenter().times(sys.getMass() / mass));
}
return massCenter;
}
@Override
public double getMass() {
double mass = 0;
for (CosmicSystem sys : all) {
mass += sys.getMass();
}
return mass;
}
@Override
public int numberOfBodies() {
int num = 0;
for (CosmicSystem sys : all) {
num += sys.numberOfBodies();
}
return num;
}
@Override
public double distanceTo(CosmicSystem cs) {
return this.getMassCenter().distanceTo(cs.getMassCenter());
}
@Override
public void addForceFrom(Body b) {
for (CosmicSystem sys : all) {
sys.addForceFrom(b);
}
}
@Override
public void addForceTo(CosmicSystem cs) {
for (CosmicSystem sys : all) {
sys.addForceTo(cs);
}
}
@Override
public BodyLinkedList getBodies() {
BodyLinkedList list = new BodyLinkedList();
for (CosmicSystem sys : all) {
for (Body b : sys.getBodies()) {
list.addFirst(b);
}
}
return list;
}
@Override
public void update() {
for (CosmicSystem sys : all) {
sys.update();
}
}
@Override
public void draw(CodeDraw cd) {
for (CosmicSystem sys : all) {
sys.draw(cd);
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(central.getName());
sb.append(" {");
boolean first = true;
for (CosmicSystem sys : orbit) {
if (!first) sb.append(", ");
sb.append(sys.toString());
first = false;
}
sb.append("}");
return sb.toString();
}
/**
* Puts the system 'cs' at the first place in the orbit of this system.
* Precondition: cs != null
*/
public boolean putFirst(CosmicSystem cs) {
CosmicSystem[] old = orbit;
orbit = new CosmicSystem[old.length + 1];
all = new CosmicSystem[old.length + 2];
orbit[0] = cs;
System.arraycopy(old, 0, orbit, 1, old.length);
all[0] = central;
System.arraycopy(orbit, 0, all, 1, orbit.length);
return true;
}
@Override
public MassiveIterator iterator() {
return new MassiveIterator() {
private int i = 0;
private MassiveIterator cur = null;
@Override
public Massive next() {
if (cur != null && cur.hasNext()) return cur.next();
for (; i < all.length; i++) {
CosmicSystem sys = all[i];
if (sys instanceof NamedBodyForcePair m) {
i++;
return m.getBody();
} else if (sys instanceof HierarchicalSystem hs) {
cur = hs.iterator();
if (cur.hasNext()) {
i++;
return cur.next();
}
}
}
return null;
}
@Override
public boolean hasNext() {
if (cur != null && cur.hasNext()) return true;
for (; i < all.length; i++) {
CosmicSystem sys = all[i];
if (sys instanceof NamedBodyForcePair) {
return true;
} else if (sys instanceof HierarchicalSystem hs) {
cur = hs.iterator();
if (cur.hasNext()) {
i++;
return true;
}
}
}
return false;
}
};
}
}