2016-04-25 6 views
-1

Я просто не могу понять поведение этого тривиального скрипта в обработке.Непонятное поведение обработки

Для ParticleSystem размера 1, он работает. Как только размер будет больше 1, частицы сойдут с ума. Зачем?

Эскиз для запуска:

float dt = 1; 
ParticleSystem ps; 

void setup(){ 
    size(700,700); 

    // PARTICLE SYSTEM 
    PVector origin = new PVector(width/2, height/2); 
    ps = new ParticleSystem(12, origin); // Change the number here to see the weird behavior ! 
} 

void draw(){ 
    background(255); 

    // PARTICLE SYSTEM 
    ps.run(); 
} 

Класс частиц:

class Particle { 

    private PVector pos; 
    private PVector prevPos; 
    private PVector vel; 
    private PVector force; 

    private float m = 10; 
    private float r = 60; 
    private boolean dead = false; 

    Particle(PVector pos, PVector vel) { 
     this.prevPos = pos; 
     this.vel = vel; 
     this.force = new PVector(0, 0); 
     this.pos = new PVector(); 
     this.pos.x = pos.x + vel.x * dt + 0.5 * force.x/m * sq(dt); 
     this.pos.y = pos.y + vel.y * dt + 0.5 * force.y/m * sq(dt); 
    } 

    void display() { 
     color c = color(0); 
     fill(c); 
     ellipse(this.pos.x, this.pos.y, this.r * 2, this.r * 2); 
    } 

    void run() { 
     this.update(); 
     this.display(); 
    } 

    void update() { 
     this.moveVerlet(); 
    } 

    void moveVerlet() { 
     PVector tempPos = new PVector(this.pos.x, this.pos.y); 
     this.pos.x = this.pos.x * 2 - this.prevPos.x + sq(dt) * this.force.x/this.m; 
     this.pos.y = this.pos.y * 2 - this.prevPos.y + sq(dt) * this.force.y/this.m; 
     this.prevPos.set(tempPos); 
    } 

} 

Particle System Класс:

class ParticleSystem { 

    private ArrayList<Particle> particles; 
    private PVector origin; 

    ParticleSystem(int nb, PVector origin) { 
     this.origin = origin; 
     this.particles = new ArrayList<Particle>(nb); 
     for (int i = 0 ; i < nb ; i++) { 
      float k = 0.5; 
      float vx = random(-k, k); 
      float vy = random(-k, k); 
      this.particles.add(new Particle(origin, new PVector(vx, vy))); 
     } 
    } 

    void checkBoundaries() { 
     for (int i = this.particles.size() - 1 ; i >= 0 ; i--) { 
      if (this.particles.get(i).pos.x - this.particles.get(i).r <= 0 
       || this.particles.get(i).pos.x + this.particles.get(i).r >= width) { 
       this.particles.get(i).prevPos.x = this.particles.get(i).pos.x + this.particles.get(i).pos.x 
        - this.particles.get(i).prevPos.x; 
      } 
      else if (this.particles.get(i).pos.y - this.particles.get(i).r <= 0 
       || this.particles.get(i).pos.y + this.particles.get(i).r >= height) { 
       this.particles.get(i).prevPos.y = this.particles.get(i).pos.y + this.particles.get(i).pos.y 
        - this.particles.get(i).prevPos.y; 
      } 
     } 
    } 

    void run() { 
     checkBoundaries(); 
     for (Particle p : this.particles) { 
      p.run(); 
     } 
    } 

} 
+0

сузите свой вопрос – saikumarm

+0

Я понятия не имею, в чем проблема. Только это должно быть в классе частиц, я думаю, в методе moveVerlet() ... – ypicard

ответ

3

Обратите внимание, что вы передаете origin в ParticleSystem конструктор. Затем вы передаете это в конструктор Particle, а класс Particle сохраняет в переменной prevPos, которую он использует для обновления позиции каждого Particle.

Итак, у вас есть несколько экземпляров Particle, разделяющих одну и ту же переменную prevPos. О, о!

Проблема в том, что класс Particle также изменяет, что prevPos переменная. Итак, теперь у вас есть несколько экземпляров Particle, которые изменяют эту же переменную prevPos, которую вы затем используете для обновления позиции, и вы начинаете накапливать ошибки.

Решение только копииoriginPVector перед передачей его в каждый Particle конструктор. К счастью PVector имеет copy() функцию, которая делает именно то, что:

this.particles.add(new Particle(origin.copy(), new PVector(vx, vy))); 

Более подробную информацию можно найти в the reference.

+0

Большое спасибо! – ypicard

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