2013-04-05 65 views
2

這裏是一個short video,其中可以看到兩個(也許更多)粒子組相互間發生故障。如何在彈性粒子碰撞模擬器中避免粒子一起抖動?

源代碼可以在​​找到。

這是我用計算碰撞代碼:

function collisionPhysics() 
{ 
    for (var i = 0; i < N - 1; ++i) 
    { 
     for (var j = i + 1; j < N; ++j) 
     { 
      var Dx = objects[j].x - objects[i].x; // Difference in X direction between objects[i] and objects[j]. 
      var Dy = objects[j].y - objects[i].y; // Difference in Y direction between objects[i] and objects[j]. 
      var D2 = Dx * Dx + Dy * Dy;    // Distance between objects[i] and objects[j] squared. 

      if (D2 <= (objects[i].rad + objects[j].rad) * (objects[i].rad + objects[j].rad)) // Colision check could be inserted here, reusing D2. 
      { 
       var delta = 2 * (Dx * (objects[i].Vx - objects[j].Vx) + Dy * (objects[i].Vy - objects[j].Vy))/(D2 * (objects[i].m + objects[j].m)); 
       objects[i].Vx += -objects[i].m * delta * Dx; 
       objects[i].Vy += -objects[i].m * delta * Dy; 
       objects[j].Vx += objects[j].m * delta * Dx; 
       objects[j].Vy += objects[j].m * delta * Dy; 
      } 
     } 
    } 
} 

編輯2013年4月6日: nwellcome提到的問題是造成奇怪的行爲。而這個調整的功能應該解決這個問題,不知道這是否可以提高性能,明智的,但它的工作原理:

function collisionPhysics() 
{ 
    for (var i = 0; i < N - 1; ++i) 
    { 
     for (var j = i + 1; j < N; ++j) 
     { 
      var Dx = objects[j].x - objects[i].x + timeStep * (objects[j].u - objects[i].u); 
      var Dy = objects[j].y - objects[i].y + timeStep * (objects[j].v - objects[i].v); 
      var D2 = Dx * Dx + Dy * Dy;    // Distance between objects[i] and objects[j] squared. 

      if (D2 <= (objects[i].r + objects[j].r) * (objects[i].r + objects[j].r)) // Colision check could be inserted here, reusing D2. 
      { 
       objects[i].col = true; 
       objects[j].col = true; 
       var dx = objects[j].x - objects[i].x; 
       var dy = objects[j].y - objects[i].y; 
       var du = objects[j].u - objects[i].u; 
       var dv = objects[j].v - objects[i].v; 
       var dr = objects[j].r + objects[i].r; 
       var dt = (-Math.sqrt(2 * dx * du * dy * dv - du * du * (dy * dy - dr * dr) - dv * dv * (dx * dx - dr * dr)) - dx * du - dy * dv)/(du * du + dv * dv); 
       Dx = objects[j].x - objects[i].x + dt * (objects[j].u - objects[i].u); 
       Dy = objects[j].y - objects[i].y + dt * (objects[j].v - objects[i].v); 
       D2 = Dx * Dx + Dy * Dy; 
       var delta = 2 * (Dx * (objects[i].u - objects[j].u) + Dy * (objects[i].v - objects[j].v))/(D2 * (objects[i].m + objects[j].m)); 
       objects[i].u += -objects[i].m * delta * Dx; 
       objects[i].v += -objects[i].m * delta * Dy; 
       objects[j].u += objects[j].m * delta * Dx; 
       objects[j].v += objects[j].m * delta * Dy; 
       objects[i].x += (timeStep - dt) * objects[i].u; 
       objects[i].y += (timeStep - dt) * objects[i].v; 
       objects[j].x += (timeStep - dt) * objects[j].u; 
       objects[j].y += (timeStep - dt) * objects[j].v; 
      } 
     } 
    } 
} 

回答

0

的問題是你的衝突解決的方法並不能確保顆粒不會仍然相交於下一幀的開始。

當您發現碰撞時,您需要回到粒子邊界發生碰撞並解決碰撞的時間點。對於這樣做的方法,請參閱this game development answer

+0

這確實是造成這個問題,做了一點數學後,我得到了一個工作對撞機。當粒子同時碰撞兩個粒子時,它似乎也能正常工作。謝謝,這實際上是一個非常合理的方法,不知道爲什麼我以前沒有想到這一點。 – fibonatic 2013-04-06 00:09:45