2014-10-19 5 views
0

У меня много частиц, движущихся вокруг и попадающих в детектор, чтобы видеть, когда они касаются друг друга. Если две частицы касаются, они должны отскакивать в противоположном направлении.Имитация двух кругов, отскакивающих друг от друга

  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 * скорость каждого кадра.

Есть много вопросов о том, как выработать скорость или угол отката, но моя проблема заключается в том, что он застревает в бесконечном колебании.

+0

Мы не можем дать ответ, как мы не можем проверить это, но, вот несколько предложения. Сначала сделайте так, а затем вычислите позицию. Внутри for проверьте сначала свой идентификатор (теперь вы его проверяете последним), используйте 'if (this.id === particle [i] .id) continue;' – GramThanos

ответ

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; я < ...) петли вместо

    • , но это не то, что точная
  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); 
          } 
      

[Примечания]

  • лучшее для хранения вождения Reflection усилия
  • легко реализовать физики моделирования рикошета правильно на нем
  • , а также для обработки пружин и других вещей
  • Если у вас есть постоянные облигации, вы можете их предварительно вычислить один раз в некоторых постоянных списках конфликтов
  • для повышения производительности
  • пуля 2 может использоваться без списка Collide, но тогда это не так точно для нескольких отскоков сразу
Смежные вопросы