Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
4e81f4b3cd | |||
0259be8338
|
@ -37,14 +37,12 @@ public class Body {
|
|||||||
* Hint: see simulation loop in Simulation.java to find out how this is done.
|
* Hint: see simulation loop in Simulation.java to find out how this is done.
|
||||||
*/
|
*/
|
||||||
public Vector gravitationalForce(Body b) {
|
public Vector gravitationalForce(Body b) {
|
||||||
Vector direction = b.massCenter.minus(this.massCenter);
|
Vector direction = b.massCenter.minus(massCenter);
|
||||||
double distance = direction.length();
|
double distance = direction.length();
|
||||||
if (distance == 0) return direction;
|
if (distance == 0) return new Vector();
|
||||||
|
|
||||||
direction.normalize();
|
direction.normalize();
|
||||||
double force = Simulation.G * this.mass * b.mass / (distance * distance);
|
double force = Simulation.G * mass * b.mass / (distance * distance);
|
||||||
direction.mul(force);
|
return direction.times(force);
|
||||||
return direction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,10 +36,11 @@ public class Octree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyForces(Body[] bodies, Vector[] forces, double t) {
|
public void applyForces(Body[] bodies, double t) {
|
||||||
if (root == null) return;
|
if (root == null) return;
|
||||||
|
Vector[] forces = new Vector[bodies.length];
|
||||||
for (int i = 0; i < bodies.length; i++) {
|
for (int i = 0; i < bodies.length; i++) {
|
||||||
root.addForcesOnBody(bodies[i], forces[i], t);
|
forces[i] = root.getForcesOnBody(bodies[i], t);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < bodies.length; i++) {
|
for (int i = 0; i < bodies.length; i++) {
|
||||||
bodies[i].move(forces[i]);
|
bodies[i].move(forces[i]);
|
||||||
@ -50,6 +51,12 @@ public class Octree {
|
|||||||
if (root == null) return;
|
if (root == null) return;
|
||||||
root.draw(cd);
|
root.draw(cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getNumberOfBalancedRegions() {
|
||||||
|
if (root == null || !(root instanceof OctreeNode r)) return 0;
|
||||||
|
|
||||||
|
return r.getNumberOfBalancedRegions();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class OctreeItem {
|
abstract class OctreeItem {
|
||||||
@ -67,8 +74,6 @@ abstract class OctreeItem {
|
|||||||
|
|
||||||
abstract protected Vector getForcesOnBody(Body body, double t);
|
abstract protected Vector getForcesOnBody(Body body, double t);
|
||||||
|
|
||||||
abstract protected void addForcesOnBody(Body body, Vector force, double t);
|
|
||||||
|
|
||||||
abstract protected void draw(CodeDraw cd);
|
abstract protected void draw(CodeDraw cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,24 +109,18 @@ class OctreeNode extends OctreeItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Vector getForcesOnBody(Body body, double t) {
|
protected Vector getForcesOnBody(Body body, double t) {
|
||||||
Vector v = new Vector();
|
double r = pseudoBody.massCenter().distanceTo(body.massCenter());
|
||||||
addForcesOnBody(body, v, t);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void addForcesOnBody(Body body, Vector force, double t) {
|
|
||||||
double r = center.distanceTo(body.massCenter());
|
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
return;
|
return new Vector();
|
||||||
} else if (size / r < t) {
|
} else if (size / r < t) {
|
||||||
force.add(body.gravitationalForce(pseudoBody));
|
return body.gravitationalForce(pseudoBody);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
Vector force = new Vector();
|
||||||
for (OctreeItem child : children) {
|
for (OctreeItem child : children) {
|
||||||
if (child == null) continue;
|
if (child == null) continue;
|
||||||
child.addForcesOnBody(body, force, t);
|
force.add(child.getForcesOnBody(body, t));
|
||||||
}
|
}
|
||||||
|
return force;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -156,6 +155,26 @@ class OctreeNode extends OctreeItem {
|
|||||||
((octNum & 4) != 0) ? -1 : 1)
|
((octNum & 4) != 0) ? -1 : 1)
|
||||||
.times(this.size / 4));
|
.times(this.size / 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isBalanced() {
|
||||||
|
for (OctreeItem i : children) {
|
||||||
|
if (!(i instanceof OctreeLeaf))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getNumberOfBalancedRegions() {
|
||||||
|
if (isBalanced()) return 1;
|
||||||
|
|
||||||
|
int c = 0;
|
||||||
|
for (OctreeItem i : children) {
|
||||||
|
if (i instanceof OctreeNode n) {
|
||||||
|
c += n.getNumberOfBalancedRegions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OctreeLeaf extends OctreeItem {
|
class OctreeLeaf extends OctreeItem {
|
||||||
@ -164,7 +183,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);
|
this.pseudoBody = new Body(this.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -174,21 +193,14 @@ class OctreeLeaf extends OctreeItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Vector getForcesOnBody(Body body, double t) {
|
protected Vector getForcesOnBody(Body body, double t) {
|
||||||
return body.gravitationalForce(body);
|
return body.gravitationalForce(pseudoBody);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void addForcesOnBody(Body body, Vector force, double t) {
|
|
||||||
force.add(getForcesOnBody(body, t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void draw(CodeDraw cd) {
|
protected void draw(CodeDraw 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.GREEN);
|
cd.setColor(Color.GREEN);
|
||||||
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));
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ 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 = 10000;
|
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();
|
||||||
@ -48,34 +48,15 @@ public class Simulation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long seconds = 0;
|
long seconds = 0;
|
||||||
Vector[] forces = new Vector[bodies.length];
|
|
||||||
for (int i = 0; i < forces.length; i++) forces[i] = new Vector();
|
|
||||||
|
|
||||||
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;
|
|
||||||
*/
|
|
||||||
//long n1 = System.nanoTime();
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
//long n2 = System.nanoTime();
|
System.out.println(octree.getNumberOfBalancedRegions());
|
||||||
for (Vector f : forces) f.reset();
|
octree.applyForces(bodies, 100);
|
||||||
octree.applyForces(bodies, forces, 1);
|
|
||||||
//long n3 = System.nanoTime();
|
|
||||||
|
|
||||||
//System.out.format("%8.3f µs, %8.3f µs\n", (n2 - n1) / 1000.0, (n3 - n2) / 1000.0);
|
|
||||||
|
|
||||||
if ((seconds % 60) == 0) {
|
if ((seconds % 60) == 0) {
|
||||||
cd.clear(Color.BLACK);
|
cd.clear(Color.BLACK);
|
||||||
|
@ -58,18 +58,6 @@ public class Vector {
|
|||||||
return new Vector(x * d, y * d, z * d);
|
return new Vector(x * d, y * d, z * d);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mul(double d) {
|
|
||||||
this.x *= d;
|
|
||||||
this.y *= d;
|
|
||||||
this.z *= d;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void div(double d) {
|
|
||||||
this.x /= d;
|
|
||||||
this.y /= d;
|
|
||||||
this.z /= d;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sum of this vector and -1*v.
|
* Returns the sum of this vector and -1*v.
|
||||||
*/
|
*/
|
||||||
@ -92,7 +80,7 @@ public class Vector {
|
|||||||
* Returns the length (norm) of this vector.
|
* Returns the length (norm) of this vector.
|
||||||
*/
|
*/
|
||||||
public double length() {
|
public double length() {
|
||||||
return Math.sqrt(x * x + y * y + z * z);
|
return distanceTo(new Vector());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,13 +88,10 @@ public class Vector {
|
|||||||
* The direction and orientation of the vector is not affected.
|
* The direction and orientation of the vector is not affected.
|
||||||
*/
|
*/
|
||||||
public void normalize() {
|
public void normalize() {
|
||||||
div(length());
|
double length = length();
|
||||||
}
|
x /= length;
|
||||||
|
y /= length;
|
||||||
public void reset() {
|
z /= length;
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
z = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getScreenX(CodeDraw cd) {
|
public double getScreenX(CodeDraw cd) {
|
||||||
|
Reference in New Issue
Block a user