不可理解的处理行为

Ununderstandable Processing behavior

我无法理解处理中这个微不足道的脚本的行为。

对于大小为 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 :

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

}

粒子系统Class:

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

}

请注意,您将 origin 传递给了 ParticleSystem 构造函数。然后将其传递给 Particle 构造函数,Particle class 将其存储在 prevPos 变量中,它用于更新每个 Particle 的位置.

所以您有多个 Particle 实例共享同一个 prevPos 变量。呃哦!

问题是 Particle class 还 修改 那个 prevPos 变量。所以现在你有多个 Particle 实例都修改同一个 prevPos 变量,然后你用它来更新位置,你开始累积错误。

解决方案是 复制 origin PVector,然后再将其传递给每个 Particle 构造函数。幸运的是 PVector 有一个 copy() 函数可以做到这一点:

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

可以在 the reference 中找到更多信息。