Calculate velocity and direction of a ball to ball collision based on mass and bouncing coefficient

后端 未结 3 1308
没有蜡笔的小新
没有蜡笔的小新 2021-02-06 12:39

I used the following code based on this

ballA.vx = (u1x * (m1 - m2) + 2 * m2 * u2x) / (m1 + m2);
ballA.vy = (u1y * (m1 - m2) + 2 * m2 * u2y) / (m1 + m2);

ballB.         


        
3条回答
  •  无人共我
    2021-02-06 12:47

    here is a demo of an inelastic collision equation in action, custom made for you:

    function BallObject(elasticity) {
      this.v = { x: 1, y: 20 }; // velocity: m/s^2
      this.m = 10; // mass: kg
      this.p = { x: 40, y: 0}; // position
      this.r = 15; // radius of obj
      this.cr = elasticity; // elasticity
    }
    
    function draw(obj) {
      ctx.beginPath();
      ctx.arc(obj.p.x, obj.p.y, obj.r, 0, 2 * Math.PI);
      ctx.closePath();
      ctx.stroke();
      ctx.fill();
    }
    
    function collide(obj) {
      obj.v.y = (obj.cr * floor.m * -obj.v.y + obj.m * obj.v.y) / (obj.m + floor.m);
    }
    
    function update(obj, dt) {
    
      // over-simplified collision detection
      // only consider the floor for simplicity
      if ((obj.p.y + obj.r) > c.height) { 
         obj.p.y = c.height - obj.r;
         collide(obj);
      }
    
      obj.v.y += g * dt;
      obj.p.x += obj.v.x * dt * ppm;
      obj.p.y += obj.v.y * dt * ppm;
    }
    
    var d = document,
        c = d.createElement('canvas'),
        b = d.createElement('button'),
        els = d.createElement('input'),
        clr = d.createElement('input'),
        clrl = d.createElement('label'),
        ctx = c.getContext('2d'),
        fps = 30, // target frames per second
        ppm = 20, // pixels per meter
        g = 9.8, // m/s^2 - acceleration due to gravity
        objs = [],
        floor = {
          v: { x: 0, y: 0 }, // floor is immobile
          m: 5.9722 * Math.pow(10, 24) // mass of earth (probably could be smaller)
        },
        t = new Date().getTime();
    
    b.innerHTML = 'add ball with elasticity: 0.70';
    b.onclick = function() { objs.push(new BallObject(els.value / 100)); };
    
    els.type = 'range';
    els.min = 0;
    els.max = 100;
    els.step = 1;
    els.value = 70;
    els.style.display = 'block';
    els.onchange = function() { 
      b.getElementsByTagName('span')[0].innerHTML = (this.value / 100).toFixed(2); 
    };
    
    clr.type = 'checkbox';
    clr.checked = true;
    
    clrl.appendChild(clr);
    clrl.appendChild(d.createTextNode('clear each frame'));
    
    c.style.border = 'solid 1px #3369ff';
    c.style.borderRadius = '10px';
    c.style.display = 'block';
    c.width = 400;
    c.height = 400;
    
    ctx.fillStyle = 'rgb(100,200,255)';
    ctx.strokeStyle = 'rgb(33,69,233)';
    
    d.body.appendChild(c);
    d.body.appendChild(els);
    d.body.appendChild(b);
    d.body.appendChild(clrl);
    
    setInterval(function() {
    
      var nt = new Date().getTime(),
          dt = (nt - t) / 1000;
    
      if (clr.checked) {
        ctx.clearRect(0, 0, c.width, c.height);
      }
    
      for (var i = 0; i < objs.length; i++) {
        update(objs[i], dt);
        draw(objs[i]);
      }
    
      t = nt;
    
    }, 1000 / fps);
    

    to see it in action yourself, just go here: http://jsbin.com/iwuxol/edit#javascript,live

    This utilizes this equation: enter image description here

    and since your "floor" doesn't move you only have to consider the influence on the ball's y velocity. mind you there are quite a few shortcuts and oversights here so this is a very primitive physics engine, and is mainly meant to illustrate this one equation...

    hope this helps -ck

提交回复
热议问题