模拟两个圆圈相互弹跳

时间:2014-10-19 22:08:18

标签: javascript physics game-physics paperjs

我有许多粒子在四处移动并触摸检测以查看它们何时接触。如果两个粒子接触,它们应该反向反弹。

            particle.moveSelf = function() {
            var radians = this.angle * Math.PI / 180;

            var moveX = this.velocity * Math.sin(radians);
            var moveY = this.velocity * Math.cos(radians);

            for (var i = 0; i < particles.length; i++) {
                var distance = this.position.getDistance(new Point(particles[i].position.x, particles[i].position.y));
                //if distance < radius 1 + radius 2, bounce this circle away
                if (distance < (this.radius + particles[i].radius) && this.id !== particles[i].id) {
                    this.velocity = -this.velocity;

                }
            }

            this.position.x += moveX;
            this.position.y += moveY;
        };

当我运行此代码时,每一帧中的圆圈相互卡住,每次移动1 *速度。

关于如何计算反弹的速度或角度有很多问题,但我的问题只是它陷入无限振荡中。

1 个答案:

答案 0 :(得分:2)

我之前做过这个,所以这里有一些见解:

  1. 最安全的方法是为每个粒子添加碰撞列表

    • 在第一次通过中,您只是检测到碰撞
    • 并清除/填充碰撞列表,其中包含彼此碰撞的所有粒子的索引

      for (i=0;i<particles;i++) particle[i].collide.clear();
      for (i=0;i<particles;i++) 
       for (j=i+1;j<particles;j++)
        if (colide(particle[i],particle[j]))
         {
         particle[i].collide.add(j);
         particle[j].collide.add(i);
         }
      
    • 您也可以使用一个列表(i = 0; i&lt; ...)循环

    • 但那不是那么精确
  2. 仅更新碰撞项目的位置和速度

    • 现在是棘手的部分
    • 我为每个粒子添加新的方向向量并将其设置为零
    • 然后在每次碰撞中添加一个反射(单位或速度或力脉冲)矢量

      for (i=0;i<particles;i++) 
       for (j=0;j<particle[i].collides;j++)
         {
         // here compute reflected direction ,speed whatever of the bounce to vector dir
         particle[                       i].reflect+=dir;
         particle[particle[i].collide[j]].reflect+=dir;
         }
      
    • 完成后,只需更新位置/速度......

    • 但您需要添加更新所需的内容,例如
    • 如果您使用单位向量然后标准化反射,并将其大小设置为新的速度
    • 同样适用于位移,因此粒子不会重叠
    • 您还可以计算所有反弹粒子的组合动能矢量,并通过质量能量分布计算新的速度

      for (i=0;i<particles;i++) 
         {
         particle[i].speed=compute_speed_from(particle[i].reflect);
         }
      
  3. <强> [注释]

    • 最好是存储驾驶反射力
    • 很容易实现正确弹跳的物理模拟
    • 还用于处理弹簧和其他东西
    • 如果你有永久性债券,那么你可以在一些永久性碰撞清单中预先计算一次
    • 提高绩效
    • bullet 2 可以在没有碰撞列表的情况下使用但是对于一次多次跳出来说不是那么精确