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