Commits

Jason S committed ecbbb3c

got keypress thrusters working

  • Participants
  • Parent commits b8a4cd2

Comments (0)

Files changed (2)

File demos/gravity1/gravity1.html

     var tick = 0;
     var k = 16;
     var dtsim = 1.0/k/fps;
+    var keymap = {37: 'left', 38: 'up', 39: 'right', 40: 'down'};
+    var keystate = {'up':false, 'down':false, 'left':false, 'right':false};
+    function modkey(keycode,isdown)
+    {
+        if (keycode in keymap)
+        {
+            keystate[keymap[keycode]] = isdown;
+            console.log(keystate);
+            return true;
+        }
+        else
+            return false;
+    }    
+    document.addEventListener('keydown',function(event) { if (modkey(event.keyCode, true)) { event.preventDefault(true); return false;} });
+    document.addEventListener('keyup',function(event) { if (modkey(event.keyCode, false)) {  event.preventDefault(true); return false;} });
+    function settextvalue(id,value)
+    {
+        document.getElementById(id).textContent = ''+value.toFixed(3);
+    }
+    function showStatistics(sim)
+    {
+        settextvalue('speed',sim.getSpeed());
+        settextvalue('radius',sim.getRadius());
+        settextvalue('angmomentum',sim.getAngularMomentum());
+        settextvalue('eccentricity',sim.getEccentricity());
+        var ke = sim.getKineticEnergy();
+        var pe = sim.getPotentialEnergy();
+        settextvalue('total energy',ke+pe);
+    }
     setInterval(function() {
         ++tick;
+        gravity1.thruster(keystate,k*dtsim);
         for (var i = 0; i < k; ++i)
             gravity1.update(dtsim);
         gravity1.draw(canvas);
         ctx.strokeStyle = '#ff0000';
         gravity1.drawOrbitPath(canvas);
         ctx.stroke();
+        showStatistics(gravity1);
     }, 1000/fps)
 }
 </script>
 </head>
 <body>
+    <div>
     <canvas id="gravity1-canvas" height="480" width="640" />
+    </div>
+    <div>
+        <p>Speed = <span id='speed'></span></p>
+        <p>Radius = <span id='radius'></span></p>
+        <p>Angular momentum = <span id='angmomentum'></span></p>
+        <p>Eccentricity = <span id='eccentricity'></span></p>
+        <p>Total energy = <span id='total energy'></span></p>
+    </div>
 </body>
 </html>

File demos/gravity1/gravity1.js

 {
     this.mu = 0.5;  // M * G
     this.minR = 0.09;
-    this.velpos = [0,1.2,0.5,0];
+    this.velpos = [0.4,-0.4,0.66,0.66];
     this.solver = 'Trapezoidal';
     this.initialEnergy = 1+this.getKineticEnergy() + this.getPotentialEnergy();
+    this.thrusterstrength = 0.05;
 }
 
 function weightedsum(A,x,len)
 
 function dotpath(ctx,x,y,r)
 {
-    ctx.beginPath();
     ctx.arc(x, y, r, 0, 2 * Math.PI, false);
 }
 function sumsq(x,y) { return x*x+y*y; }
         var f = function(vx) { return me.calcDerivative(vx); }
         this.velpos = S(this.velpos, f, dt);
     },
+    thruster: function(keymap, dt)
+    {
+        if (keymap.up)
+            this.velpos[1] += this.thrusterstrength * dt;
+        if (keymap.down)
+            this.velpos[1] -= this.thrusterstrength * dt;
+        if (keymap.right)
+            this.velpos[0] += this.thrusterstrength * dt;
+        if (keymap.left)
+            this.velpos[0] -= this.thrusterstrength * dt;
+    },
     solvers: { 
         'Euler': function(vx, f, dt)
         {
     getPotentialEnergy: function() {
         return this.mu*(-1.0/this.getRadius());
     },    
+    getSpeed: function() { return hypot(this.velpos[0],this.velpos[1]); },
     getAngularMomentum: function() {
         // r x v = rx*vy - ry*vx
         return this.velpos[1]*this.velpos[2] - this.velpos[0]*this.velpos[3];
     },
+    getEccentricity: function() {
+        var mu = this.mu;
+        var h = this.getAngularMomentum();
+        var r = this.getRadius();
+        var mu_e = [this.velpos[1]*h  - mu/r*this.velpos[2],
+                    -this.velpos[0]*h - mu/r*this.velpos[3]];
+        return hypot(mu_e[0],mu_e[1])/mu;     
+    },
     draw: function(canvas)
     {
         var ctx = canvas.getContext('2d');
         ctx.fillRect(0,0,cw,ch);
         
         ctx.fillStyle = '#ffffff';        
+        ctx.beginPath();
         dotpath(ctx, cw/2,ch/2,5);
         ctx.fill();        
 
+        ctx.beginPath();
         dotpath(ctx,x1,y1,2);
         ctx.fill();  
         
 
         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]];
-        var e = hypot(mu_e[0],mu_e[1])/this.mu;            
+        var mu = this.mu;
+        var mu_e = [this.velpos[1]*h  - mu/r*this.velpos[2],
+                    -this.velpos[0]*h - mu/r*this.velpos[3]];
+        var e = hypot(mu_e[0],mu_e[1])/mu;            
         ctx.beginPath();
-        var penup = true;
         var th_start = 0;
-        var th_stop = 1;
-        var done = false;
+        var th_stop = 2*Math.PI;
         if (e > 1)
         {
-            var rclosest = h*h/this.mu/(1+e);
+            var rclosest = h*h/mu/(1+e);
             var th_c = Math.atan2(mu_e[1],mu_e[0]);
             var th_d = Math.PI-Math.acos(1/e);
-            th_start = (th_c-th_d+0.00001)/2/Math.PI;
-            th_stop = (th_c+th_d-0.00001)/2/Math.PI;
+            th_start = th_c-th_d+0.00001;
+            th_stop = th_c+th_d-0.00001;
             var rc = rmax*rclosest*(1+1/(e-1));
             var rk = 2*rmax+rc;
             var cx = cw/2 + rc*Math.cos(th_c);
             ctx.lineTo(cx + rk*Math.cos(th_c+th_d),
                        cy - rk*Math.sin(th_c+th_d));
         }
+        else if (e > 0.05)
+        {
+            var th_c = Math.atan2(mu_e[1],mu_e[0]);
+            th_start = th_c - Math.PI;
+            th_stop = th_c + Math.PI;            
+        }
         th = th_start;
         
-        while (true)
+        function f(theta)
         {
-            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));
-            if (r_i < 0)
+            var costh = Math.cos(theta);
+            var sinth = Math.sin(theta);
+            var r_i = h*h/(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;
+            return [x,y];
+        }
+        var N = 16;
+        for (var i = 0; i <= N; ++i)
+        {   
+            var rho = i / N;
+            var rhowarp = rho - 0.04*Math.sin(2*Math.PI*rho);
+            var th_i = th_start + rhowarp*(th_stop-th_start);
+            var xy = f(th_i);
+            /*if (i == 0)
             {
-                penup = true;
-                break;
+                ctx.moveTo(xy[0],xy[1]);
+                dotpath(ctx,xy[0],xy[1],2);
             }
             else
-            {
-                var rx = r_i*costh;
-                var ry = r_i*sinth;
-                var x = cw/2 + rmax*rx;
-                var y = ch/2 - rmax*ry;
-                if (penup)
-                {
-                    ctx.moveTo(x,y);
-                    penup = false;
-                }
-                else
-                    ctx.lineTo(x,y);
-            }
-            
-            if (th >= th_stop)
-                break;
-            th += 0.05;
-            if (th > th_stop)
-                th = th_stop;
+                ctx.lineTo(xy[0],xy[1]);
+            if (i == N)*/
+                dotpath(ctx,xy[0],xy[1],2);
         }
     }
 }