Advertisement
Grey_Hugentobler

Gravity Applet 1.3

Apr 4th, 2011
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.06 KB | None | 0 0
  1. //Code by Grey Hugentobler, March 31st, 2011 through April 3rd, 2011
  2.  
  3. package GravityApplet;
  4.  
  5. import java.awt.*;
  6. import java.util.*;
  7. import javax.swing.*;
  8.  
  9. public class GravityApplet extends JApplet implements Runnable {
  10. // G is the gravitational constant for the depicted universe
  11. public final float gravitationalConstant = 10;
  12. // t is the time since the simulation started
  13. public float time = 0;
  14. // dt is the increment of time we will advance the simulation by each step
  15. public final float deltaTime = .02f;
  16. // number of particles
  17. public int numberOfPlanets = 1000;
  18. // total mass of the system
  19. public float totalMass = 0;
  20. // inverse total mass of the system
  21. public float inverseTotalMass = 0;
  22. // center of mass of the system (mechanism to check that the net momentum is
  23. // in fact 0)
  24. public Vector centerOfMass = new Vector(0, 0);
  25.  
  26. // Mass stores the masses of the particles
  27. public ArrayList<Float> mass = new ArrayList<Float>();
  28. // inverseMass stores the inverse mass of each particle
  29. public ArrayList<Float> inverseMass = new ArrayList<Float>();
  30. // Position is a collection of the particles position Vectors
  31. public ArrayList<Vector> position = new ArrayList<Vector>();
  32. // Velocity is a collection of the particles velocity Vectors
  33. public ArrayList<Vector> velocity = new ArrayList<Vector>();
  34. // Acceleration is derived from NetForce using Mass.
  35. public ArrayList<Vector> acceleration = new ArrayList<Vector>();
  36. // Color is where the random colors are stored
  37. public ArrayList<Color> color = new ArrayList<Color>();
  38. // size stores the radius of each blob determined by mass
  39. public ArrayList<Float> size = new ArrayList<Float>();
  40.  
  41. // bufferGraphics is the Graphics buffer
  42. public Graphics bufferGraphics;
  43. // offscreen is the image being put together offscreen
  44. public Image offscreen;
  45. // dim is the current dimensions of the applet
  46. public Dimension dimensions;
  47.  
  48. // Show center or not
  49. public boolean showCenter = true;
  50. // Show time or not
  51. public boolean showTime = true;
  52. //Collide or not
  53. public boolean collisionOn = true;
  54. //show number of planets or not
  55. public boolean showNumberOfPlanets = true;
  56.  
  57. // Random number Generator
  58. public Random randomNumberGenerator = new Random();
  59.  
  60. // initiate Applet
  61. public void init() {
  62.  
  63. // standard deviation of the radius
  64. double sigmaR = 800;
  65. // standard deviation of the velocity
  66. double sigmaV = 100;
  67. // maximum mass
  68. float maxMass = 20;
  69. // minimum mass
  70. float minMass = 20;
  71.  
  72. // generate our distribution of particles
  73. for (int i = 0; i < numberOfPlanets; i++) {
  74. mass.add(i, minMass + (maxMass - minMass) * randomNumberGenerator.nextFloat());
  75. inverseMass.add(i, 1 / mass.get(i));
  76.  
  77. double random1 = sigmaR * randomNumberGenerator.nextGaussian();
  78. double random2 = 2 * Math.PI * randomNumberGenerator.nextDouble();
  79.  
  80. position.add( i, new Vector(Math.round(random1 * Math.sin(random2)), Math.round(random1 * Math.cos(random2))));
  81.  
  82. double random3 = sigmaV * randomNumberGenerator.nextGaussian();
  83. double random4 = 2 * Math.PI * randomNumberGenerator.nextDouble();
  84.  
  85. velocity.add(i, new Vector(Math.round(random3 * Math.sin(random4)), Math.round(random3 * Math.cos(random4))));
  86. acceleration.add(i, new Vector(0, 0));
  87.  
  88. float randomRed = randomNumberGenerator.nextFloat();
  89. float randomGreen = randomNumberGenerator.nextFloat();
  90. float randomBlue = randomNumberGenerator.nextFloat();
  91.  
  92. color.add(i, new Color(randomRed, randomGreen, randomBlue));
  93. size.add(i, (float) Math.sqrt(mass.get(i)));
  94. }
  95.  
  96. // correct for net momentum so that the system doesn't go off screen
  97. // create Vector representing net momentum
  98. Vector netMomentum = new Vector(0, 0);
  99.  
  100. // find total momentum and total mass
  101. for (int i = 0; i < numberOfPlanets; i++) {
  102. netMomentum = netMomentum.add(velocity.get(i).multiply(mass.get(i)));
  103. totalMass += mass.get(i);
  104. }
  105.  
  106. inverseTotalMass = 1 / totalMass;
  107.  
  108. // create vector representing net velocity
  109. Vector netVelocity = netMomentum.multiply(inverseTotalMass);
  110.  
  111. // modify all the velocities to cancel the net momentum
  112. for (int i = 0; i < numberOfPlanets; i++) {
  113. velocity.set(i, velocity.get(i).subtract(netVelocity));
  114. }
  115.  
  116. // intermediate between the properties of the particles and the center of mass
  117. Vector massPosition = new Vector(0, 0);
  118.  
  119. // add up the masses multiplied by the positions, the masses
  120. // have already been added up
  121. for (int i = 0; i < numberOfPlanets; i++) {
  122. massPosition = massPosition.add(position.get(i).multiply(mass.get(i)));
  123. }
  124.  
  125. // calculate the center of mass
  126. centerOfMass = massPosition.multiply(inverseTotalMass);
  127.  
  128. //shift all the planets so that the center of mass is the center
  129. for (int i = 0; i < numberOfPlanets; i++) {
  130. position.set(i, position.get(i).subtract(centerOfMass));
  131. }
  132.  
  133. // set the background to black, like space
  134. setBackground(Color.black);
  135.  
  136. // start a new thread to run the simulation
  137. Thread newThread;
  138. newThread = new Thread(this);
  139. newThread.start();
  140. }
  141.  
  142. public void paint(Graphics onscreenGraphics) {
  143. // change dimensions to the current size of the Applet
  144. dimensions = getSize();
  145.  
  146. // change the offscreen image to the dimensions of the Applet
  147. offscreen = createImage(dimensions.width, dimensions.height);
  148. bufferGraphics = offscreen.getGraphics();
  149.  
  150. // Draw all the little dots
  151. for (int i = 0; i < numberOfPlanets; i++) {
  152. bufferGraphics.setColor(color.get(i));
  153. 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)));
  154. }
  155.  
  156. // draw the time to the screen in a green serif bold font
  157. if (showTime) {
  158. bufferGraphics.setFont(new Font("serif", Font.BOLD, 12));
  159. bufferGraphics.setColor(Color.green);
  160. bufferGraphics.drawString(((int) time + ""), 0, bufferGraphics.getFont().getSize());
  161. }
  162.  
  163. //draw the number of Planets to the screen
  164. if (showNumberOfPlanets) {
  165. bufferGraphics.setFont(new Font("serif", Font.BOLD, 12));
  166. bufferGraphics.setColor(Color.green);
  167. bufferGraphics.drawString(((int) mass.size() + ""), 0, dimensions.height);
  168. }
  169.  
  170. // draw the center of mass
  171. if (showCenter) {
  172. bufferGraphics.setColor(Color.white);
  173. bufferGraphics.fillRect((int) (centerOfMass.x() - 1 + 0.5 * dimensions.width), (int) (centerOfMass.y() - 1 + 0.5 * dimensions.height), 2, 2);
  174. }
  175.  
  176. // draw it all to the applet
  177. onscreenGraphics.drawImage(offscreen, 0, 0, this);
  178. }
  179.  
  180. public void run() {
  181. while (true) {
  182. // check the system time
  183. long time1 = System.currentTimeMillis();
  184.  
  185. // create some storage variables to make the calculations
  186. // NetForce is where we store the force of all the particles on each individual particle
  187. Vector[] netForce = new Vector[numberOfPlanets];
  188. // Force is where we store the force of each particle on each of the other particles
  189. Vector[][] force = new Vector[numberOfPlanets][numberOfPlanets];
  190. // radius is the Vector that will point at the next planet
  191. Vector radius;
  192. // divisor is the magnitude of radius squared
  193. float radiusSquared;
  194.  
  195. if(collisionOn)
  196. {
  197. // size of the radiuses of the planets added together
  198. float addedSize;
  199.  
  200. for (int i = 0; i < numberOfPlanets; i++) {
  201. for (int j = i + 1; j < numberOfPlanets; j++) {
  202. radius = (position.get(j).subtract(position.get(i)));
  203. radiusSquared = radius.dot(radius);
  204. addedSize = size.get(i) + size.get(j);
  205. if (radiusSquared <= addedSize * addedSize) {
  206. 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))));
  207. 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))));
  208.  
  209. int red = Math.round((mass.get(i) * color.get(i).getRed() + mass.get(j) * color.get(j).getRed()) / (mass.get(i) + mass.get(j)));
  210. int green = Math.round((mass.get(i) * color.get(i).getGreen() + mass.get(j) * color.get(j).getGreen()) / (mass.get(i) + mass.get(j)));
  211. int blue = Math.round((mass.get(i) * color.get(i).getBlue() + mass.get(j) * color.get(j).getBlue()) / (mass.get(i) + mass.get(j)));
  212.  
  213. color.set(i, new Color(red, green, blue));
  214. mass.set(i, mass.get(i) + mass.get(j));
  215. inverseMass.set(i, 1 / mass.get(i));
  216. size.set(i, ((float) Math.sqrt(mass.get(i))));
  217. mass.remove(j);
  218. inverseMass.remove(j);
  219. position.remove(j);
  220. velocity.remove(j);
  221. acceleration.remove(j);
  222. color.remove(j);
  223. size.remove(j);
  224. numberOfPlanets--;
  225. j--;
  226. }
  227. }
  228. }
  229. }
  230.  
  231. // find all the forces of each planet on each other planet
  232. for (int i = 0; i < numberOfPlanets; i++) {
  233. for (int j = numberOfPlanets - 1; j >= i; j--) {
  234. radius = (position.get(i).subtract(position.get(j)));
  235. radiusSquared = radius.dot(radius);
  236. if (radiusSquared <= .01) {
  237. force[i][j] = new Vector(0, 0);
  238. } else {
  239. force[i][j] = radius.multiply(-gravitationalConstant * mass.get(i) * mass.get(j) / radiusSquared);
  240. }
  241. force[j][i] = force[i][j].negative();
  242. }
  243. }
  244.  
  245. // set the net force to zero
  246. for (int i = 0; i < numberOfPlanets; i++) {
  247. netForce[i] = new Vector(0, 0);
  248. }
  249.  
  250. // sum up the forces to find the total force
  251. for (int i = 0; i < numberOfPlanets; i++) {
  252. for (int j = 0; j < numberOfPlanets; j++) {
  253. netForce[i] = netForce[i].add(force[i][j]);
  254. }
  255. }
  256.  
  257. // convert force to acceleration
  258. for (int i = 0; i < numberOfPlanets; i++) {
  259. acceleration.set(i, netForce[i].multiply(inverseMass.get(i)));
  260. }
  261.  
  262. // integrate the position and velocity
  263. for (int i = 0; i < numberOfPlanets; i++) {
  264. position.set(i, position.get(i).add(velocity.get(i).multiply(deltaTime)));
  265. velocity.set(i, velocity.get(i).add(acceleration.get(i).multiply(deltaTime)));
  266. }
  267.  
  268. // increment the time variable
  269. if (showTime) {
  270. time += deltaTime;
  271. }
  272.  
  273. if (showCenter) {
  274. // intermediate between the properties of the particles and the center of mass
  275. Vector massPosition = new Vector(0, 0);
  276.  
  277. // add up the masses multiplied by the positions, the masses have already been added up
  278. for (int i = 0; i < numberOfPlanets; i++) {
  279. massPosition = massPosition.add(position.get(i).multiply(mass.get(i)));
  280. }
  281.  
  282. // calculate the center of mass
  283. centerOfMass = massPosition.multiply(inverseTotalMass);
  284. }
  285.  
  286. // check the systme time again
  287. long time2 = System.currentTimeMillis();
  288. //find out how much time we have used
  289. int timeUsed = (int) (time2 - time1);
  290. //figure out how much time is left to use
  291. int timeRemaining = (int) (1000 * deltaTime) - timeUsed;
  292. //if we have used up our time just move on
  293. if (timeRemaining < 0) {
  294. timeRemaining = 0;
  295. }
  296. // sleep the thread until we are ready
  297. try {
  298. Thread.sleep(timeRemaining);
  299. } catch (InterruptedException e) {
  300. }
  301. repaint();
  302. }
  303. }
  304. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement