html5碰撞小球模拟

这里根据动量守恒和能量守恒定理来计算小球的位置,从而模拟完全弹性碰撞下的小球运行轨迹。

html代码:

 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3   <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 5     <script class="jquery library" src="/js/sandbox/jquery/jquery-1.8.2.min.js" type="text/javascript"></script>
 6     <title>碰撞小球</title>
 7   </head>
 8     <body>
 9         <canvas id='box' width="300" height="300" style="border:2px; background:black;">
10      </canvas>
11   </body>
12 </html>

js代码:

  1 //get a random color to render the ball
  2 function getRandomColor(){
  3   return (function(m,s,c){
  4     return (c ? arguments.callee(m,s,c-1) : '#') +
  5       s[m.floor(m.random() * 16)]
  6   })(Math,'0123456789abcdef',5)
  7 }
  8 
  9 //get a random number between min and max
 10 function getRandomNumber(min, max) {
 11     return min + Math.ceil(Math.random() * (max - min));
 12 }
 13 
 14 var balls = [];
 15 var ballCount = 4;
 16 var boxLen = 300;
 17 
 18 function createBall() {
 19     var r = getRandomNumber(10,20);
 20     var ball = {
 21         m:r,
 22         r:r,
 23         x:getRandomNumber(0,boxLen-2*r),
 24         y:getRandomNumber(0,boxLen-2*r),
 25         vx:getRandomNumber(1,3),
 26         vy:getRandomNumber(1,3),
 27         color:getRandomColor()
 28     };
 29     return ball;
 30 }
 31 
 32 //test collision
 33 function checkCollision(b1, b2) {
 34     var dx = b1.x - b2.x;
 35     var dy = b1.y - b2.y;
 36     var dist = Math.ceil(Math.sqrt(dx * dx + dy * dy));
 37     return dist < b1.r + b2.r;
 38 }
 39 
 40 //initialize the balls
 41 for(var i = 0; i < ballCount; i++) {    
 42     var collision = false;
 43     while(true) {
 44         var b = createBall();        
 45         for(var j = 0; j < i; j++) {
 46             collision = checkCollision(b,balls[j]);
 47             if(collision) break;
 48         }
 49         if(!collision) {
 50             balls[i] = b;
 51             break;
 52         }
 53     }
 54 }
 55 
 56 function calcV(m1, m2, v1, v2) {
 57     return ((m1 - m2) * v1 + 2 * m2 * v2) / (m1 + m2);
 58 }
 59 
 60 function draw() {
 61     //handle collisions
 62     for(var i = 0; i < balls.length; i++) {
 63         for(var j = i + 1; j < balls.length; j++) {
 64             if(checkCollision(balls[i],balls[j])) {
 65                 var b1 = balls[i], b2 = balls[j];
 66                 var v1 = { x : b1.vx, y : b1.vy };
 67                 var v2 = { x : b2.vx, y : b2.vy };
 68                 b1.vx = calcV(b1.m, b2.m, v1.x, v2.x);
 69                 b1.vy = calcV(b1.m, b2.m, v1.y, v2.y);
 70                 b2.vx = calcV(b2.m, b1.m, v2.x, v1.x);
 71                 b2.vy = calcV(b2.m, b1.m, v2.y, v1.y);
 72             }
 73         }
 74     }
 75     
 76     //move the balls
 77     for(var i in balls) {
 78         var b = balls[i];
 79         b.x += b.vx;
 80         b.y += b.vy;
 81         var closeSide = false;
 82         var maxPos = boxLen - 2 * b.r;
 83         if(b.x < 0) {
 84             b.x = 0;
 85             closeSide = true;
 86         } else if(b.x > maxPos) {
 87             b.x = maxPos;
 88             closeSide = true;
 89         }
 90         if(closeSide)
 91             b.vx = -1 * b.vx;
 92         closeSide = false;
 93         if(b.y < 0) {
 94             b.y = 0;
 95             closeSide = true;
 96         } else if(b.y > maxPos) {
 97             b.y = maxPos;
 98             closeSide = true;
 99         }
100         if(closeSide)
101             b.vy = -1 * b.vy;
102     }
103         
104     //draw the balls
105     var canvas = document.getElementById('box');
106     var ctx = canvas.getContext('2d');
107     ctx.fillStyle = "#000";
108     ctx.fillRect(0,0,canvas.width, canvas.height);
109     for(var i in balls) {
110         var b = balls[i];
111         ctx.beginPath();
112         ctx.arc(b.x+b.r, b.y+b.r, b.r, 0, 2 * Math.PI,true);
113         ctx.closePath();
114         ctx.fillStyle = b.color;
115         ctx.fill();
116     }
117     setTimeout(draw,10);
118 }
119     
120 draw();

 

posted @ 2013-11-06 17:07  李土鳖  阅读(455)  评论(0编辑  收藏  举报