2013-04-05 4 views
2

Вот short video, в котором видно, что группы из двух (возможно, более) частиц сбиваются друг с другом.Как избежать частиц, сжимающихся вместе в симуляторе столкновения упругих частиц?

Исходный код может быть найден here.

И это код, который я использую для расчета столкновений с:

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; 
      } 
     } 
    } 
} 

Edit 2013/04/06: Вопрос 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

Смежные вопросы