不可理解的处理行为
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 中找到更多信息。
我无法理解处理中这个微不足道的脚本的行为。
对于大小为 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 中找到更多信息。