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
  • 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));
    }
Tagged with: