Commits

Jason S committed 9d28a9b

yay, added draw orbit

  • Participants
  • Parent commits 310cddd

Comments (0)

Files changed (2)

File demos/gravity1/gravity1.html

     var canvas = document.getElementById('gravity1-canvas');
     var gravity1 = new Gravity1Simulation();
     var fps = 20;
-    var i = 0;
+    var tick = 0;
     var k = 16;
     var dtsim = 1.0/k/fps;
     setInterval(function() {
+        ++tick;
         for (var i = 0; i < k; ++i)
             gravity1.update(dtsim);
         gravity1.draw(canvas);
+        var ctx = canvas.getContext('2d');
+        ctx.strokeStyle = '#ff0000';
+        gravity1.drawOrbitPath(canvas);
+        ctx.stroke();
     }, 1000/fps)
 }
 </script>

File demos/gravity1/gravity1.js

 function Gravity1Simulation()
 {
-    this.M1G = 0.5;
+    this.mu = 0.5;  // M * G
     this.minR = 0.05;
-    this.velpos = [0,0.7,0.5,0];
+    this.velpos = [0,0.55,0.5,0];
     this.solver = 'Trapezoidal';
     this.initialEnergy = this.getKineticEnergy() + this.getPotentialEnergy();
 }
     return result;
 }
 
-function dot(ctx,x,y,r)
+function dotpath(ctx,x,y,r)
 {
     ctx.beginPath();
     ctx.arc(x, y, r, 0, 2 * Math.PI, false);
         var r = Math.sqrt(vx[2]*vx[2] + vx[3]*vx[3]);
         // |a| = F/M2 = 1/M2*(M1*M2*G/r/r) = M1*G/r/r
         // a = -|a|*x/|x| = -|a|*x/r
-        var k = -this.M1G/r/r/r;
+        var k = -this.mu/r/r/r;
         return [k*vx[2],k*vx[3],vx[0],vx[1]]; 
     },
     update: function(dt)
             return weightedsum([1,dt/2,dt/2], [vx,dvxdt1,dvxdt2], 4);
         }
     },
+    getRadius: function() {
+        return Math.sqrt(sumsq(this.velpos[2],this.velpos[3]));
+    },
     getKineticEnergy: function() { return sumsq(this.velpos[0],this.velpos[1])/2; },
     getPotentialEnergy: function() {
-        var rsquared=sumsq(this.velpos[2],this.velpos[3]);
-        return this.M1G*(1.0/this.minR - 1.0/Math.sqrt(rsquared));
+        return this.mu*(1.0/this.minR - 1.0/this.getRadius());
     },    
+    getAngularMomentum: function() {
+        // r x v = rx*vy - ry*vx
+        return this.velpos[1]*this.velpos[2] - this.velpos[0]*this.velpos[3];
+    },
     draw: function(canvas)
     {
         var ctx = canvas.getContext('2d');
         ctx.fillRect(0,0,cw,ch);
         
         ctx.fillStyle = '#ffffff';        
-        dot(ctx, cw/2,ch/2,5);
+        dotpath(ctx, cw/2,ch/2,5);
         ctx.fill();        
 
-        dot(ctx,x1,y1,2);
+        dotpath(ctx,x1,y1,2);
         ctx.fill();  
         
         var e0=0.8 / this.initialEnergy;
         drawbar(ctx,cw-9,2,ch,2,pe);   
         ctx.fillStyle = '#8080ff';
         drawbar(ctx,cw-5,2,ch,2,ke+pe);     
-    }   
+    },
+    drawOrbitPath: function(canvas)
+    {
+        // based on http://ocw.mit.edu/courses/aeronautics-and-astronautics/16-346-astrodynamics-fall-2008/lecture-notes/lec_01.pdf
+        var ctx = canvas.getContext('2d');
+        var cw = canvas.width;
+        var ch = canvas.height;
+        var rmax = Math.min(cw,ch)/2;
+
+        var h = this.getAngularMomentum();
+        var r = this.getRadius();
+        var mu_e = [this.velpos[1]*h  - this.mu/r*this.velpos[2],
+                    -this.velpos[0]*h - this.mu/r*this.velpos[3]];
+                    
+        ctx.beginPath();
+        var pathcoords = [];
+        for (var th = 0; th < 1; th += 0.01)
+        {
+            var th_i = th * 2 * Math.PI;
+            var costh = Math.cos(th_i);
+            var sinth = Math.sin(th_i);
+            var r_i = h*h/(this.mu + (mu_e[0]*costh + mu_e[1]*sinth));
+            var rx = r_i*costh;
+            var ry = r_i*sinth;
+            var x = cw/2 + rmax*rx;
+            var y = ch/2 - rmax*ry;
+            pathcoords.push([th,r_i,rx,ry]);
+            if (th == 0)
+                ctx.moveTo(x,y);
+            else
+                ctx.lineTo(x,y);
+        }
+        return pathcoords;
+    }
 }