I have a model that works, as far as I know, but it's so messy! I am very new to Java, so I'd really appreciate some help tidying up. In particular, a lot of my constructors are empty which is probably not good, and I'm not sure if I've made the right choices in terms of public, static, void etc for my methods. It probably doesn't follow best practices.
SolarSim
(Main):
import java.util.Scanner;
import java.lang.Math;
import java.util.Arrays;
import java.io.*;
public class SolarSim{
private static final double earthMass = 5.9726*Math.pow(10,24);
private static final double earthRadius = 6371000;
private static final double sunMass = 1.9885*Math.pow(10,30);
private static final double sunRadius = 696342000;
private static final double mercuryMass = 3.301*Math.pow(10,23);
private static final double mercuryRadius = 2.44*Math.pow(10,6);
private static final PhysicsVector zero = new PhysicsVector(0,0);
private static final PhysicsVector zero1 = new PhysicsVector(0,0);
private static final PhysicsVector zero2 = new PhysicsVector(0,0);
private static final PhysicsVector zeroa = new PhysicsVector(0,0);
private static final PhysicsVector zerob = new PhysicsVector(0,0);
private static final PhysicsVector zeroc = new PhysicsVector(0,0);
public static PhysicsVector[] copyArray(PhysicsVector[] a) {
int length = a.length;
PhysicsVector[] copy = new PhysicsVector[length];
System.arraycopy(a, 0, copy, 0, length);
return copy;
}
public static double sumArray(double[] p){
double sum = 0;
for(int z= 0; z < p.length; z++){
sum += p[z];
}
return sum;
}
public static PhysicsVector[] add(PhysicsVector[] sum, PhysicsVector a){
for(int c = 0; c<sum.length; c++){
sum[c].increaseBy(a);
}
return sum;
}
public static PhysicsVector[] subtract(PhysicsVector[] diff, PhysicsVector g){
for (int ab=0; ab<diff.length;ab++){
diff[ab].decreaseBy(g);
}
return diff;
}
public static void main(String[] args) throws IOException{
java.io.File file = new java.io.File("output.txt" );
java.io.PrintWriter n = new PrintWriter(file);
//Initialise variables here
PhysicsVector earthInitialPos = new PhysicsVector();
PhysicsVector earthInitialV = new PhysicsVector();
PhysicsVector sunInitialV = new PhysicsVector();
PhysicsVector sunInitialPos = new PhysicsVector();
PhysicsVector mercuryInitialPos = new PhysicsVector();
PhysicsVector mercuryInitialV=new PhysicsVector();
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter the size of the time step:");
double timeStep = scanner.nextDouble();
//SET PLANETS' INITIAL POSITIONS
earthInitialPos.setVector(1.4960*Math.pow(10,11),0);
earthInitialV.setVector(0,29786.24);
sunInitialPos.setVector(0,0);
sunInitialV.setVector(0,0);
mercuryInitialPos.setVector(5.791*Math.pow(10,10),0);
mercuryInitialV.setVector(0,47873.5);
//CREATE GRAVFIELD OBJECTS
GravField sunGravField = new GravField(sunMass, sunRadius, sunInitialPos);
GravField earthGravField = new GravField(earthMass, earthRadius, earthInitialPos);
GravField mercuryGravField = new GravField(mercuryMass, mercuryRadius, mercuryInitialPos);
//CREATE PARTICLE OBJECTS
Particle earth = new Particle(earthMass, earthInitialPos, earthInitialV);
Particle sun = new Particle(sunMass, sunInitialPos, sunInitialV);
Particle mercury = new Particle(mercuryMass, mercuryInitialPos, mercuryInitialV);
double time = 0;
double finalTime = 31557600; //One earth year(seconds)
PhysicsVector newSunGrav = new PhysicsVector();
PhysicsVector newEarthGrav = new PhysicsVector();
PhysicsVector newMoonGrav = new PhysicsVector();
GravField[] gravityObject = {earthGravField, sunGravField, mercuryGravField};
PhysicsVector[] position = {earthInitialPos, sunInitialPos, mercuryInitialPos};
PhysicsVector[] velocity = {earthInitialV, sunInitialV, mercuryInitialV};
PhysicsVector[] gravField = {zero, zero1, zero2};
double[] planetMass = {earthMass, sunMass, mercuryMass};
Particle[] planets = {earth, sun, mercury};
//Calculate the centre of mass and subtract position from positions of planets, so c.o.m is at origin
PhysicsVector centreOfMass = new PhysicsVector();
centreOfMass = sun.centreOfMass(planetMass, position);
position = SolarSim.subtract(position, centreOfMass);
System.out.println(Arrays.toString(position));
centreOfMass.print();
//Calculate centre of mass velocity and subtract from planet velocities
PhysicsVector centreOfMassVelocity = new PhysicsVector();
centreOfMassVelocity = sun.cOMVel(planetMass, velocity);
centreOfMassVelocity.print();
velocity = SolarSim.subtract(velocity, centreOfMassVelocity);
//Calculate fields of planets
for(int ac=0; ac<gravityObject.length; ac++){
for(int ad=0;ad<gravityObject.length;ad++){
if(ac!=ad){
gravField[ac].increaseBy(gravityObject[ac].aDueToGravity(planetMass[ad], position[ad], position[ac]));
}
else{
//do nothing
}
}
}
PhysicsVector[] newP = new PhysicsVector[position.length];
PhysicsVector[] newGrav = {zeroa,zerob,zeroc};
PhysicsVector[] newVel = new PhysicsVector[velocity.length];
do{
PhysicsVector[] y = new PhysicsVector[gravField.length];
y=copyArray(gravField);
for(int i=0; i<planets.length;i++){
newP[i] = planets[i].updatePosition(position[i], velocity[i], timeStep, gravField[i]);
}
for(int j=0; j<gravityObject.length; j++){
for(int l=0;l<gravityObject.length;l++){
if(j!=l){
newGrav[j].increaseBy(gravityObject[j].aDueToGravity(planetMass[l], newP[l], newP[j]));
}
else{
//do nothing
}
}
}
for(int k=0; k<planets.length; k++){
newVel[k] = planets[k].updateVelocity(velocity[k], timeStep, y[k], newGrav[k]);
}
//Calculate centre of mass velocity and subtract from planet velocities
centreOfMassVelocity = earth.cOMVel(planetMass, newVel);
for (int ab=0; ab<newVel.length;ab++){
newVel[ab].decreaseBy(centreOfMassVelocity);
}
newVel = SolarSim.subtract(newVel, centreOfMassVelocity);
gravField = copyArray(newGrav);
velocity = newVel;
position = newP;
time+=timeStep;
double x = newP[0].getX();
double ap = newP[0].getY();
n.println(x+" "+ap);
}while (time<=1000*finalTime);
System.out.println(Arrays.toString(newP));
n.close();
}
}
Particle
:
import java.lang.Math;
//Class that creates a particle object with mass, initial velocity and initial position
public class Particle{
private double mass;
PhysicsVector initialPosition = new PhysicsVector();
PhysicsVector initialVelocity = new PhysicsVector();
PhysicsVector centreOfMass = new PhysicsVector(0,0);
PhysicsVector cOMV=new PhysicsVector(0,0);
//Default constructor
public Particle(){
mass = 1;
initialPosition.setVector(0,0);
initialVelocity.setVector(1,1);
}
//Constructor
public Particle(double mass, PhysicsVector x, PhysicsVector y){
}
//Make it static or not?
public PhysicsVector updatePosition(PhysicsVector initialPosition, PhysicsVector initialVelocity, double timeStep, PhysicsVector aDueToGravity){
PhysicsVector x = new PhysicsVector(initialVelocity);
x.scale(timeStep);
PhysicsVector z = new PhysicsVector(aDueToGravity);
z.scale(0.5*timeStep*timeStep);
initialPosition.increaseBy(x);
initialPosition.increaseBy(z);
return initialPosition;
}
public PhysicsVector updateVelocity(PhysicsVector initialVelocity, double timeStep, PhysicsVector a, PhysicsVector newA){
PhysicsVector z = new PhysicsVector(newA);
PhysicsVector x = new PhysicsVector(a);
z.increaseBy(x);
z.scale(0.5*timeStep);
initialVelocity.increaseBy(z);
return initialVelocity;
}
public PhysicsVector centreOfMass(double[] mass, PhysicsVector[] positions){
//Set origin at centre of sun, so that sunMass*distance = 0
double sum = SolarSim.sumArray(mass);
for(int i=0;i<positions.length;i++){
centreOfMass.increaseBy(positions[i].scale(mass[i],positions[i]));
}
centreOfMass.scale(1/sum);
return centreOfMass;
}
public PhysicsVector cOMVel(double[] mass, PhysicsVector[] velocity){
double total = SolarSim.sumArray(mass);
for(int ae=0;ae<velocity.length;ae++){
cOMV.increaseBy(velocity[ae].scale(mass[ae],velocity[ae]));
}
cOMV.scale(1/total);
return cOMV;
}
}
GravField
:
import java.lang.Math;
import java.io.*;
//Class to create a gravity object.
public class GravField{
public static final double G = 6.67408*Math.pow(10,-11);
private double planetMass;
private double planetRadius;
PhysicsVector gravityAcceleration = new PhysicsVector();
/**
*Default constructor that creates a GravField object with the mass and radius of the earth,
*acting on a projectile starting at x=0, y=0, where the x and y axes are on the surface of the planet
*/
public GravField(){
}
/**
*Constructor that creates a GravField object
*@param planetMass Mass of the planet whose field is to be calculated
*@param planetRadius Radius of the planet
*/
public GravField(double mass, double radius, PhysicsVector initialPos){
//can't think of anything to do here
}
//Calculates the acceleration due to the gravitational field of the object
public PhysicsVector aDueToGravity(double planetMass, PhysicsVector sourcePos, PhysicsVector initialPosition){
PhysicsVector a = new PhysicsVector(sourcePos);
PhysicsVector b = new PhysicsVector(initialPosition);
b.decreaseBy(sourcePos);
double distance = b.magnitude();
b.scale(-1*G*planetMass/(distance*distance*distance));
return b;
}
}