From 10eb2fbb0e5e2fed367864d45fb9545f0be377d2 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Wed, 4 May 2022 19:53:16 +0200 Subject: [PATCH] Trying to make more efficient --- src/Body.java | 10 ++++++---- src/Octree.java | 36 +++++++++++++++++++++++++----------- src/Simulation.java | 13 +++++++++++-- src/Vector.java | 25 ++++++++++++++++++++----- 4 files changed, 62 insertions(+), 22 deletions(-) diff --git a/src/Body.java b/src/Body.java index c5c08d3..884e1eb 100644 --- a/src/Body.java +++ b/src/Body.java @@ -37,12 +37,14 @@ public class Body { * Hint: see simulation loop in Simulation.java to find out how this is done. */ public Vector gravitationalForce(Body b) { - Vector direction = b.massCenter.minus(massCenter); + Vector direction = b.massCenter.minus(this.massCenter); double distance = direction.length(); - if (distance == 0) return new Vector(); + if (distance == 0) return direction; + direction.normalize(); - double force = Simulation.G * mass * b.mass / (distance * distance); - return direction.times(force); + double force = Simulation.G * this.mass * b.mass / (distance * distance); + direction.mul(force); + return direction; } /** diff --git a/src/Octree.java b/src/Octree.java index fe0988c..8763481 100644 --- a/src/Octree.java +++ b/src/Octree.java @@ -36,11 +36,10 @@ public class Octree { } } - public void applyForces(Body[] bodies, double t) { + public void applyForces(Body[] bodies, Vector[] forces, double t) { if (root == null) return; - Vector[] forces = new Vector[bodies.length]; for (int i = 0; i < bodies.length; i++) { - forces[i] = root.getForcesOnBody(bodies[i], t); + root.addForcesOnBody(bodies[i], forces[i], t); } for (int i = 0; i < bodies.length; i++) { bodies[i].move(forces[i]); @@ -68,6 +67,8 @@ abstract class OctreeItem { abstract protected Vector getForcesOnBody(Body body, double t); + abstract protected void addForcesOnBody(Body body, Vector force, double t); + abstract protected void draw(CodeDraw cd); } @@ -103,18 +104,24 @@ class OctreeNode extends OctreeItem { @Override protected Vector getForcesOnBody(Body body, double t) { - double r = pseudoBody.massCenter().distanceTo(body.massCenter()); + Vector v = new Vector(); + 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) { - return new Vector(); + return; } else if (size / r < t) { - return body.gravitationalForce(pseudoBody); + force.add(body.gravitationalForce(pseudoBody)); + return; } - Vector force = new Vector(); for (OctreeItem child : children) { if (child == null) continue; - force.add(child.getForcesOnBody(body, t)); + child.addForcesOnBody(body, force, t); } - return force; } @Override @@ -157,7 +164,7 @@ class OctreeLeaf extends OctreeItem { public OctreeLeaf(Vector center, double size, Body body) { super(center, size); this.body = body; - this.pseudoBody = new Body(this.body); + //this.pseudoBody = new Body(this.body); } @Override @@ -167,14 +174,21 @@ class OctreeLeaf extends OctreeItem { @Override protected Vector getForcesOnBody(Body body, double t) { - return body.gravitationalForce(pseudoBody); + return body.gravitationalForce(body); + } + + @Override + protected void addForcesOnBody(Body body, Vector force, double t) { + force.add(getForcesOnBody(body, t)); } @Override protected void draw(CodeDraw cd) { + /* Vector p1 = center.minus(new Vector(size / 2)); Vector p2 = new Vector(size).minus(new Vector(Simulation.SECTION_SIZE / 2)); cd.setColor(Color.GREEN); cd.drawRectangle(p1.getScreenX(cd), p1.getScreenY(cd), p2.getScreenX(cd), p2.getScreenY(cd)); + */ } } diff --git a/src/Simulation.java b/src/Simulation.java index 2f60e1d..b1c3bdb 100644 --- a/src/Simulation.java +++ b/src/Simulation.java @@ -22,7 +22,7 @@ public class Simulation { // set some system parameters public static final double SECTION_SIZE = 2 * AU; // the size of the square region in space - public static final int NUMBER_OF_BODIES = 220; + public static final int NUMBER_OF_BODIES = 10000; public static final double OVERALL_SYSTEM_MASS = 20 * SUN_MASS; // kilograms public static void main(String[] args) { @@ -48,6 +48,9 @@ public class Simulation { } long seconds = 0; + Vector[] forces = new Vector[bodies.length]; + for (int i = 0; i < forces.length; i++) forces[i] = new Vector(); + while (true) { seconds++; @@ -62,11 +65,17 @@ public class Simulation { } bodies = mergedBodies; */ + //long n1 = System.nanoTime(); Octree octree = new Octree(new Vector(0, 0, 0), SECTION_SIZE); for (Body body : bodies) { octree.add(body); } - octree.applyForces(bodies, 1); + //long n2 = System.nanoTime(); + for (Vector f : forces) f.reset(); + 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) { cd.clear(Color.BLACK); diff --git a/src/Vector.java b/src/Vector.java index ccc21df..901643a 100644 --- a/src/Vector.java +++ b/src/Vector.java @@ -58,6 +58,18 @@ public class Vector { 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. */ @@ -80,7 +92,7 @@ public class Vector { * Returns the length (norm) of this vector. */ public double length() { - return distanceTo(new Vector()); + return Math.sqrt(x * x + y * y + z * z); } /** @@ -88,10 +100,13 @@ public class Vector { * The direction and orientation of the vector is not affected. */ public void normalize() { - double length = length(); - x /= length; - y /= length; - z /= length; + div(length()); + } + + public void reset() { + x = 0; + y = 0; + z = 0; } public double getScreenX(CodeDraw cd) {