Advertisement
Grey_Hugentobler

Gravity Applet 1.4

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