Posted By

jamessiene on 10/10/10


Tagged

javascript canvas html5 gravity


Versions (?)

Gravity


 / Published in: JavaScript
 

It's gravity

  1. <!doctype html>
  2. <HTML>
  3. <head>
  4. <title>Gravity!</title>
  5. <style type = "text/css">
  6. h1{
  7. color:rgb(255,255,255);
  8. }
  9. body{
  10. background-color:rgb(0,0,0);
  11. }
  12. plot_surf{
  13. background-color:rgb(0,0,0);
  14. }
  15. </style>
  16. <script type = "text/javascript">
  17. /*
  18.   @James Siene - September 28, 2010
  19.   - This program simulates what gravity might look like on some
  20.   particles in space. The gravity has been intensified to
  21.   scale with the programs display settings - its made to look nice
  22.   and its NOT 100% accurate with real gravity, its an approximation
  23.   */
  24. // For drawing to the Canvas object
  25. var canvas;
  26. var ctx;
  27. var imgLight;
  28.  
  29. // The universal constants
  30. var kNumPlanets = 10;
  31. var kMaxMass = 1000;
  32. var kSolarMass = 30000;
  33. var kGravity = 0.05;
  34. var kFps = 50;
  35. var kGenesisVelocity = 20.0;
  36. var kTimestep = .5;
  37.  
  38. var kUniverseDepth;
  39.  
  40. var camera
  41.  
  42. function Vector (nx, ny, nz) {
  43. this.x = nx;
  44. this.y = ny;
  45. this.z = nz;
  46. this.magnitude = function(){
  47. return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
  48. }
  49. this.add = function(rhs){
  50. return new Vector(this.x + rhs.x, this.y + rhs.y, this.z + rhs.z);
  51. }
  52. this.sub = function(rhs){
  53. return new Vector(this.x - rhs.x, this.y - rhs.y, this.z - rhs.z);
  54. }
  55. this.div = function(num){
  56. return new Vector(this.x / num, this.y / num, this.z / num);
  57. }
  58. this.mul = function(num){
  59. return new Vector(this.x * num, this.y * num, this.z * num);
  60. }
  61. this.distance = function(rhs){
  62. return Math.sqrt((rhs.x - this.x)^2 + (rhs.y - this.y)^2);
  63. }
  64. }
  65.  
  66. function Planet(newMass, isSolarObject) {
  67. this.pos = new Vector(0, 0, 0);
  68. this.vel = new Vector(0, 0, 0);
  69. this.acc = new Vector(0, 0, 0);
  70. this.mass = newMass;
  71. this.isSolar = isSolarObject;
  72.  
  73. this.draw = function(){
  74. var size = Math.sqrt(this.mass) * (this.pos.z / camera.z);
  75.  
  76. if (size < 2)
  77. size = 2;
  78.  
  79. // double size to (since it's a radius, and we need a diameter)
  80. var halfSize = size;
  81. size *= 2;
  82.  
  83. ctx.drawImage(imgLight,
  84. this.pos.x - halfSize,
  85. this.pos.y - halfSize,
  86. size,
  87. size);
  88. }
  89.  
  90. this.updateVelocity = function(){
  91. this.vel = this.vel.add(this.acc);
  92. }
  93.  
  94. this.updatePosition = function() {
  95. this.pos = this.pos.add(this.vel);
  96. }
  97.  
  98. this.updateAcceleration = function(otherPlanet) {
  99.  
  100. var posDiff = otherPlanet.pos.sub(this.pos);
  101. var tDiff = Math.sqrt(posDiff.x * posDiff.x + posDiff.y * posDiff.y + posDiff.z * posDiff.z);
  102.  
  103. var force = kGravity * (otherPlanet.mass) / (tDiff * tDiff);
  104.  
  105. return new Vector(posDiff.x * force, posDiff.y * force, posDiff.z * force);
  106. }
  107. }
  108.  
  109. var planets = new Array();
  110.  
  111. function init(){
  112. //Create canvas object
  113. canvas = document.getElementById("plot_surf");
  114. ctx = canvas.getContext("2d");
  115.  
  116. imgLight = new Image();
  117. imgLight.src = "images/light.png";
  118.  
  119. kUniverseDepth = Math.sqrt(canvas.width * canvas.height);
  120.  
  121. camera = new Vector(canvas.width / 2, canvas.height / 2, kUniverseDepth);
  122.  
  123.  
  124. // Center Planet (Solar Object)
  125. planets[0] = new Planet(kSolarMass, true);
  126. planets[0].pos = new Vector(canvas.width / 2, canvas.height / 2, kUniverseDepth / 2);
  127.  
  128. for (var curPlanet = 1; curPlanet < kNumPlanets; curPlanet++){
  129. planets[curPlanet] = new Planet((kMaxMass / 4) + Math.floor(Math.random() * (kMaxMass * 0.75)),false);
  130.  
  131. planets[curPlanet].pos.x = Math.floor(Math.cos((curPlanet / kNumPlanets) * Math.PI * 2) * (canvas.width / 2)) + canvas.width / 2;
  132. planets[curPlanet].pos.y = Math.floor(Math.sin((curPlanet / kNumPlanets) * Math.PI * 2) * (canvas.height / 2)) + canvas.height / 2;
  133. planets[curPlanet].pos.z = Math.floor(Math.random() * kUniverseDepth);
  134.  
  135. // Genesis velocity application
  136. planets[curPlanet].vel = new Vector(
  137. Math.floor(Math.random() * kGenesisVelocity) - (kGenesisVelocity / 2),
  138. Math.floor(Math.random() * kGenesisVelocity) - (kGenesisVelocity / 2),
  139. Math.floor(Math.random() * kGenesisVelocity) - (kGenesisVelocity / 2));
  140.  
  141. }
  142.  
  143. setInterval(doPhysics, 1000 / kFps);
  144. }
  145.  
  146. function doPhysics(){
  147. ctx.fillStyle="rgba(0,32,64,0.15)";
  148. ctx.fillRect(0, 0, canvas.width, canvas.height);
  149.  
  150. var relocVector = new Vector(0, 0, 0);
  151.  
  152. // First we'll update all of the planets accelerations
  153. for (var curPlanet in planets){
  154. var newAccel = new Vector(0, 0, 0);
  155. for (var otherPlanet in planets){
  156. if (curPlanet == otherPlanet)
  157. continue;
  158. newAccel = newAccel.add(planets[curPlanet].updateAcceleration(planets[otherPlanet]));
  159. }
  160. planets[curPlanet].acc = newAccel.div(kNumPlanets - 1);
  161. planets[curPlanet].updateVelocity();
  162. }
  163.  
  164. // Update all positions and get the offset of the solar object
  165. for (var curPlanet in planets){
  166. planets[curPlanet].updatePosition();
  167. if (planets[curPlanet].isSolar){
  168. relocVector = new Vector(
  169. planets[curPlanet].pos.x - (canvas.width / 2),
  170. planets[curPlanet].pos.y - (canvas.height / 2),
  171. planets[curPlanet].pos.z - (kUniverseDepth / 2));
  172. }
  173. }
  174.  
  175. relocVector = relocVector.div(8);
  176. planets.sort( function(a, b) { return a.pos.z - b.pos.z; });
  177.  
  178. for (var curPlanet in planets){
  179. // Move planets to center the solar object
  180. planets[curPlanet].pos = planets[curPlanet].pos.sub(relocVector);
  181. planets[curPlanet].draw();
  182. }
  183. }
  184.  
  185. </script>
  186. </head>
  187. <BODY onload="init();">
  188. <h1>Gravitational Model</h1>
  189. <canvas id="plot_surf" width=800 height=600></canvas>
  190. </BODY>
  191. </HTML>

Report this snippet  

You need to login to post a comment.