180 lines
4.8 KiB
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;
|
|
}
|
|
};
|
|
}
|
|
}
|