Compare commits
3 Commits
4f8f9e0c37
...
Endabgabe
Author | SHA1 | Date | |
---|---|---|---|
0259be8338
|
|||
bf9a6c6d43 | |||
1ab9c3650e
|
@@ -4,7 +4,7 @@ import codedraw.CodeDraw;
|
|||||||
* This class represents celestial bodies like stars, planets, asteroids, etc...
|
* This class represents celestial bodies like stars, planets, asteroids, etc...
|
||||||
*/
|
*/
|
||||||
public class Body {
|
public class Body {
|
||||||
private final double mass;
|
private double mass;
|
||||||
private Vector massCenter; // position of the mass center.
|
private Vector massCenter; // position of the mass center.
|
||||||
private Vector currentMovement;
|
private Vector currentMovement;
|
||||||
|
|
||||||
@@ -83,6 +83,12 @@ public class Body {
|
|||||||
return massCenter;
|
return massCenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void update(Body b) {
|
||||||
|
double combinedMass = this.mass + b.mass;
|
||||||
|
this.massCenter = this.massCenter.times(this.mass / combinedMass).plus(b.massCenter.times(b.mass / combinedMass));
|
||||||
|
this.mass = combinedMass;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean collidesWith(Body body) {
|
public boolean collidesWith(Body body) {
|
||||||
return this.distanceTo(body) < this.radius() + body.radius();
|
return this.distanceTo(body) < this.radius() + body.radius();
|
||||||
}
|
}
|
||||||
|
@@ -38,7 +38,6 @@ public class Octree {
|
|||||||
|
|
||||||
public void applyForces(Body[] bodies, double t) {
|
public void applyForces(Body[] bodies, double t) {
|
||||||
if (root == null) return;
|
if (root == null) return;
|
||||||
root.preCalc();
|
|
||||||
Vector[] forces = new Vector[bodies.length];
|
Vector[] forces = new Vector[bodies.length];
|
||||||
for (int i = 0; i < bodies.length; i++) {
|
for (int i = 0; i < bodies.length; i++) {
|
||||||
forces[i] = root.getForcesOnBody(bodies[i], t);
|
forces[i] = root.getForcesOnBody(bodies[i], t);
|
||||||
@@ -55,8 +54,8 @@ public class Octree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class OctreeItem {
|
abstract class OctreeItem {
|
||||||
protected Vector center;
|
protected final Vector center;
|
||||||
protected double size;
|
protected final double size;
|
||||||
|
|
||||||
protected Body pseudoBody;
|
protected Body pseudoBody;
|
||||||
|
|
||||||
@@ -67,8 +66,6 @@ abstract class OctreeItem {
|
|||||||
|
|
||||||
abstract protected OctreeNode add(Body body);
|
abstract protected OctreeNode add(Body body);
|
||||||
|
|
||||||
abstract protected void preCalc();
|
|
||||||
|
|
||||||
abstract protected Vector getForcesOnBody(Body body, double t);
|
abstract protected Vector getForcesOnBody(Body body, double t);
|
||||||
|
|
||||||
abstract protected void draw(CodeDraw cd);
|
abstract protected void draw(CodeDraw cd);
|
||||||
@@ -76,16 +73,25 @@ abstract class OctreeItem {
|
|||||||
|
|
||||||
class OctreeNode extends OctreeItem {
|
class OctreeNode extends OctreeItem {
|
||||||
private final OctreeItem[] children;
|
private final OctreeItem[] children;
|
||||||
|
private final Vector p1;
|
||||||
|
private final Vector p2 ;
|
||||||
|
|
||||||
protected OctreeNode(Vector center, double size) {
|
protected OctreeNode(Vector center, double size) {
|
||||||
super(center, size);
|
super(center, size);
|
||||||
children = new OctreeItem[8];
|
children = new OctreeItem[8];
|
||||||
|
p1 = center.plus(new Vector(size / 2));
|
||||||
|
p2 = center.minus(new Vector(size / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected OctreeNode add(Body body) {
|
protected OctreeNode add(Body body) {
|
||||||
int num = getOctantNum(body.massCenter());
|
int num = getOctantNum(body.massCenter());
|
||||||
if (num < 0) return this;
|
if (num < 0) return this;
|
||||||
|
if (this.pseudoBody == null) {
|
||||||
|
this.pseudoBody = new Body(body);
|
||||||
|
} else {
|
||||||
|
this.pseudoBody.update(body);
|
||||||
|
}
|
||||||
OctreeItem oct = children[num];
|
OctreeItem oct = children[num];
|
||||||
if (oct == null) {
|
if (oct == null) {
|
||||||
children[num] = new OctreeLeaf(getOctantCenter(num), size / 2, body);
|
children[num] = new OctreeLeaf(getOctantCenter(num), size / 2, body);
|
||||||
@@ -95,22 +101,6 @@ class OctreeNode extends OctreeItem {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void preCalc() {
|
|
||||||
double mass = 0;
|
|
||||||
for (OctreeItem oct : children) {
|
|
||||||
if (oct == null) continue;
|
|
||||||
oct.preCalc();
|
|
||||||
mass += oct.pseudoBody.mass();
|
|
||||||
}
|
|
||||||
Vector massCenter = new Vector();
|
|
||||||
for (OctreeItem oct : children) {
|
|
||||||
if (oct == null) continue;
|
|
||||||
massCenter = massCenter.plus(oct.pseudoBody.massCenter().times(oct.pseudoBody.mass() / mass));
|
|
||||||
}
|
|
||||||
this.pseudoBody = new Body(mass, massCenter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Vector getForcesOnBody(Body body, double t) {
|
protected Vector getForcesOnBody(Body body, double t) {
|
||||||
double r = pseudoBody.massCenter().distanceTo(body.massCenter());
|
double r = pseudoBody.massCenter().distanceTo(body.massCenter());
|
||||||
@@ -122,7 +112,7 @@ class OctreeNode extends OctreeItem {
|
|||||||
Vector force = new Vector();
|
Vector force = new Vector();
|
||||||
for (OctreeItem child : children) {
|
for (OctreeItem child : children) {
|
||||||
if (child == null) continue;
|
if (child == null) continue;
|
||||||
force = force.plus(child.getForcesOnBody(body, t));
|
force.add(child.getForcesOnBody(body, t));
|
||||||
}
|
}
|
||||||
return force;
|
return force;
|
||||||
}
|
}
|
||||||
@@ -133,10 +123,12 @@ class OctreeNode extends OctreeItem {
|
|||||||
if (child == null) continue;
|
if (child == null) continue;
|
||||||
child.draw(cd);
|
child.draw(cd);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
Vector p1 = center.minus(new Vector(size / 2));
|
Vector p1 = center.minus(new Vector(size / 2));
|
||||||
Vector p2 = new Vector(size).minus(new Vector(Simulation.SECTION_SIZE / 2));
|
Vector p2 = new Vector(size).minus(new Vector(Simulation.SECTION_SIZE / 2));
|
||||||
cd.setColor(Color.CYAN);
|
cd.setColor(Color.CYAN);
|
||||||
cd.drawRectangle(p1.getScreenX(cd), p1.getScreenY(cd), p2.getScreenX(cd), p2.getScreenY(cd));
|
cd.drawRectangle(p1.getScreenX(cd), p1.getScreenY(cd), p2.getScreenX(cd), p2.getScreenY(cd));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getOctantNum(Vector bodyPos) {
|
private int getOctantNum(Vector bodyPos) {
|
||||||
@@ -146,8 +138,6 @@ class OctreeNode extends OctreeItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInOctant(Vector pos) {
|
private boolean isInOctant(Vector pos) {
|
||||||
Vector p1 = center.plus(new Vector(size / 2));
|
|
||||||
Vector p2 = center.minus(new Vector(size / 2));
|
|
||||||
return pos.getX() <= p1.getX() && pos.getY() <= p1.getY() && pos.getZ() <= p1.getZ() &&
|
return pos.getX() <= p1.getX() && pos.getY() <= p1.getY() && pos.getZ() <= p1.getZ() &&
|
||||||
pos.getX() >= p2.getX() && pos.getY() >= p2.getY() && pos.getZ() >= p2.getZ();
|
pos.getX() >= p2.getX() && pos.getY() >= p2.getY() && pos.getZ() >= p2.getZ();
|
||||||
}
|
}
|
||||||
@@ -167,6 +157,7 @@ class OctreeLeaf extends OctreeItem {
|
|||||||
public OctreeLeaf(Vector center, double size, Body body) {
|
public OctreeLeaf(Vector center, double size, Body body) {
|
||||||
super(center, size);
|
super(center, size);
|
||||||
this.body = body;
|
this.body = body;
|
||||||
|
this.pseudoBody = new Body(this.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -174,11 +165,6 @@ class OctreeLeaf extends OctreeItem {
|
|||||||
return new OctreeNode(this.center, this.size).add(this.body).add(body);
|
return new OctreeNode(this.center, this.size).add(this.body).add(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void preCalc() {
|
|
||||||
this.pseudoBody = new Body(this.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Vector getForcesOnBody(Body body, double t) {
|
protected Vector getForcesOnBody(Body body, double t) {
|
||||||
return body.gravitationalForce(pseudoBody);
|
return body.gravitationalForce(pseudoBody);
|
||||||
|
@@ -22,8 +22,8 @@ public class Simulation {
|
|||||||
|
|
||||||
// set some system parameters
|
// set some system parameters
|
||||||
public static final double SECTION_SIZE = 2 * AU; // the size of the square region in space
|
public static final double SECTION_SIZE = 2 * AU; // the size of the square region in space
|
||||||
public static final int NUMBER_OF_BODIES = 22;
|
public static final int NUMBER_OF_BODIES = 10000;
|
||||||
public static final double OVERALL_SYSTEM_MASS = 20 * SUN_MASS; // kilograms
|
public static final double OVERALL_SYSTEM_MASS = 2000 * SUN_MASS; // kilograms
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
CodeDraw cd = new CodeDraw();
|
CodeDraw cd = new CodeDraw();
|
||||||
@@ -51,24 +51,13 @@ public class Simulation {
|
|||||||
while (true) {
|
while (true) {
|
||||||
seconds++;
|
seconds++;
|
||||||
|
|
||||||
/*
|
|
||||||
BodyLinkedList mergedBodies = new BodyLinkedList();
|
|
||||||
for (Body b1 : bodies) {
|
|
||||||
BodyLinkedList colliding = bodies.removeCollidingWith(b1);
|
|
||||||
for (Body b2 : colliding) {
|
|
||||||
b1 = b1.merge(b2);
|
|
||||||
}
|
|
||||||
mergedBodies.addLast(b1);
|
|
||||||
}
|
|
||||||
bodies = mergedBodies;
|
|
||||||
*/
|
|
||||||
Octree octree = new Octree(new Vector(0, 0, 0), SECTION_SIZE);
|
Octree octree = new Octree(new Vector(0, 0, 0), SECTION_SIZE);
|
||||||
for (Body body : bodies) {
|
for (Body body : bodies) {
|
||||||
octree.add(body);
|
octree.add(body);
|
||||||
}
|
}
|
||||||
octree.applyForces(bodies, 1);
|
octree.applyForces(bodies, 100);
|
||||||
|
|
||||||
if ((seconds % 3600) == 0) {
|
if ((seconds % 60) == 0) {
|
||||||
cd.clear(Color.BLACK);
|
cd.clear(Color.BLACK);
|
||||||
for (Body body : bodies) {
|
for (Body body : bodies) {
|
||||||
body.draw(cd);
|
body.draw(cd);
|
||||||
|
@@ -45,6 +45,12 @@ public class Vector {
|
|||||||
return new Vector(x + v.x, y + v.y, z + v.z);
|
return new Vector(x + v.x, y + v.y, z + v.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void add(Vector v) {
|
||||||
|
this.x += v.x;
|
||||||
|
this.y += v.y;
|
||||||
|
this.z += v.z;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the product of this vector and 'd'.
|
* Returns the product of this vector and 'd'.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user