2 Commits

Author SHA1 Message Date
4e81f4b3cd Übungstest 7 2022-06-09 14:40:49 +02:00
0259be8338 Last fixes 2022-06-07 22:27:26 +02:00
4 changed files with 49 additions and 73 deletions

View File

@ -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;
} }
/** /**

View File

@ -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));
*/
} }
} }

View File

@ -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);

View File

@ -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) {