Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Code by Grey Hugentobler, March 31st, 2011 through April 3rd, 2011
- package GravityApplet;
- import java.awt.*;
- import java.util.*;
- import javax.swing.*;
- public class GravityApplet extends JApplet implements Runnable {
- // G is the gravitational constant for the depicted universe
- public final float gravitationalConstant = 10;
- // t is the time since the simulation started
- public float time = 0;
- // dt is the increment of time we will advance the simulation by each step
- public final float deltaTime = .02f;
- // number of particles
- public int numberOfPlanets = 1000;
- // total mass of the system
- public float totalMass = 0;
- // inverse total mass of the system
- public float inverseTotalMass = 0;
- // center of mass of the system (mechanism to check that the net momentum is
- // in fact 0)
- public Vector centerOfMass = new Vector(0, 0);
- // Mass stores the masses of the particles
- public ArrayList<Float> mass = new ArrayList<Float>();
- // inverseMass stores the inverse mass of each particle
- public ArrayList<Float> inverseMass = new ArrayList<Float>();
- // Position is a collection of the particles position Vectors
- public ArrayList<Vector> position = new ArrayList<Vector>();
- // Velocity is a collection of the particles velocity Vectors
- public ArrayList<Vector> velocity = new ArrayList<Vector>();
- // Acceleration is derived from NetForce using Mass.
- public ArrayList<Vector> acceleration = new ArrayList<Vector>();
- // Color is where the random colors are stored
- public ArrayList<Color> color = new ArrayList<Color>();
- // size stores the radius of each blob determined by mass
- public ArrayList<Float> size = new ArrayList<Float>();
- // bufferGraphics is the Graphics buffer
- public Graphics bufferGraphics;
- // offscreen is the image being put together offscreen
- public Image offscreen;
- // dim is the current dimensions of the applet
- public Dimension dimensions;
- // Show center or not
- public boolean showCenter = true;
- // Show time or not
- public boolean showTime = true;
- //Collide or not
- public boolean collisionOn = true;
- //show number of planets or not
- public boolean showNumberOfPlanets = true;
- // Random number Generator
- public Random randomNumberGenerator = new Random();
- // initiate Applet
- public void init() {
- // standard deviation of the radius
- double sigmaR = 800;
- // standard deviation of the velocity
- double sigmaV = 100;
- // maximum mass
- float maxMass = 20;
- // minimum mass
- float minMass = 20;
- // generate our distribution of particles
- for (int i = 0; i < numberOfPlanets; i++) {
- mass.add(i, minMass + (maxMass - minMass) * randomNumberGenerator.nextFloat());
- inverseMass.add(i, 1 / mass.get(i));
- double random1 = sigmaR * randomNumberGenerator.nextGaussian();
- double random2 = 2 * Math.PI * randomNumberGenerator.nextDouble();
- position.add( i, new Vector(Math.round(random1 * Math.sin(random2)), Math.round(random1 * Math.cos(random2))));
- double random3 = sigmaV * randomNumberGenerator.nextGaussian();
- double random4 = 2 * Math.PI * randomNumberGenerator.nextDouble();
- velocity.add(i, new Vector(Math.round(random3 * Math.sin(random4)), Math.round(random3 * Math.cos(random4))));
- acceleration.add(i, new Vector(0, 0));
- float randomRed = randomNumberGenerator.nextFloat();
- float randomGreen = randomNumberGenerator.nextFloat();
- float randomBlue = randomNumberGenerator.nextFloat();
- color.add(i, new Color(randomRed, randomGreen, randomBlue));
- size.add(i, (float) Math.sqrt(mass.get(i)));
- }
- // correct for net momentum so that the system doesn't go off screen
- // create Vector representing net momentum
- Vector netMomentum = new Vector(0, 0);
- // find total momentum and total mass
- for (int i = 0; i < numberOfPlanets; i++) {
- netMomentum = netMomentum.add(velocity.get(i).multiply(mass.get(i)));
- totalMass += mass.get(i);
- }
- inverseTotalMass = 1 / totalMass;
- // create vector representing net velocity
- Vector netVelocity = netMomentum.multiply(inverseTotalMass);
- // modify all the velocities to cancel the net momentum
- for (int i = 0; i < numberOfPlanets; i++) {
- velocity.set(i, velocity.get(i).subtract(netVelocity));
- }
- // intermediate between the properties of the particles and the center of mass
- Vector massPosition = new Vector(0, 0);
- // add up the masses multiplied by the positions, the masses
- // have already been added up
- for (int i = 0; i < numberOfPlanets; i++) {
- massPosition = massPosition.add(position.get(i).multiply(mass.get(i)));
- }
- // calculate the center of mass
- centerOfMass = massPosition.multiply(inverseTotalMass);
- //shift all the planets so that the center of mass is the center
- for (int i = 0; i < numberOfPlanets; i++) {
- position.set(i, position.get(i).subtract(centerOfMass));
- }
- // set the background to black, like space
- setBackground(Color.black);
- // start a new thread to run the simulation
- Thread newThread;
- newThread = new Thread(this);
- newThread.start();
- }
- public void paint(Graphics onscreenGraphics) {
- // change dimensions to the current size of the Applet
- dimensions = getSize();
- // change the offscreen image to the dimensions of the Applet
- offscreen = createImage(dimensions.width, dimensions.height);
- bufferGraphics = offscreen.getGraphics();
- // Draw all the little dots
- for (int i = 0; i < numberOfPlanets; i++) {
- bufferGraphics.setColor(color.get(i));
- bufferGraphics.fillOval((int) (position.get(i).x() - size.get(i) + 0.5*dimensions.width), (int) (position.get(i).y() - size.get(i) + 0.5 * dimensions.height), (int) (2 * size.get(i)), (int) (2 * size.get(i)));
- }
- // draw the time to the screen in a green serif bold font
- if (showTime) {
- bufferGraphics.setFont(new Font("serif", Font.BOLD, 12));
- bufferGraphics.setColor(Color.green);
- bufferGraphics.drawString(((int) time + ""), 0, bufferGraphics.getFont().getSize());
- }
- //draw the number of Planets to the screen
- if (showNumberOfPlanets) {
- bufferGraphics.setFont(new Font("serif", Font.BOLD, 12));
- bufferGraphics.setColor(Color.green);
- bufferGraphics.drawString(((int) mass.size() + ""), 0, dimensions.height);
- }
- // draw the center of mass
- if (showCenter) {
- bufferGraphics.setColor(Color.white);
- bufferGraphics.fillRect((int) (centerOfMass.x() - 1 + 0.5 * dimensions.width), (int) (centerOfMass.y() - 1 + 0.5 * dimensions.height), 2, 2);
- }
- // draw it all to the applet
- onscreenGraphics.drawImage(offscreen, 0, 0, this);
- }
- public void run() {
- while (true) {
- // check the system time
- long time1 = System.currentTimeMillis();
- // create some storage variables to make the calculations
- // NetForce is where we store the force of all the particles on each individual particle
- Vector[] netForce = new Vector[numberOfPlanets];
- // Force is where we store the force of each particle on each of the other particles
- Vector[][] force = new Vector[numberOfPlanets][numberOfPlanets];
- // radius is the Vector that will point at the next planet
- Vector radius;
- // divisor is the magnitude of radius squared
- float radiusSquared;
- if(collisionOn)
- {
- // size of the radiuses of the planets added together
- float addedSize;
- for (int i = 0; i < numberOfPlanets; i++) {
- for (int j = i + 1; j < numberOfPlanets; j++) {
- radius = (position.get(j).subtract(position.get(i)));
- radiusSquared = radius.dot(radius);
- addedSize = size.get(i) + size.get(j);
- if (radiusSquared <= addedSize * addedSize) {
- velocity.set(i, velocity.get(i).multiply(mass.get(i)).add(velocity.get(j).multiply(mass.get(j))).multiply(1 / (mass.get(i) + mass.get(j))));
- position.set(i, position.get(i).multiply(mass.get(i)).add(position.get(j).multiply(mass.get(j))).multiply(1 / (mass.get(i) + mass.get(j))));
- int red = Math.round((mass.get(i) * color.get(i).getRed() + mass.get(j) * color.get(j).getRed()) / (mass.get(i) + mass.get(j)));
- int green = Math.round((mass.get(i) * color.get(i).getGreen() + mass.get(j) * color.get(j).getGreen()) / (mass.get(i) + mass.get(j)));
- int blue = Math.round((mass.get(i) * color.get(i).getBlue() + mass.get(j) * color.get(j).getBlue()) / (mass.get(i) + mass.get(j)));
- color.set(i, new Color(red, green, blue));
- mass.set(i, mass.get(i) + mass.get(j));
- inverseMass.set(i, 1 / mass.get(i));
- size.set(i, ((float) Math.sqrt(mass.get(i))));
- mass.remove(j);
- inverseMass.remove(j);
- position.remove(j);
- velocity.remove(j);
- acceleration.remove(j);
- color.remove(j);
- size.remove(j);
- numberOfPlanets--;
- j--;
- }
- }
- }
- }
- // find all the forces of each planet on each other planet
- for (int i = 0; i < numberOfPlanets; i++) {
- for (int j = numberOfPlanets - 1; j >= i; j--) {
- radius = (position.get(i).subtract(position.get(j)));
- radiusSquared = radius.dot(radius);
- if (radiusSquared <= .01) {
- force[i][j] = new Vector(0, 0);
- } else {
- force[i][j] = radius.multiply(-gravitationalConstant * mass.get(i) * mass.get(j) / radiusSquared);
- }
- force[j][i] = force[i][j].negative();
- }
- }
- // set the net force to zero
- for (int i = 0; i < numberOfPlanets; i++) {
- netForce[i] = new Vector(0, 0);
- }
- // sum up the forces to find the total force
- for (int i = 0; i < numberOfPlanets; i++) {
- for (int j = 0; j < numberOfPlanets; j++) {
- netForce[i] = netForce[i].add(force[i][j]);
- }
- }
- // convert force to acceleration
- for (int i = 0; i < numberOfPlanets; i++) {
- acceleration.set(i, netForce[i].multiply(inverseMass.get(i)));
- }
- // integrate the position and velocity
- for (int i = 0; i < numberOfPlanets; i++) {
- position.set(i, position.get(i).add(velocity.get(i).multiply(deltaTime)));
- velocity.set(i, velocity.get(i).add(acceleration.get(i).multiply(deltaTime)));
- }
- // increment the time variable
- if (showTime) {
- time += deltaTime;
- }
- if (showCenter) {
- // intermediate between the properties of the particles and the center of mass
- Vector massPosition = new Vector(0, 0);
- // add up the masses multiplied by the positions, the masses have already been added up
- for (int i = 0; i < numberOfPlanets; i++) {
- massPosition = massPosition.add(position.get(i).multiply(mass.get(i)));
- }
- // calculate the center of mass
- centerOfMass = massPosition.multiply(inverseTotalMass);
- }
- // check the systme time again
- long time2 = System.currentTimeMillis();
- //find out how much time we have used
- int timeUsed = (int) (time2 - time1);
- //figure out how much time is left to use
- int timeRemaining = (int) (1000 * deltaTime) - timeUsed;
- //if we have used up our time just move on
- if (timeRemaining < 0) {
- timeRemaining = 0;
- }
- // sleep the thread until we are ready
- try {
- Thread.sleep(timeRemaining);
- } catch (InterruptedException e) {
- }
- repaint();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement