The title’s a mouth full but the problem is very interesting and not too hard to break down.
- Runge Kutta is a numerical method technique very usefull for solving ordinary differential equations on computers
- It keeps computational errors to a minimum and keeps your simulations using ordinary differential equations stable.
- Basic explanation of the method I’m using can be found here: http://en.wikipedia.org/wiki/Runge-Kutta_methods
- HTML5 is the new html specification currently being implemented by browsers that allows many new things including:
- Use of canvas objects (2D drawing on the web, see below)
- Websockets (persistent connections between clients and servers)
- Video and Audio
What I’ve done is use a combination of the html canvas tools with the runge kutta technique implemented in javascript to show two masses/objects orbiting eachother. You can do a bunch of neat things with this including processing orbits etc. Check it out:
Javascript code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | $(document).ready(function() { //get a reference to the canvas ctx = $('#canvas')[0].getContext("2d"); ax=100.0; ay=200.0; bx=200.0; by=100.0; adx=1; ady=1; bdx=-1; bdy=-1; time_step=1; setInterval(draw, 10); }); // runge kutta gravitational advance function f(p1,p2,dist){ var g=.05; return g*(1/dist^2)*((p2-p1)/dist); } function draw() { // stop iterating if they collide var dist=distance(ax,ay,bx,by); if(!dist<10){ k1_adx=f(ax,bx,dist); k2_adx=f(ax+time_step/2*k1_adx,bx,dist); k3_adx=f(ax+time_step/2*k2_adx,bx,dist); k4_adx=f(ax+time_step*k3_adx,bx,dist); adx+=time_step*(k1_adx+2*(k2_adx+k3_adx)+k4_adx)/6; k1_ady=f(ay,by,dist); k2_ady=f(ay+time_step/2*k1_ady,by,dist); k3_ady=f(ay+time_step/2*k2_ady,by,dist); k4_ady=f(ay+time_step*k3_ady,by,dist); ady+=time_step*(k1_ady+2*(k2_ady+k3_ady)+k4_ady)/6; k1_bdx=f(bx,ax,dist); k2_bdx=f(bx+time_step/2*k1_bdx,ax,dist); k3_bdx=f(bx+time_step/2*k2_bdx,ax,dist); k4_bdx=f(bx+time_step*k3_bdx,ax,dist); bdx+=time_step*(k1_bdx+2*(k2_bdx+k3_bdx)+k4_bdx)/6; k1_bdy=f(by,ay,dist); k2_bdy=f(by+time_step/2*k1_bdy,ay,dist); k3_bdy=f(by+time_step/2*k2_bdy,ay,dist); k4_bdy=f(by+time_step*k3_bdy,ay,dist); bdy+=time_step*(k1_bdy+2*(k2_bdy+k3_bdy)+k4_bdy)/6; } else{ console.log("stop moving\n"); } // update positions ax += adx; ay += ady; bx += bdx; by += bdy; ctx.clearRect(0,0,1000,800); ctx.beginPath(); ctx.arc(ax, ay, 10, 0, Math.PI*2, true); ctx.closePath(); ctx.fill(); ctx.beginPath(); ctx.arc(bx, by, 10, 0, Math.PI*2, true); ctx.closePath(); ctx.fill(); } function distance(x1,y1,x2,y2){ return Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2)); } |

