「The Nature of Code」からパーティクルを押しのける力について取り上げます。パーティクルを押しのける力を持つ物体を生成します。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。
パーティクルと押しのける力
以下は、パーティクルを押しのける力を持つ物体の参考例です。
//ParticleSystem with repeller ParticleSystem ps; Repeller repeller; void setup(){ size(200, 200); ps = new ParticleSystem(new PVector(width/2, 50)); repeller = new Repeller(width/2-20, height/2); } void draw(){ background(255); ps.addParticle(); PVector gravity = new PVector(0, 0.1); ps.applyForce(gravity); ps.applyRepeller(repeller); repeller.display(); ps.run(); }
import java.util.Iterator; class ParticleSystem{ ArrayList<Particle> particles; PVector origin; //パーティクルの座標 //コンストラクタ ParticleSystem(PVector location){ origin = location.copy(); particles = new ArrayList<Particle>(); } //パーティクルの追加 void addParticle(){ //パーティクルの生成・追加 particles.add(new Particle(origin)); } //力の適用 void applyForce(PVector f){ for(Particle p : particles){ p.applyForce(f); } } //押し返す力の適用 void applyRepeller(Repeller r){ for(Particle p : particles){ PVector force = r.repel(p); p.applyForce(force); } } //実行 void run(){ Iterator<Particle> it = particles.iterator(); while(it.hasNext()){ Particle p = it.next(); p.run(); if(p.isDead()){ it.remove(); } } } }
//パーティクル class Particle{ PVector location; PVector velocity; PVector acceleration; float lifespan; float mass = 1; //コンストラクタ Particle(PVector l){ location = l.copy(); velocity = new PVector(random(-1, 1), random(-2, 0)); acceleration = new PVector(0, 0); lifespan = 255.0; } //実行 void run(){ update(); display(); } //力の適用 void applyForce(PVector force){ PVector f = force.copy(); f.div(mass); acceleration.add(f); } //座標の更新 void update(){ velocity.add(acceleration); location.add(velocity); acceleration.mult(0); lifespan -= 2.0; } //図形の描画 void display(){ stroke(0, lifespan); strokeWeight(2); fill(127, lifespan); ellipse(location.x, location.y, 12, 12); } //パーティクルの生存確認 boolean isDead(){ if(lifespan < 0.0){ return true; }else{ return false; } } }
class Repeller{ PVector location; float r = 10; float strength = 100; //コンストラクタ Repeller(float x, float y){ location = new PVector(x, y); } //押し返す力を計算する PVector repel(Particle p){ PVector dir = PVector.sub(location, p.location); float d = dir.mag(); dir.normalize(); d = constrain(d, 5, 100); float force = -1 * strength / (d * d); dir.mult(force); return dir; } //図形の描画 void display(){ stroke(0); strokeWeight(2); fill(127); ellipse(location.x, location.y, r*4, r*4); } }
まとめ
「The Nature of Code」からパーティクルを押しのける力について取り上げました。パーティクルを押しのける力を持つ物体を生成しました。引き続き、「The Nature of Code」の内容を勉強します。
参考書籍
※Javaの勉強にもなるので一石二鳥です。