/* Orbit.java applet by Matt Mahoney. This animation simulates planets orbiting in 2-dimensional space, obeying Newton's law of gravity, with collisions. To create a planet, click in the blank area. The mass and size of the planet depends on how long the mouse is held down. If you move the mouse while pressed, the initial velocity of the planet will match that of the mouse. The display is centered around the first planet created. To change the "home planet", right click on it. There are 3 buttons at the top: Zoom In - magnify the display by a factor of 2. Zoom Out - opposite of zoom in. Clear - removes all planets and resets the zoom level. */ import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Orbit extends JApplet implements ActionListener { private Timer timer; private Display display; private JButton zoomin, zoomout, clear; private static final int N = 10000; // max number of planets private static final double DENSITY = 40.0; // area/mass private double[] x = new double[N], y = new double[N]; // positions private double[] dx = new double[N], dy = new double[N]; // velocities private double[] m = new double[N]; // masses private int n = 0; // number of planets, n <= N private double scale = 1.0; // viewing magnification private double xpos = 0, ypos = 0; // upper left corner position private int t = 0; // current time private int tstart = 0; // mouse down time private double xstart = 0, ystart = 0; // mouse down position private int homePlanet = 0; // Initialize public void init() { display = new Display(); JPanel topPanel = new JPanel(); topPanel.add(zoomin = new JButton("Zoom In")); topPanel.add(zoomout = new JButton("Zoom Out")); topPanel.add(clear = new JButton("Clear")); zoomin.addActionListener(this); zoomout.addActionListener(this); clear.addActionListener(this); add(display); add(topPanel, BorderLayout.NORTH); display.addMouseListener(display); timer = new Timer(30, this); timer.start(); } // Handle button press or timer events. public void actionPerformed(ActionEvent e) { // Zoom In if (e.getSource()==zoomin) { scale*=2; xpos+=getWidth()/(scale*2); ypos+=getHeight()/(scale*2); return; } // Zoom out if (e.getSource()==zoomout) { xpos-=getWidth()/(scale*2); ypos-=getHeight()/(scale*2); scale/=2; return; } // Clear if (e.getSource()==clear) { n = 0; scale = 1; xpos = ypos = 0; return; } // Timer event: First merge colliding planets for (int i=0; i 0) { r2 = Math.sqrt(r2*r2*r2)*.01; fx += m[j]*xd/r2; fy += m[j]*yd/r2; } } dx[i] += fx; dy[i] += fy; } } // Update positions for (int i=0; i