2016-04-25 9 views
-1

私はこの単純なスクリプトの処理における処理を理解できません。理解できない処理の振る舞い

サイズ1のParticleSystemでは、動作します。サイズが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); 
    } 

} 

パーティクルシステムクラス:あなたはParticleSystemコンストラクタにoriginを渡す

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

私はどこから問題が発生しているのか分かりません。それはParticleクラスになければならない、私はmoveVerlet()メソッドで推測する... – ypicard

答えて

3

お知らせ。それをParticleコンストラクタに渡します。Particleクラスは、prevPos変数にその値を格納します。Particleの位置の更新に使用します。

したがって、同じprevPos変数を共有するParticleの複数のインスタンスがあります。ええとああ!

問題はParticleクラスそのprevPos変数を変更することです。これで、Particleの複数のインスタンスにすべて同じ同じprevPos変数が変更され、その位置を更新してエラーが蓄積されるようになりました。

ソリューションは、各Particleコンストラクタに渡す前にちょうどコピーoriginPVectorです。幸いにもPVectorはまさにそのcopy()機能を持っています

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

詳細情報はthe referenceで見つけることができます。

+0

ありがとう! – ypicard

関連する問題