001 import java.awt.*; 002 import java.awt.event.*; 003 import java.util.*; 004 import javax.swing.*; 005 import java.io.*; 006 import java.lang.*; 007 008 /** 009 * This class is a sub class of <code>JFrame</code> and is responsible for the GUI and 010 * for displaying the space objects and there orbits. 011 * It is doing most of the work. 012 * @author Markus Signitzer 013 */ 014 public class Display extends JFrame{ 015 /** 016 * The integrator will hold a instance of <code>SolarIntegrator</code> and 017 * will be needed by the paint() method. 018 */ 019 SolarIntegrator integrator; 020 /** 021 * Is the screen where the Space Objects and their orbits will be displayed. 022 */ 023 ScreenOne screenOne; 024 /** 025 * The JSlider will be used to zoom in and out of the solar system. 026 */ 027 JSlider scaleSlider; 028 /** 029 * Will hold all the positon data for all Space Objects in the HELIO Centric case. 030 */ 031 Vector oldDataH = new Vector(); 032 /** 033 * Will hold all the positon data for cruithne in the special "second moon view". 034 */ 035 Vector oldSecondMoon = new Vector(); 036 /** 037 * Will hold all the positon data for cruithne in the special "second moon view". 038 */ 039 Vector oldCoRotational = new Vector(); 040 041 /** 042 * Will hold all the positon data for all Space Objects in the GEO Centric case. 043 */ 044 Vector oldData = new Vector(); 045 /** 046 * The array of Space Objects making up my Solar System. 047 */ 048 SpaceObject[] objects; 049 050 /** 051 * Constructs a <code>Display</code> which will act as my main GUI. 052 * 053 * @param objects the array of Space Objects making up my Solar System. 054 * @param startPoint the initial positons and velocities of all Space Objects. 055 */ 056 public Display(SpaceObject[] objects, PointN startPoint){ 057 058 this.objects = objects; 059 //initialize Window 060 setBackground(Color.lightGray); 061 setTitle("Solar-System-Simulator by Markus Signitzer"); 062 Dimension screenSize = getToolkit().getScreenSize(); 063 setSize(550, screenSize.height-35); 064 //setSize(500, 700); 065 //setResizable(false); 066 067 getContentPane().setLayout(new BorderLayout()); 068 069 // create a Panel to draw onto 070 screenOne = new ScreenOne(objects, startPoint); 071 072 screenOne.setBorder(BorderFactory.createLineBorder(Color.green, 2)); 073 // some Buttons and panels which are needed for the GUI 074 JPanel buttonPanel = new JPanel(); 075 buttonPanel.setLayout(new GridLayout(2, 3)); 076 077 JButton pause = new JButton("Run/Pause"); 078 pause.addMouseListener(new PausePressed()); 079 080 JButton write = new JButton("Display selected orbits ON/OFF"); 081 write.addMouseListener(new WritePressed()); 082 083 JButton clear = new JButton("Clear Orbits"); 084 clear.addMouseListener(new ClearPressed()); 085 086 JButton helio = new JButton("SWITCH VIEWS"); 087 helio.addMouseListener(new HelioPressed()); 088 089 JButton momentumChange = new JButton("Change Cruithnes Momentum"); 090 momentumChange.addMouseListener(new MomentumChange()); 091 092 JButton importUpdatedMomentum = new JButton("Import Updated Momentum"); 093 importUpdatedMomentum.addMouseListener(new ImportUpdatedMomentum()); 094 095 scaleSlider = new JSlider(JSlider.VERTICAL, 1, 30, 1); 096 scaleSlider.setMajorTickSpacing(1); 097 scaleSlider.setPaintTicks(true); 098 scaleSlider.setPaintLabels(true); 099 100 // Pull-down menu bar to select which space object should 101 // display their trajectory 102 JMenuBar menubar = new JMenuBar(); 103 menubar.add(createMenu()); 104 setJMenuBar(menubar); 105 106 // add the buttons 107 buttonPanel.add(pause); 108 buttonPanel.add(write); 109 buttonPanel.add(clear); 110 buttonPanel.add(helio); 111 buttonPanel.add(momentumChange); 112 buttonPanel.add(importUpdatedMomentum); 113 114 // add everything on to the main Frame 115 getContentPane().add(screenOne, BorderLayout.CENTER); 116 getContentPane().add(buttonPanel, BorderLayout.SOUTH); 117 getContentPane().add(scaleSlider, BorderLayout.EAST); 118 } 119 120 /** 121 * Method for creating a pull down Menu. 122 * Will allow the user to select which orbits should be displayed. 123 * @return <code>JMenu</code> a pull down menu, ready to be attached to the main frame. 124 */ 125 private JMenu createMenu(){ 126 JMenu menu = new JMenu("CLICK HERE to select which orbits you want displayed"); 127 JCheckBoxMenuItem sun = new JCheckBoxMenuItem("Sun", false); 128 sun.setBackground(Color.yellow); 129 sun.addMouseListener(new SunPressed()); 130 menu.add(sun); 131 132 JCheckBoxMenuItem mercury = new JCheckBoxMenuItem("Mercury", false); 133 mercury.setBackground(Color.gray); 134 mercury.addMouseListener(new MercuryPressed()); 135 menu.add(mercury); 136 137 JCheckBoxMenuItem venus = new JCheckBoxMenuItem("Venus", false); 138 venus.setBackground(Color.orange); 139 venus.addMouseListener(new VenusPressed()); 140 menu.add(venus); 141 142 JCheckBoxMenuItem earth = new JCheckBoxMenuItem("Earth", false); 143 earth.setBackground(Color.blue); 144 earth.addMouseListener(new EarthPressed()); 145 menu.add(earth); 146 147 JCheckBoxMenuItem mars = new JCheckBoxMenuItem("Mars",false); 148 mars.setBackground(Color.red); 149 mars.addMouseListener(new MarsPressed()); 150 menu.add(mars); 151 152 JCheckBoxMenuItem jupiter = new JCheckBoxMenuItem("Jupiter",false); 153 jupiter.setBackground(Color.orange); 154 jupiter.addMouseListener(new JupiterPressed()); 155 menu.add(jupiter); 156 157 JCheckBoxMenuItem saturn = new JCheckBoxMenuItem("Saturn", false); 158 saturn.setBackground(Color.cyan); 159 saturn.addMouseListener(new SaturnPressed()); 160 menu.add(saturn); 161 162 JCheckBoxMenuItem uranus = new JCheckBoxMenuItem("Uranus", false); 163 uranus.setBackground(Color.green); 164 uranus.addMouseListener(new UranusPressed()); 165 menu.add(uranus); 166 167 JCheckBoxMenuItem neptune = new JCheckBoxMenuItem("Neptune",false); 168 neptune.setBackground(Color.blue); 169 neptune.addMouseListener(new NeptunPressed()); 170 menu.add(neptune); 171 172 JCheckBoxMenuItem cruithne = new JCheckBoxMenuItem("Cruithne",true); 173 cruithne.setBackground(Color.white); 174 cruithne.addMouseListener(new CruithnePressed()); 175 menu.add(cruithne); 176 177 return menu; 178 } 179 180 181 /** 182 * A little nested class which extends <code>MouseAdapter</code>. Makes the 183 * pull down menu interactive. i.e. this class changes the 184 * visibility of the orbit of a certain space object. 185 */ 186 class SunPressed extends MouseAdapter{ 187 public void mousePressed(MouseEvent e){ 188 //Button Pressed 189 if (objects[0].getDisplay()){ 190 objects[0].setDisplay(false); 191 }else{ 192 objects[0].setDisplay(true); 193 } 194 195 } 196 } 197 /** 198 * A little nested class which extends <code>MouseAdapter</code>. Makes the 199 * pull down menu interactive. i.e. this class changes the 200 * visibility of the orbit of a certain space object. 201 */ 202 class MercuryPressed extends MouseAdapter{ 203 public void mousePressed(MouseEvent e){ 204 //Button Pressed 205 if (objects[1].getDisplay()){ 206 objects[1].setDisplay(false); 207 }else{ 208 objects[1].setDisplay(true); 209 } 210 211 } 212 } 213 /** 214 * A little nested class which extends <code>MouseAdapter</code>. Makes the 215 * pull down menu interactive. i.e. this class changes the 216 * visibility of the orbit of a certain space object. 217 */ 218 class VenusPressed extends MouseAdapter{ 219 public void mousePressed(MouseEvent e){ 220 //Button Pressed 221 if (objects[2].getDisplay()){ 222 objects[2].setDisplay(false); 223 }else{ 224 objects[2].setDisplay(true); 225 } 226 227 } 228 } 229 /** 230 * A little nested class which extends <code>MouseAdapter</code>. Makes the 231 * pull down menu interactive. i.e. this class changes the 232 * visibility of the orbit of a certain space object. 233 */ 234 class EarthPressed extends MouseAdapter{ 235 public void mousePressed(MouseEvent e){ 236 //Button Pressed 237 if (objects[3].getDisplay()){ 238 objects[3].setDisplay(false); 239 }else{ 240 objects[3].setDisplay(true); 241 } 242 243 } 244 } 245 /** 246 * A little nested class which extends <code>MouseAdapter</code>. Makes the 247 * pull down menu interactive. i.e. this class changes the 248 * visibility of the orbit of a certain space object. 249 */ 250 class MarsPressed extends MouseAdapter{ 251 public void mousePressed(MouseEvent e){ 252 //Button Pressed 253 if (objects[4].getDisplay()){ 254 objects[4].setDisplay(false); 255 }else{ 256 objects[4].setDisplay(true); 257 } 258 259 } 260 } 261 /** 262 * A little nested class which extends <code>MouseAdapter</code>. Makes the 263 * pull down menu interactive. i.e. this class changes the 264 * visibility of the orbit of a certain space object. 265 */ 266 class JupiterPressed extends MouseAdapter{ 267 public void mousePressed(MouseEvent e){ 268 //Button Pressed 269 if (objects[5].getDisplay()){ 270 objects[5].setDisplay(false); 271 }else{ 272 objects[5].setDisplay(true); 273 } 274 275 } 276 } 277 /** 278 * A little nested class which extends <code>MouseAdapter</code>. Makes the 279 * pull down menu interactive. i.e. this class changes the 280 * visibility of the orbit of a certain space object. 281 */ 282 class SaturnPressed extends MouseAdapter{ 283 public void mousePressed(MouseEvent e){ 284 //Button Pressed 285 if (objects[6].getDisplay()){ 286 objects[6].setDisplay(false); 287 }else{ 288 objects[6].setDisplay(true); 289 } 290 291 } 292 } 293 /** 294 * A little nested class which extends <code>MouseAdapter</code>. Makes the 295 * pull down menu interactive. i.e. this class changes the 296 * visibility of the orbit of a certain space object. 297 */ 298 class UranusPressed extends MouseAdapter{ 299 public void mousePressed(MouseEvent e){ 300 //Button Pressed 301 if (objects[7].getDisplay()){ 302 objects[7].setDisplay(false); 303 }else{ 304 objects[7].setDisplay(true); 305 } 306 307 } 308 } 309 /** 310 * A little nested class which extends <code>MouseAdapter</code>. Makes the 311 * pull down menu interactive. i.e. this class changes the 312 * visibility of the orbit of a certain space object. 313 */ 314 class NeptunPressed extends MouseAdapter{ 315 public void mousePressed(MouseEvent e){ 316 //Button Pressed 317 if (objects[8].getDisplay()){ 318 objects[8].setDisplay(false); 319 }else{ 320 objects[8].setDisplay(true); 321 } 322 323 } 324 } 325 /** 326 * A little nested class which extends <code>MouseAdapter</code>. Makes the 327 * pull down menu interactive. i.e. this class changes the 328 * visibility of the orbit of a certain space object. 329 */ 330 class CruithnePressed extends MouseAdapter{ 331 public void mousePressed(MouseEvent e){ 332 //Button Pressed 333 if (objects[9].getDisplay()){ 334 objects[9].setDisplay(false); 335 }else{ 336 objects[9].setDisplay(true); 337 } 338 339 } 340 } 341 342 343 /** 344 * A little nested class which extends <code>MouseAdapter</code>. 345 * Listens to button presses on the main GUI. 346 * Switches the Applet between Pause and Run modus 347 */ 348 class PausePressed extends MouseAdapter{ 349 public void mousePressed(MouseEvent e){ 350 //Button Pressed 351 if(screenOne.pause == false){ 352 screenOne.pause = true; 353 }else{ 354 screenOne.pause = false; 355 screenOne.repaint(); 356 } 357 } 358 } 359 360 361 /** 362 * A little nested class which extends <code>MouseAdapter</code>. 363 * Listens to button presses on the main GUI. 364 * Will display selected orbits if pressed. 365 */ 366 class WritePressed extends MouseAdapter{ 367 public void mousePressed(MouseEvent e){ 368 //Button Pressed 369 if(screenOne.write == false){ 370 screenOne.write = true; 371 }else{ 372 screenOne.write = false; 373 } 374 } 375 } 376 377 /** 378 * A little nested class which extends <code>MouseAdapter</code>. 379 * Listens to button presses on the main GUI. 380 * Deletes the so far collected orbit data (history of all past positions). 381 * Primarily used to free up some memory and to accelerate the applet. 382 */ 383 class ClearPressed extends MouseAdapter{ 384 public void mousePressed(MouseEvent e){ 385 //Button Pressed 386 if(screenOne.view == 1){ 387 oldDataH.clear(); 388 }else if(screenOne.view == 2){ 389 oldData.clear(); 390 }else if(screenOne.view == 3){ 391 oldSecondMoon.clear(); 392 oldDataH.clear(); 393 oldData.clear(); 394 }else{ 395 oldCoRotational.clear(); 396 } 397 398 399 400 } 401 } 402 403 /** 404 * A little nested class which extends <code>MouseAdapter</code>. 405 * Listens to button presses on the main GUI. 406 * Allows to switch between the different view options of the simulation. 407 */ 408 class HelioPressed extends MouseAdapter{ 409 public void mousePressed(MouseEvent e){ 410 //Button Pressed 411 //oldDataH.clear(); 412 //oldData.clear(); 413 if(screenOne.view == 1){ 414 screenOne.view = 2; 415 }else if(screenOne.view == 2){ 416 screenOne.view = 3; 417 }else if(screenOne.view == 3){ 418 screenOne.view = 4; 419 }else{ 420 screenOne.view = 1; 421 } 422 423 } 424 } 425 426 /** 427 * A little nested class which extends <code>MouseAdapter</code>. 428 * Listens to button presses on the main GUI. 429 * Allows to change cruithnes velocities and mass. 430 */ 431 class MomentumChange extends MouseAdapter{ 432 public void mousePressed(MouseEvent e){ 433 screenOne.changeMomentum = true; 434 435 } 436 } 437 438 /** 439 * A little nested class which extends <code>MouseAdapter</code>. 440 * Listens to button presses on the main GUI. 441 * Allows to import cruithnes velocities and mass. 442 */ 443 class ImportUpdatedMomentum extends MouseAdapter{ 444 public void mousePressed(MouseEvent e){ 445 screenOne.now = screenOne.changer.getUpdatedVelocities(); 446 objects[9].setM(screenOne.changer.getUpdatedMass()); 447 screenOne.changer.terminate(); 448 screenOne.pause = false; 449 screenOne.repaint(); 450 451 452 453 } 454 } 455 456 457 458 459 460 461 /** 462 * A nested class which extends <code>JPanel</code> and implements <code>Runnable</code>. 463 * Used to create the a painting area in which the planets and their orbits will be displayed. 464 * Runnable was implemented to use different threads for drawing orbits and calculating 465 * new data, but it was so far not necessary to use it due to the "double buffer" option 466 * on Swing grafik components. 467 */ 468 class ScreenOne extends JPanel implements Runnable{ 469 /** 470 * Will hold the updated coordinates and velocities of all space objects after integration. 471 */ 472 PointN now; 473 /** 474 * A linear correction factor that scalls down the distance between planets to a few pixel. 475 */ 476 double distPerPixel; 477 /** 478 * The horizontal center of the display panel on which the planets and orbits will be drawn (a x coordinate). 479 */ 480 int middleX; 481 /** 482 * The vertical center of the display panel on which the planets and orbits will be drawn (a x coordinate). 483 */ 484 int middleY; 485 int middleZ; 486 /** 487 * Number of earth days that that the simulations is running so far. 488 */ 489 int days = 0; 490 /** 491 * Holding different colors for differnet space objects. 492 */ 493 Color[] colours = new Color[10]; 494 /** 495 * If true, then the simulations is in Pause mode. 496 */ 497 boolean pause = false; 498 /** 499 * If true, then the orbits are displayed. 500 */ 501 boolean write = false; 502 /** 503 * Can take three different integer values, each one corresponding 504 * to special view mode of the simulation. 505 * 1 = helio centric; 2 = geo centric; 3 = special second moon view; 506 */ 507 int view = 1; // can take 3 values: 1=helio; 2=geo; 3=coRot; 508 /** 509 * If true, then the the momentum change option comes up before the next integration step. 510 */ 511 boolean changeMomentum = false; 512 /** 513 * Needed to get the data out. 514 */ 515 FileWriter out; 516 /** 517 * Needed to get the data out. 518 */ 519 BufferedWriter myWriter; 520 /** 521 * Instance of MomentumChanger class which allows to change cruithnes momentum during the simulation 522 */ 523 MomentumChanger changer; 524 /** 525 * A counter which will keep the orbit data low. Only every 3 earth days 526 * the coordinates will be added to the vector holding old positons. So 527 * this integer will count to 3, data will be stored, and the reset to 0. 528 */ 529 int countTillThree = 1; 530 531 532 // the CONSTRUCTOR 533 /** 534 * Constructs a <code>ScreenOne</code> which will act as my drawing bord for planets and orbits. 535 * 536 * @param objects the array of Space Objects making up my Solar System. 537 * @param startPoint the initial positons and velocities of all Space Objects. 538 */ 539 public ScreenOne(SpaceObject[] objects, PointN startPoint){ 540 setBackground(Color.black); 541 542 now = startPoint; 543 544 colours[0] = Color.yellow; //sun 545 colours[1] = Color.gray; //mercury 546 colours[2] = Color.orange; //venus 547 colours[3] = Color.blue; //earth 548 colours[4] = Color.red; //mars 549 colours[5] = Color.orange; //juptier 550 colours[6] = Color.cyan; //saturn 551 colours[7] = Color.green; //uranus 552 colours[8] = Color.blue; //neptun 553 colours[9] = Color.white; //cruithne 554 555 556 } 557 /** 558 * A little method to calculate the scaling factor for drawing the planets. 559 * It will update the <code>distPerPixel</code> field in <code>ScreenOne</code>. 560 * @param w the width of the ScreenOne I am drawing onto. It's size is defind by layout managers. 561 */ 562 public void scaling(){ 563 // this is a scalling for the inner 8 planets 564 // such that neptunes orbit will max. screensize 565 double neptuneDistance = 4495.1*Math.pow(10,9); 566 int scale = scaleSlider.getValue(); 567 middleX = getWidth()/2; 568 middleY = getHeight()*4/10; 569 middleZ = getHeight()*9/10; 570 if (middleX >= middleY){ 571 distPerPixel = neptuneDistance/((middleY - 10)*scale); 572 }else{ 573 distPerPixel = neptuneDistance/((middleX - 10)*scale); 574 } 575 576 } 577 578 579 580 /** 581 * The Paint() method is the heart of the simulation. Carrying out all the drawing, saving old 582 * coordinates and creating new integrators (one per earth day) in a infinite loop. 583 * @param g the Graphics Object on which we paint. 584 */ 585 586 public void paint(Graphics g){ 587 //can do the scaling calc now, as I only know now the window size 588 scaling(); 589 590 super.paint(g); 591 592 double xEarth = now.coordinate(3*6+0); 593 double yEarth = now.coordinate(3*6+1); 594 double zEarth = now.coordinate(3*6+2); 595 // stuff for the co rotational view 596 double thetaEarth = Math.atan2(yEarth,xEarth); // result in range -PI to +PI 597 if (thetaEarth < 0.0) 598 thetaEarth = thetaEarth + 2*Math.PI; 599 600 601 for (int i = 0; i < objects.length; i++){ 602 double x = now.coordinate(i*6+0); 603 double y = now.coordinate(i*6+1); 604 double z = now.coordinate(i*6+2); 605 606 607 if (countTillThree == 3){ // this is data collection for orbit display 608 oldDataH.add(new Double(x)); 609 oldDataH.add(new Double(y)); 610 oldDataH.add(new Double(z)); 611 612 oldData.add(new Double(x - xEarth)); 613 oldData.add(new Double(y - yEarth)); 614 oldData.add(new Double(z - zEarth)); 615 if (i == 9){ //cruithne: special vectors to store special views 616 oldSecondMoon.add(new Double(x-xEarth)); 617 oldSecondMoon.add(new Double(y-yEarth)); 618 oldSecondMoon.add(new Double(z-zEarth)); 619 double r = Math.sqrt(x*x+y*y); 620 double theta = Math.atan2(y,x); 621 if (theta < 0.0) 622 theta = theta + 2*Math.PI; 623 624 theta = theta - thetaEarth; 625 double xCoRot = r*Math.cos(theta); 626 double yCoRot = r*Math.sin(theta); 627 628 oldCoRotational.add(new Double(xCoRot)); 629 oldCoRotational.add(new Double(yCoRot)); 630 oldCoRotational.add(new Double(z)); 631 632 } 633 634 } 635 636 637 if (view == 1){ //helio centric 638 g.setColor(Color.yellow); 639 g.fillOval(middleX-2, middleY-2, 4, 4); 640 g.fillOval(middleX-2, middleZ-2, 4, 4); 641 g.setColor(Color.white); 642 g.drawString("Days: "+days, 8, 12); 643 g.drawString("Heli centric view", 8, 22); 644 645 x = x/distPerPixel; 646 y = y/distPerPixel; 647 z = z/distPerPixel; 648 649 int xx = middleX + (int)x; // adapt cordinates 650 int yy = middleY + (int)y; 651 int zz = middleZ + (int)z; 652 653 g.setColor(colours[i]); 654 g.fillOval(xx-2, yy-2, 4, 4); 655 g.fillOval(xx-2, zz-2, 4, 4); 656 657 658 } 659 if (view == 2){ // this is GEO CENTRIC 660 g.setColor(Color.blue); 661 g.fillOval(middleX-2, middleY-2, 4, 4); 662 g.fillOval(middleX-2, middleZ-2, 4, 4); 663 g.setColor(Color.white); 664 g.drawString("Days: "+days, 8, 12); 665 g.drawString("Geo centric view", 8, 22); 666 667 if(i != 3){ // this excludes earth, is i have draw it manually already 668 669 x = x - xEarth; 670 y = y - yEarth; 671 z = z - zEarth; 672 673 x = x/(distPerPixel); 674 y = y/(distPerPixel); 675 z = z/(distPerPixel); 676 677 int xx = middleX + (int)x; // adapt coordinates 678 int yy = middleY + (int)y; 679 int zz = middleZ + (int)z; 680 681 g.setColor(colours[i]); 682 g.fillOval(xx-2, yy-2, 4, 4); 683 g.fillOval(xx-2, zz-2, 4, 4); 684 } 685 686 687 } 688 689 690 if (view == 3){ // this is the special moon view 691 if (i == 9){ 692 g.setColor(Color.white); 693 g.drawString("Days: "+days, 8, 12); 694 g.drawString("Earth's second moon view", 8, 22); 695 //sun 696 g.setColor(Color.yellow); 697 g.fillOval(middleX-2, middleY-2, 4, 4); 698 g.fillOval(middleX-2, middleZ-2, 4, 4); 699 //earth 700 //double d = Math.sqrt(xEarth*xEarth + yEarth*yEarth); 701 //d = d/(distPerPixel); 702 //adapt coordinates 703 int ex = (int) (xEarth/distPerPixel); 704 int ey = (int) (yEarth/distPerPixel); 705 int ez = (int) (zEarth/distPerPixel); 706 707 g.setColor(Color.blue); 708 g.fillOval(middleX+ex-2, middleY+ey-2, 4, 4); 709 g.fillOval(middleX+ex-2, middleZ+ez-2, 4, 4); 710 //cruithne 711 x = (x)/(distPerPixel); 712 y = (y)/(distPerPixel); 713 z = (z)/(distPerPixel); 714 g.setColor(Color.white); 715 g.fillOval((int)(middleX+x-2), (int)(middleY+y-2), 4, 4); 716 g.fillOval((int)(middleX+x-2), (int)(middleZ+z-2), 4, 4); 717 // draw history lines if "write" is pressed 718 719 } 720 } 721 if (view == 4){ //Co Rotational frame 722 g.setColor(Color.yellow); 723 g.fillOval(middleX-2, middleY-2, 4, 4); 724 g.fillOval(middleX-2, middleZ-2, 4, 4); 725 g.setColor(Color.white); 726 g.drawString("Days: "+days, 8, 12); 727 g.drawString("Co Rotational view", 8, 22); 728 729 double r = Math.sqrt(x*x+y*y); 730 double theta = Math.atan2(y,x); 731 if (theta < 0.0) 732 theta = theta + 2*Math.PI; 733 734 theta = theta - thetaEarth; 735 x = r*Math.cos(theta); 736 y = r*Math.sin(theta); 737 738 x = x/distPerPixel; 739 y = y/distPerPixel; 740 z = z/distPerPixel; 741 742 int xx = middleX + (int)x; // adapt cordinates 743 int yy = middleY + (int)y; 744 int zz = middleZ + (int)z; 745 746 g.setColor(colours[i]); 747 g.fillOval(xx-2, yy-2, 4, 4); 748 g.fillOval(xx-2, zz-2, 4, 4); 749 750 751 } 752 } 753 // draw history lines if "write" is pressed for the helio centric view 754 if (write && view == 1){ //write 755 int length = oldDataH.size(); 756 int sectionLength = (objects.length)*3; 757 int numberOfSections = length/sectionLength; 758 for(int j = 0; j < (numberOfSections-1); j++){ 759 for (int i = 1; i < objects.length; i++){ 760 if(objects[i].getDisplay()){ 761 g.setColor(colours[i]); 762 // get start point of line 763 double x = ((Double) oldDataH.get(3*i + j*sectionLength)).doubleValue(); 764 double y = ((Double) oldDataH.get(3*i+1+j*sectionLength)).doubleValue(); 765 double z = ((Double) oldDataH.get(3*i+2+j*sectionLength)).doubleValue(); 766 767 x = x/(distPerPixel); 768 y = y/(distPerPixel); 769 z = z/(distPerPixel); 770 771 g.fillRect((int)x+middleX, (int)y+middleY, 1, 1); 772 g.fillRect((int)x+middleX, (int)z+middleZ, 1, 1); 773 } 774 } 775 } 776 } 777 // draw history lines if "write" is pressed for the geo centric view 778 if (write && view == 2){ 779 int length = oldData.size(); 780 int sectionLength = (objects.length)*3; 781 int numberOfSections = length/sectionLength; 782 783 for(int j = 0; j < (numberOfSections-1); j++){ 784 for (int i = 0; i < objects.length; i++){ 785 if(i != 3 && objects[i].getDisplay()){ // the unequal 3 is to skip earth 786 g.setColor(colours[i]); 787 788 double x = ((Double) oldData.get(3*i + j*sectionLength)).doubleValue(); 789 double y = ((Double) oldData.get(3*i+1+j*sectionLength)).doubleValue(); 790 double z = ((Double) oldData.get(3*i+2+j*sectionLength)).doubleValue(); 791 x = x/(distPerPixel); 792 y = y/(distPerPixel); 793 z = z/(distPerPixel); 794 g.fillRect((int)x+middleX, (int)y+middleY, 1, 1); 795 g.fillRect((int)x+middleX, (int)z+middleZ, 1, 1); 796 797 } 798 } 799 } 800 } 801 //special second moon view 802 if (write && view == 3){ 803 int length = oldSecondMoon.size(); 804 int numberOfSections = length/3; 805 for(int j = 0; j < (numberOfSections-1); j++){ 806 807 g.setColor(Color.red); 808 double x = ((Double) oldSecondMoon.get(3*j+0)).doubleValue(); 809 double y = ((Double) oldSecondMoon.get(3*j+1)).doubleValue(); 810 double z = ((Double) oldSecondMoon.get(3*j+2)).doubleValue(); 811 x = x/(distPerPixel); 812 y = y/(distPerPixel); 813 z = z/(distPerPixel); 814 815 int ex = (int) (xEarth/distPerPixel); 816 int ey = (int) (yEarth/distPerPixel); 817 int ez = (int) (zEarth/distPerPixel); 818 819 g.fillRect((int)x+ex+middleX, (int)y+ey+middleY, 1, 1); 820 g.fillRect((int)x+ex+middleX, (int)z+ez+middleZ, 1, 1); 821 822 } 823 length = oldDataH.size(); 824 int sectionLength = (objects.length)*3; 825 numberOfSections = length/sectionLength; 826 for(int j = 0; j < (numberOfSections-1); j++){ 827 for (int i = 3; i <= 9; i=i+6){ //only earth and cruithne 828 if(objects[i].getDisplay()){ 829 g.setColor(colours[i]); 830 // get start point of line 831 double x = ((Double) oldDataH.get(3*i + j*sectionLength)).doubleValue(); 832 double y = ((Double) oldDataH.get(3*i+1+j*sectionLength)).doubleValue(); 833 double z = ((Double) oldDataH.get(3*i+2+j*sectionLength)).doubleValue(); 834 835 x = x/(distPerPixel); 836 y = y/(distPerPixel); 837 z = z/(distPerPixel); 838 839 g.fillRect((int)x+middleX, (int)y+middleY, 1, 1); 840 g.fillRect((int)x+middleX, (int)z+middleZ, 1, 1); 841 } 842 } 843 } 844 } 845 // special co rotating view 846 if (write && view == 4){ 847 int length = oldCoRotational.size(); 848 int sectionLength = 3; // only x/y/z coordinates of cruithne 849 int numberOfSections = length/sectionLength; 850 for(int j = 0; j < numberOfSections; j++){ 851 if(objects[9].getDisplay()){ 852 g.setColor(colours[9]); 853 854 double x = ((Double) oldCoRotational.get(j*sectionLength)).doubleValue(); 855 double y = ((Double) oldCoRotational.get(1+j*sectionLength)).doubleValue(); 856 double z = ((Double) oldCoRotational.get(2+j*sectionLength)).doubleValue(); 857 858 x = x/(distPerPixel); 859 y = y/(distPerPixel); 860 z = z/(distPerPixel); 861 862 g.fillRect((int)x+middleX, (int)y+middleY, 1, 1); 863 g.fillRect((int)x+middleX, (int)z+middleZ, 1, 1); 864 } 865 } 866 } 867 868 869 870 871 // momentum change of cruithne 872 if (changeMomentum){ 873 pause = true; 874 // get cruithnes mass 875 double m = objects[9].getM(); 876 // bring up a new window 877 changer = new MomentumChanger(now, m); 878 changer.setVisible(true); 879 changer.repaint(); 880 881 changeMomentum = false; 882 } 883 884 // watch the free memory of the machine and clear the old 885 // orbit data if I am short on memory 886 Runtime r = Runtime.getRuntime(); 887 long freeMemory = r.freeMemory(); 888 if (freeMemory <= 102400){ 889 oldSecondMoon.clear(); 890 oldDataH.clear(); 891 oldData.clear(); 892 oldCoRotational.clear(); 893 System.gc(); 894 895 } 896 897 898 // make another integrator, for another day and increase the number of days by one. 899 SolarIntegrator integ = new SolarIntegrator(objects, 0.0, 86400.0, now, 7); 900 if(pause == false){ 901 now = (PointN) integ.integrate(); 902 days = days + 1; 903 countTillThree++; 904 905 if (countTillThree == 4) 906 countTillThree = 1; 907 908 repaint(); 909 910 }else{ 911 g.setColor(Color.white); 912 g.drawString("SIMULATION PAUSED !!!", 38, 84); 913 } 914 915 } 916 917 // little method to calc the distance between the current object and an other space object 918 /** 919 * calculates the distance of a <code>SpaceObject</code> s from a certain position in 3D. 920 * @param s a <code>SpaceObject</code>. 921 * @param x cartesian x coordinate of a point in 3D. 922 * @param y cartesian y coordinate of a point in 3D. 923 * @param z cartesian z coordinate of a point in 3D. 924 * @return the distace beetween the <code>SpaceObject</code> s and the point in 3D. 925 */ 926 public double getDistance(SpaceObject s, double x, double y, double z){ 927 PointN pos = s.getC(); 928 double sx = pos.coordinate(0); 929 double sy = pos.coordinate(1); 930 double sz = pos.coordinate(2); 931 double xx = sx-x; 932 double yy = sy-y; 933 double zz = sz-z; 934 return Math.sqrt((Math.pow(xx, 2) + Math.pow(yy, 2) + Math.pow(zz, 2))); 935 } 936 937 938 /** 939 * not needed as it turned out that I don't need seperate Threads 940 */ 941 public void run(){ 942 } 943 } 944 } 945 946 947 948 949 950 951 952 953 954