书名:代码本色:用编程模拟自然系统
作者:Daniel Shiffman
译者:周晗彬
ISBN:978-7-115-36947-5
目录
4.12 带排斥对象的粒子系统
1、带排斥对象的粒子系统
我们想进一步优化这个粒子系统,在其中加入一个排斥对象(Repeller)——排斥对象的作用力和第2章中的引力相反,排斥对象对其他对象有斥力作用,以防止对方靠近。这个特性实现起来比较复杂,和重力不同,Attractor或者Repeller对每个粒子的作用力都不相同,我们需要逐个计算。
我们打算在上面的示例程序中加入这个排斥对象。我们需要加入两个额外的功能点:
- 1.排斥对象(声明、初始化和显示);
- 2.在粒子系统中加入一个新函数,该函数以Repeller对象为参数,它的功能是将排斥力作用在每个粒子上。
请注意一个关键点,在加入排斥对象的整个过程中,我们从来没有直接在Particle类上作任何修改。粒子不需要知道外部环境的细节,它只需要管理自身的位置、速度和加速度,并接受外力作用。
2、示例
示例代码4-7 带Repeller的粒子系统
ParticleSystem ps;
Repeller repeller;
void setup() {
size(640,360);
ps = new ParticleSystem(new PVector(width/2,50));
repeller = new Repeller(width/2-20,height/2);
}
void draw() {
background(255);
ps.addParticle();
// Apply gravity force to all Particles
PVector gravity = new PVector(0,0.1);
ps.applyForce(gravity);
ps.applyRepeller(repeller);
repeller.display();
ps.run();
}
ParticleSystem.pde (同上,略)
Particle.pde (同上,略)
Repeller.pde
class Repeller {
// Gravitational Constant
float G = 100;
// position
PVector position;
float r = 10;
Repeller(float x, float y) {
position = new PVector(x,y);
}
void display() {
stroke(0);
strokeWeight(2);
fill(175,0,0);
ellipse(position.x,position.y,48,48);
}
// Calculate a force to push particle away from repeller
PVector repel(Particle p) {
PVector dir = PVector.sub(position,p.position); // Calculate direction of force
float d = dir.mag(); // Distance between objects
dir.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction)
d = constrain(d,5,100); // Keep distance within a reasonable range
float force = -1 * G / (d * d); // Repelling force is inversely proportional to distance
dir.mult(force); // Get force vector --> magnitude * direction
return dir;
}
}