与不同的球质量的现实球碰撞 - 小球停止大球

时间:2016-04-11 14:50:35

标签: javascript game-physics

tl;dr demo with editor of the bounce function

点击将新球添加到该区域

有一个question with over 200 votes on this topic得分不到一半的最佳答案。我注意到这一点,因为答案通常会超出问题范围。

我尝试将建议的代码转换为javascript。我的小行星具有以下属性:

  • vxvy - x轴和y轴的速度
  • xy获取职位
  • mass以千克为单位,如果重要的话

我的代码因此读作:

  function bounce(objectA, objectB) { 
    /** objectA and objectB have following properties:
     *   vx, vy - speed in x and y direction
     *   x, y   - position
     *   mass   - masss
     *   radius - diameter, calculated from mass
     *            using average rock density according to wikipedia
   ***/  

    // Colision point as seen from B's perspective  
    var collision = [objectA.x-objectB.x, objectA.y-objectB.y];
    var distance = Math.sqrt(collision[0]*collision[0] + collision[1]*collision[1]);

    collision[0] /= distance;
    collision[1] /= distance;

    var aci = objectA.vx* collision[0] + objectA.vy* collision[1]; 
    var bci = objectB.vx* collision[0] + objectB.vy*collision[1]; 

    var totalMass = objectA.mass + objectB.mass;
    // This is what I had to add since the original answer doesn't account for mass
    var acf = bci * objectB.mass/totalMass;
    var bcf = aci * objectA.mass/totalMass;

    // I put velocities in arrays in case I wanted to apply more changes
    // I mean I need to apply some changes, but I don't know what changes exactly
    // to make this crap of code work
    var v1 = [(acf-aci) * collision[0], (acf-aci) * collision[1]]; 
    var v2 = [(bcf-bci) * collision[0], (bcf-bci) * collision[1]];     


    // Addition sure works better than assignment, but I encourage to try it for
    // the lulz
    objectA.vx += v1[0];
    objectA.vy += v1[1];
    objectB.vx += v2[0];
    objectB.vy += v2[1];
  }

现在在我的场景中,我观察到奇怪的行为。如果大球击中小球,小球快速飞走,但大球完全停止。足够大的球应该将小球推开而不会减速。

在这种情况下:

image description

发生这种情况:

image description

无论你使用什么尺寸,这都不会发生:

image description

我认为这是由于我在两个球之间划分速度的方式造成的。但是如何确定变化?

我理解这个问题很难通过查看代码来回答。不幸的是,上下文不适合jsfiddle中的SSCCE。因此,通过一些努力,我创建了 online demo on github pages ,其中可以编辑上述功能以立即生效。我将尽力确保保留演示以供进一步参考。

1 个答案:

答案 0 :(得分:1)

阅读elastic collisions。你的方程式缺少重要因素,如质量差异,以及 - 因为你在两个维度上工作 - 碰撞角度。

对于一维碰撞,您需要实现以下等式(来自该维基百科页面),其中u1u2是碰撞前每个对象的速度,{{1 } / v1是之后的速度。

One-dimensional elastic collision, object 1

One-dimensional elastic collision, object 1

您可以通过检查系统的总动量和动能在碰撞过程中保持不变来验证结果。

二维方程也在那篇文章中,但更多涉及,所以我不会在这里复制它们(我只是粘贴整篇文章)。重要的是,它们需要使用三角函数(v2sin)和点积,这些函数在您当前的实现中是不存在的。