Finish AB 2
This commit is contained in:
@ -53,6 +53,10 @@ public class Body {
|
||||
return SpaceDraw.massToRadius(mass);
|
||||
}
|
||||
|
||||
public double mass() {
|
||||
return mass;
|
||||
}
|
||||
|
||||
// Returns a new body that is formed by the collision of this body and 'b'. The impulse
|
||||
// of the returned body is the sum of the impulses of 'this' and 'b'.
|
||||
public Body merge(Body b) {
|
||||
|
@ -3,21 +3,55 @@
|
||||
//
|
||||
public class BodyForceMap {
|
||||
|
||||
//TODO: declare variables.
|
||||
private int size = 0;
|
||||
private int capacity;
|
||||
private Body[] keys;
|
||||
private Vector3[] values;
|
||||
|
||||
public BodyForceMap() {
|
||||
this(4);
|
||||
}
|
||||
|
||||
// Initializes this map with an initial capacity.
|
||||
// Precondition: initialCapacity > 0.
|
||||
public BodyForceMap(int initialCapacity) {
|
||||
|
||||
//TODO: define constructor.
|
||||
this.capacity = initialCapacity;
|
||||
this.keys = new Body[this.capacity];
|
||||
this.values = new Vector3[this.capacity];
|
||||
}
|
||||
|
||||
// Adds a new key-value association to this map. If the key already exists in this map,
|
||||
// the value is replaced and the old value is returned. Otherwise 'null' is returned.
|
||||
// Precondition: key != null.
|
||||
public Vector3 put(Body key, Vector3 force) {
|
||||
if (size == capacity) {
|
||||
doubleCapacity();
|
||||
}
|
||||
|
||||
//TODO: implement method.
|
||||
int left = 0;
|
||||
int right = size - 1;
|
||||
while (left <= right) {
|
||||
int middle = left + (right - left) / 2;
|
||||
if (keys[middle] == key) {
|
||||
Vector3 v = values[middle];
|
||||
values[middle] = force;
|
||||
return v;
|
||||
} else if (keys[middle].mass() < key.mass()) {
|
||||
right = middle - 1;
|
||||
} else {
|
||||
left = middle + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int insert = right + 1;
|
||||
|
||||
for (int i = size; i > insert; i--) {
|
||||
keys[i] = keys[i - 1];
|
||||
values[i] = values[i - 1];
|
||||
}
|
||||
size++;
|
||||
keys[insert] = key;
|
||||
values[insert] = force;
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -25,8 +59,52 @@ public class BodyForceMap {
|
||||
// associated with the specified body. Returns 'null' if the key is not contained in this map.
|
||||
// Precondition: key != null.
|
||||
public Vector3 get(Body key) {
|
||||
int left = 0;
|
||||
int right = size - 1;
|
||||
|
||||
while (left <= right) {
|
||||
int middle = left + ((right - left) / 2);
|
||||
int middleLeft = left + (middle - left) / 2;
|
||||
int middleRight = middle + (right - middle) / 2;
|
||||
|
||||
if (keys[middle] == key) {
|
||||
return values[middle];
|
||||
}
|
||||
|
||||
if (keys[middleLeft].mass() == keys[middle].mass()) {
|
||||
for (int i = middleLeft; i < middle; i++) {
|
||||
if (keys[i] == key)
|
||||
return values[i];
|
||||
}
|
||||
}
|
||||
if (keys[middle].mass() == keys[middleRight].mass()) {
|
||||
for (int i = middle; i < middleRight; i++) {
|
||||
if (keys[i] == key)
|
||||
return values[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (keys[middle].mass() < key.mass()) {
|
||||
right = middle - 1;
|
||||
} else {
|
||||
left = middle + 1;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: implement method.
|
||||
return null;
|
||||
}
|
||||
|
||||
private void doubleCapacity() {
|
||||
capacity *= 2;
|
||||
Body[] tmpKeys = new Body[capacity];
|
||||
Vector3[] tmpValues = new Vector3[capacity];
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
tmpKeys[i] = keys[i];
|
||||
tmpValues[i] = values[i];
|
||||
}
|
||||
|
||||
keys = tmpKeys;
|
||||
values = tmpValues;
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,20 @@
|
||||
//
|
||||
public class BodyQueue {
|
||||
|
||||
//TODO: declare variables.
|
||||
private int capacity;
|
||||
private int head = 0;
|
||||
private int tail = 0;
|
||||
private Body[] queue;
|
||||
|
||||
public BodyQueue() {
|
||||
this(4);
|
||||
}
|
||||
|
||||
// Initializes this queue with an initial capacity.
|
||||
// Precondition: initialCapacity > 0.
|
||||
public BodyQueue(int initialCapacity) {
|
||||
|
||||
//TODO: define constructor.
|
||||
this.capacity = initialCapacity;
|
||||
this.queue = new Body[this.capacity];
|
||||
}
|
||||
|
||||
// Initializes this queue as an independent copy of the specified queue.
|
||||
@ -19,28 +26,50 @@ public class BodyQueue {
|
||||
// and vice versa.
|
||||
// Precondition: q != null.
|
||||
public BodyQueue(BodyQueue q) {
|
||||
|
||||
//TODO: define constructor.
|
||||
this.capacity = q.capacity;
|
||||
this.head = q.size();
|
||||
this.tail = 0;
|
||||
this.queue = new Body[this.capacity];
|
||||
for (int i = 0; i < q.size(); i++) {
|
||||
this.queue[i] = q.queue[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Adds the specified body 'b' to this queue.
|
||||
public void add(Body b) {
|
||||
|
||||
//TODO: implement method.
|
||||
queue[head] = b;
|
||||
head = (head + 1) % capacity;
|
||||
if (head == tail) {
|
||||
doubleCapacity();
|
||||
head = capacity / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieves and removes the head of this queue, or returns 'null'
|
||||
// if this queue is empty.
|
||||
public Body poll() {
|
||||
|
||||
//TODO: implement method.
|
||||
if (tail == head) {
|
||||
return null;
|
||||
}
|
||||
Body b = queue[tail];
|
||||
queue[tail] = null;
|
||||
tail = (tail + 1) % capacity;
|
||||
return b;
|
||||
}
|
||||
|
||||
// Returns the number of bodies in this queue.
|
||||
public int size() {
|
||||
return (head - tail + capacity) % capacity;
|
||||
}
|
||||
|
||||
//TODO: implement method.
|
||||
return -1;
|
||||
private void doubleCapacity() {
|
||||
Body[] tmp = new Body[capacity * 2];
|
||||
for (int i = head, j = 0; i < tail + capacity; i++, j++) {
|
||||
tmp[j] = queue[i % capacity];
|
||||
}
|
||||
head = capacity;
|
||||
tail = 0;
|
||||
capacity *= 2;
|
||||
queue = tmp;
|
||||
}
|
||||
}
|
||||
|
@ -41,14 +41,14 @@ public class Simulation {
|
||||
public static void main(String[] args) {
|
||||
// simulation
|
||||
CodeDraw cd = new CodeDraw();
|
||||
Body[] bodies = new Body[NUMBER_OF_BODIES];
|
||||
Vector3[] forceOnBody = new Vector3[bodies.length];
|
||||
BodyQueue bodies = new BodyQueue();
|
||||
BodyForceMap forceOnBody = new BodyForceMap();
|
||||
|
||||
Random random = new Random(2022);
|
||||
|
||||
for (int i = 0; i < bodies.length; i++) {
|
||||
bodies[i] = new Body(
|
||||
Math.abs(random.nextGaussian()) * OVERALL_SYSTEM_MASS / bodies.length, // kg
|
||||
for (int i = 0; i < NUMBER_OF_BODIES; i++) {
|
||||
bodies.add(new Body(
|
||||
Math.abs(random.nextGaussian()) * OVERALL_SYSTEM_MASS / NUMBER_OF_BODIES, // kg
|
||||
new Vector3(
|
||||
0.2 * random.nextGaussian() * AU,
|
||||
0.2 * random.nextGaussian() * AU,
|
||||
@ -59,15 +59,21 @@ public class Simulation {
|
||||
0 + random.nextGaussian() * 5e3,
|
||||
0 + random.nextGaussian() * 5e3
|
||||
)
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
double seconds = 0;
|
||||
|
||||
// simulation loop
|
||||
while (true) {
|
||||
BodyQueue newBodies = new BodyQueue(bodies);
|
||||
Body[] tmp = new Body[bodies.size()];
|
||||
for (int i = 0; bodies.size() > 0; i++) {
|
||||
tmp[i] = bodies.poll();
|
||||
}
|
||||
seconds++; // each iteration computes the movement of the celestial bodies within one second.
|
||||
|
||||
/*
|
||||
// merge bodies that have collided
|
||||
for (int i = 0; i < bodies.length; i++) {
|
||||
for (int j = i + 1; j < bodies.length; j++) {
|
||||
@ -86,22 +92,23 @@ public class Simulation {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// for each body (with index i): compute the total force exerted on it.
|
||||
for (int i = 0; i < bodies.length; i++) {
|
||||
forceOnBody[i] = new Vector3(); // begin with zero
|
||||
for (int j = 0; j < bodies.length; j++) {
|
||||
if (i != j) {
|
||||
Vector3 forceToAdd = bodies[i].gravitationalForce(bodies[j]);
|
||||
forceOnBody[i] = forceOnBody[i].plus(forceToAdd);
|
||||
for (Body b1 : tmp) {
|
||||
Vector3 force = new Vector3(); // begin with zero
|
||||
for (Body b2 : tmp) {
|
||||
if (b1 != b2) {
|
||||
force = force.plus(b1.gravitationalForce(b2));
|
||||
}
|
||||
}
|
||||
forceOnBody.put(b1, force);
|
||||
}
|
||||
// now forceOnBody[i] holds the force vector exerted on body with index i.
|
||||
|
||||
// for each body (with index i): move it according to the total force exerted on it.
|
||||
for (int i = 0; i < bodies.length; i++) {
|
||||
bodies[i].move(forceOnBody[i]);
|
||||
for (Body body : tmp) {
|
||||
body.move(forceOnBody.get(body));
|
||||
}
|
||||
|
||||
// show all movements in the canvas only every hour (to speed up the simulation)
|
||||
@ -110,7 +117,7 @@ public class Simulation {
|
||||
cd.clear(Color.BLACK);
|
||||
|
||||
// draw new positions
|
||||
for (Body body : bodies) {
|
||||
for (Body body : tmp) {
|
||||
body.draw(cd);
|
||||
}
|
||||
|
||||
@ -118,6 +125,7 @@ public class Simulation {
|
||||
cd.show();
|
||||
}
|
||||
|
||||
bodies = newBodies;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user