diff --git a/Main.java b/Main.java new file mode 100644 index 0000000..4369b66 --- /dev/null +++ b/Main.java @@ -0,0 +1,32 @@ +import java.awt.Dimension; +import java.awt.Toolkit; + +import javax.swing.JFrame; + +public class Main { + + static Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize(); + static Dimension dim = new Dimension(1200,800); + static Dimension dim2 = new Dimension(1000,800); + static Dimension dim3 = new Dimension(800,600); + + static Dimension frameDim = screenDim; + + + + public static void main(String[] args) { + // TODO Auto-generated method stub + + + JFrame win = new JFrame("Realtime: Drawing of a Solar System [IN PROGRESS]"); + + MainPanel mainPanel = new MainPanel(); + + win.setSize(frameDim); + win.setLocationRelativeTo(null); + win.setContentPane(mainPanel); + win.setVisible(true); + + } + +} diff --git a/MainPanel.java b/MainPanel.java new file mode 100644 index 0000000..54dfaf2 --- /dev/null +++ b/MainPanel.java @@ -0,0 +1,537 @@ +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.Ellipse2D; +import java.util.Arrays; +import java.util.Scanner; +import javax.swing.JPanel; + + +/** +* This class contains all the information about three bodies involved in the 3-body problem necessary to produce a graph +* as well as to calculate minimum and maximum values of certain quantities +* +*@authors Matthew Williams, Yulia Kosharych +*@version 17-05-2017 +*/ + +public class MainPanel extends JPanel{ + +public static Dimension MainPanelDim = Main.frameDim; + +//Objects +Object sun; +Object sat; +Object earth; + +//Dimensions of the simulation box +public static final double x0 = MainPanelDim.getWidth()/2; +public static final double y0 = MainPanelDim.getHeight()/2; + +//Radius of simulation models +final double sunR = 75; +final double satR = 35; +final double earthR = 35; + +//Simulation colors +Color sunColor; +Color satColor; +Color earthColor; + +double t = 0; +public static final double G = 8.64960768*Math.pow(10, -13);//gravitational constant (km^3/kg/h^2) +public static final double dt = 1.0; //delta t in hours +public static final double tmax = 8760 ; //number of hours to run (1 year) +public static double time = 0; //initial time +public static final boolean graphing = true; +public static final double au = 1.49597870700*Math.pow(10,8);//initial distance of earth from the sun in km + +//Masses +public static final double massSun=SolarBody.massSol; //kg +public static final double massEarth= SolarBody.massEarth; //kg +public static final double massJupiter =SolarBody.massJupiter;//kg +public static final double massL5 = massEarth/1000; //kg +public static double massSat; //kg +public static double massPlanet; //mass of the planet + +//Velocities +public static final double velocityEarth = BodyMaths.circleVelocityG(massSun,au);// initial velocity of Earth +public static final double velocityJupiter = BodyMaths.circleVelocityG(massSun,5.2*au);//velocity Jupiter + +public static double scaling =350; +public static Scanner kb = new Scanner(System.in); +public static double [][][] object = new double[3][3][2]; +public static double [] maxAccel, minPosSun, minPosEarth; +double satX, satY, velInitialX, velInitialY; +double planetX, planetY, velInitialPlanetX, velInitialPlanetY; + +/** + * This method does the Sun-Earth-Moon simulation + * + * @authors Matthew Williams,Yulia Kosharych + * @version 17-05-2018 + */ +public void initSunEarthLuna(){ + +scaling = 350; +//Sat Conditions +massSat = SolarBody.massLuna; +satX = au-384400; +satY = 0; +velInitialX = 0; +velInitialY = velocityEarth+BodyMaths.circleVelocityG(massEarth,384402);; + +//Earth Condition +massPlanet=massEarth; +planetX =au; +planetY =0; +velInitialPlanetX = 0; +velInitialPlanetY =velocityEarth; + + +} + +/** + * This method does the Sun-Earth-L5 simulation + * + * @authors Matthew Williams,Yulia Kosharych + * @version 17-05-2018 + */ +public void initSunEarthL5(){ + +scaling = 150; +//Sat Conditions +massSat = massL5; +satX = 0.7*au; +satY = 0.7*au; +velInitialX = 0.7*velocityEarth; +velInitialY = 0.7*velocityEarth; + +//Planet Condition +massPlanet=massEarth; +planetX =au; +planetY =0; +velInitialPlanetX = 0; +velInitialPlanetY =velocityEarth; + +} + +/** + * This method does the Sun-Jupiter-PlanetX simulation + * + * @authors Matthew Williams,Yulia Kosharych + * @version 17-05-2018 + */ +public void initSunJupiterProbe(){ + +scaling =75; +//Sat Conditions +System.out.println("Please enter the mass of the satellite:"); +massSat = kb.nextDouble(); + +System.out.println("Please enter the x position of the satellite:"); +satX = kb.nextDouble(); +System.out.println("Please enter the y position of the satellite:"); +satY = kb.nextDouble(); +System.out.println("Please enter the initial x component of the velocity of satellite"); +velInitialX = kb.nextDouble(); +System.out.println("Please enter the initial y component of the velocity of satellite"); +velInitialY = kb.nextDouble(); + +//Jupiter Condition +massPlanet=massJupiter; +planetX =5.2*au; +planetY =0; +velInitialPlanetX = 0; +velInitialPlanetY =velocityJupiter; +} + +/** + * This method assigns values to vector components of velocity, acceleration and position of each object + * + * @authors Matthew Williams,Yulia Kosharych + * @version 17-05-2018 + */ +public void Algorithm(){ + +//Earth or any random planet +object[0][0][0] = planetX; +object[0][0][1] = planetY; + +object[0][1][0] = velInitialPlanetX; +object[0][1][1] = velInitialPlanetY; + +object[0][2][0] = 0; +object[0][2][1] = 0; + +//Sun +object[1][0][0] = 0; +object[1][0][1] = 0; + +object[1][1][0] = 0; +object[1][1][1] = 0; + +object[1][2][0] = 0; +object[1][2][1] = 0; + +//Satellite +object[2][0][0] = satX; +object[2][0][1] = satY; + +object[2][1][0] = velInitialX; +object[2][1][1] = velInitialY; + +object[2][2][0] = 0; +object[2][2][1] = 0; +} + +/** + * This is the main method which determines the simulation that will be displayed on the screen + * + * @authors Matthew Williams,Yulia Kosharych + * @version 17-05-2018 + */ +public MainPanel() { +this.setSize(Main.dim2); +int sim; +System.out.println("Please enter the simulation number: "); +sim = kb.nextInt(); + +//Simulation number +if(sim == 1) initSunEarthLuna(); +if (sim == 2) initSunEarthL5(); +if (sim == 3) initSunJupiterProbe(); + +//Algorithm for graphing +Algorithm(); +sunColor = new Color(255, 172, 0); +sun = new Object(object[1][0][0] + x0, object[1][0][1] + y0, sunR); +satColor = new Color(211,211,211); +sat = new Object((scaling*object[2][0][0]/au) + x0, (275*object[2][0][1]/au) + y0, satR); +earthColor = new Color(47,94,79); +earth = new Object((scaling*object[0][0][0]/au) + x0, (275*object[0][0][1]/au) + y0, earthR); +maxAccel = object[2][2]; +minPosSun = differencePos(object[2][0],object[1][0]); +minPosEarth = differencePos(object[2][0],object[0][0]); +} + +/** +* This method updates acceleration, velocity and position of each object under the influence of two other objects +* +* @authors Matthew Williams,Yulia Kosharych +* @version 17-05-2018 +*/ +public void update() { + +object[0][2] = accelSunAnyObj(massSun,object[0][0],object[1][0]); +object[1][2] = accelSunAnyObj(massPlanet,object[1][0],object[0][0]); +object[2][2] = accelSunAnyObj(massSun,object[2][0], object[1][0]); + +object[1][2] = add(object[1][2], accelSunAnyObj(massSat,object[1][0], object[2][0])); +object[0][2] = add(object[0][2], accelSunAnyObj(massSat,object[0][0],object[2][0])); +object[2][2] = add(object[2][2], accelSunAnyObj(massPlanet, object[2][0],object[0][0])); + +object[0][1] = add((mult(object[0][2])), object[0][1]); +object[1][1] = add((mult(object[1][2])), object[1][1]); +object[2][1] = add((mult(object[2][2])), object[2][1]); + +object[0][0] = add((mult(object[0][1])), object[0][0]); +object[1][0] = add((mult(object[1][1])), object[1][0]); +object[2][0] = add((mult(object[2][1])), object[2][0]); +} + +/** + * This method does the graphing of the 3-body system + * + * @return double add + * @authors Matthew Williams,Yulia Kosharych + * @version 17-05-2018 + */ +public void paintChildren(Graphics g) +{ + +super.paintChildren(g); + +//findMaxAccel(); //satellite +maxAccel = compareAccel(maxAccel,object[2][2]); + +// findMinDis(); //sun +minPosSun = comparePosition(minPosSun, differencePos(object[2][0],object[1][0])); + +// findMinDis(); //earth +minPosEarth = comparePosition(minPosEarth, differencePos(object[2][0],object[0][0])); + +//Set the background of the graph +Graphics2D g2 = (Graphics2D) g; +g2.setColor(Color.BLACK); +g2.fillRect(0, 0, MainPanelDim.width, MainPanelDim.height); + + +//Drawing Sun +sun.updateCelestialObj(object[1][0]); +sun.paintObj(g2, sunColor); + + +//Drawing Planet +earth.updateCelestialObj(object[0][0]); +earth.paintObj(g2, earthColor); + +//Drawing Sat +sat.updateCelestialObj(object[2][0]); +sat.paintObj(g2, satColor); +update(); + +//Adjust for DELAY + + +//Display Time + +g2.setColor(Color.RED); +time += dt; + +//Display number of hours and years of simulation on the graph + +g2.setStroke(new BasicStroke(3)); +g2.drawString("Number of hours : " + Double.toString(time), 10, 12); +g2.drawString("Number of years : " + Double.toString(time/8760), 10, 29); + +//Acceleration Vectors +g2.drawLine((int) ((scaling*object[1][0][0]/au) + x0),(int) ((scaling*object[1][0][1]/au) + y0), (int)(((scaling*object[1][0][0]/au) + x0 ) + (0.7*sunR)*getUnit(object[1][2], getMag(object[1][2]))[0]), (int)(((scaling*object[1][0][1]/au) + y0 ) + (0.7*sunR)*getUnit(object[1][2], getMag(object[1][2]))[1])); +g2.drawLine((int) ((scaling*object[0][0][0]/au) + x0),(int) ((scaling*object[0][0][1]/au) + y0 ), (int)(((scaling*object[0][0][0]/au) + x0 ) + (0.7*earthR)*getUnit(object[0][2], getMag(object[0][2]))[0]), (int)(((scaling*object[0][0][1]/au) + y0 ) + (0.7*earthR)*getUnit(object[0][2], getMag(object[0][2]))[1])); +g2.drawLine((int) ((scaling*object[2][0][0]/au) + x0),(int) ((scaling*object[2][0][1]/au) + y0 ), (int)(((scaling*object[2][0][0]/au) + x0 ) + (0.7*satR)*getUnit(object[2][2], getMag(object[2][2]))[0]), (int)(((scaling*object[2][0][1]/au) + y0 ) + (0.7*satR)*getUnit(object[2][2], getMag(object[2][2]))[1])); + + +repaint(); + +//Display maximum acceleration reached by the satellite as well as the minimum distance reached to +//two other objects + +if(time==tmax) { +System.out.println("The maximim acceleration is: " +getMag(maxAccel)); +System.out.println("The minimum position of the satellite to the planet is: "+getMag(minPosEarth)); +System.out.println("The minimum position of the satellite to the Sun is: "+getMag(minPosSun)); +System.exit(0); + +} +} + + /** + * This method takes a double array as an input and multiplies is by the derivative of time + * + * @param double[] array + * @return array + * @authors Matthew Williams,Yulia Kosharych + * @version 17-05-2018 + */ + +public static double [] mult(double [] array) { +for(int i =0; i magPosFin ) { +return posFinal; +}else { +return posInitial; +} +} + +/** + * This method compares instantaneous velocities of an object and returns the smallest one + * @param double [] velInitial + * @param double [] velFinal + * @return velFinal if the following velocity is greater than the previous one + * @return velInitial if the following velocity is smaller than the previous one + * @authors Matthew Williams,Yulia Kosharych + * @version 17-05-2018 + */ +public static double compareVelocity(double[] velInitial, double[] velFinal) { +double magVelIn = getMag(velInitial); +double magVelFin = getMag(velFinal); +if (magVelIn < magVelFin ) { +return magVelFin; +}else { +return magVelIn; +} +} + +}//end MainPanel class diff --git a/Object.java b/Object.java new file mode 100644 index 0000000..3056fc8 --- /dev/null +++ b/Object.java @@ -0,0 +1,75 @@ +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Ellipse2D; + +public class Object { + + + double[] initPosVec = new double[2]; + double[] PosVec = new double[2]; + + double radius; + + Ellipse2D object; + + public Object(double _x0, double _y0, double _radius) + { + + + radius = _radius; + + initPosVec[0] = _x0 - radius/2; + initPosVec[1] = _y0 - radius/2; + + PosVec[0] = _x0 - radius/2; + PosVec[1] = _y0 - radius/2; + + + + object = new Ellipse2D.Double(initPosVec[0], initPosVec[1], radius, radius); //sets centered object at x0, y0 + + + } + + public double[] getInitPosVec() + { + return initPosVec; + + } + + public void updateObj(double[] posVec) + { + + PosVec[0] = posVec[0]; + PosVec[1] = posVec[1]; + + object.setFrame(PosVec[0], PosVec[1], radius, radius); + } + + public void updateCelestialObj(double[] posVec) + { + + PosVec[0] = (MainPanel.scaling*posVec[0])/MainPanel.au + MainPanel.x0 - radius/2; + PosVec[1] = (MainPanel.scaling*posVec[1])/MainPanel.au + MainPanel.y0 - radius/2; + + object.setFrame(PosVec[0], PosVec[1], radius, radius); + } + + public void readObj(double[][] posVec, int t) + { + + PosVec[0] = posVec[0][t]; + PosVec[1] = posVec[1][t]; + + object.setFrame(posVec[0][t], posVec[1][t], radius, radius); + } + + public void paintObj(Graphics2D g, Color color) + { + + g.setColor(color); + g.fill(object); + + } + +} diff --git a/ThreeBodyInstantaneousSimulationVersion b/ThreeBodyInstantaneousSimulationVersion index 22ac7a1..fd0d62d 100644 --- a/ThreeBodyInstantaneousSimulationVersion +++ b/ThreeBodyInstantaneousSimulationVersion @@ -12,39 +12,27 @@ public static final double dt = 0.1; //delta t in hours public static double tmax ; //number of hours to run public static double time = 0; //initial time - // public static final double tmax; //number of hours to run {inputs} public static final int imax =(int) (tmax/dt); //number of time steps - // public static final double imax; //number of time steps {inputs} public static final boolean graphing = true; public static final double au = 1.49597870700*Math.pow(10,8);//initial distance of earth from the sun in km - // public static final double radEarth=; //km - // public static final double radSun=; //km - public static final double massEarth=5.972*Math.pow(10, 24); //kg public static final double massSun=1.989*Math.pow(10, 30); //kg public static double massSat; //kg public static final double velocityEarth = 1.08*Math.pow(10, 5);// initial velocity of Earth + public static Scanner kb = new Scanner(System.in); - - public static void main(String[] args) { System.out.print("Please enter the duration of the simulation: "); - tmax = kb.nextDouble(); + tmax = kb.nextDouble(); System.out.print("Please enter the mass of the satellite: "); - massSat = kb.nextDouble(); + massSat = kb.nextDouble(); double satX, satY, velInitialX, velInitialY; - // earthX[0][0]=1.495978*Math.pow(10,16); - // earthX[1][0]=0; - // earthY[1][0]=108000; - // earthY[0][0]=0; - // System.out.println("please enter the mass of the satellite: "); - // massSat = kb.nextDouble(); System.out.print("Please enter the initial x position of the satellite: "); satX = kb.nextDouble(); System.out.print("Please enter the initial y position of the satellite: "); @@ -54,10 +42,6 @@ System.out.print("Please enter the initial y velocity of the satellite: "); velInitialY = kb.nextDouble(); - - - - double [][][] object = new double [3][3][2]; @@ -85,7 +69,7 @@ object[1][2][0] = 0; object[1][2][1] = 0; - //Sat + //Satellite object[2][0][0] = satX; object[2][0][1] = satY; @@ -150,79 +134,119 @@ - public static double [] mult(double [] array) { - - for(int i =0; i