パーティクル(particle)とは運動する粒子で表現される事象のことで、コンピューターグラフィックスでは、光、炎、水などの現象を表現するのに用いられています。今回はprocessingを用いたパーティクルの表現を学びます。またオブジェクト指向プログラミングのための、クラス構文(以下、クラス)についても学んでいきましょう。
クラスの定義
クラスとは型のようなもので、そこで定義された内容をもとに複数の実体=インスタンスを作成することができます。クラスは以下のように記述します。クラス名は慣例的に大文字で始めます。
class Mediaproduce {
  //初期化用メソッド(コンストラクタ) 
  Mediaproduce ( ) {
    
  }
  //更新用メソッド
 void update() {
 }
  //表示用メソッド
  void display() {
 }
 
}
クラスを用いた描画
次に、クラスを実際に使って描画を実行するスケッチを作成してみましょう。
//クラスのインスタンスを宣言
Mediaproduce c1, c2, c3, c4, c5;
 
void setup() {
  size(600, 600);
 
  //インスタンスを作成
  c1 = new Mediaproduce(100,100, 10, 1.0);
  c2 = new Mediaproduce(150,150, 20, 1.5);
  c3 = new Mediaproduce(200,200, 30, 2.0);
  c4 = new Mediaproduce(250,250, 40, 2.5);
  c5 = new Mediaproduce(300,300, 50, 3.0);
}
 
void draw() {
  background(0);
 
  noStroke();
  fill(255,0,0);
  c1.update(); 
  c1.display();
 
  fill(0,255,0);
  c2.update(); 
  c2.display();
  
  fill(0,0,255);
  c3.update(); 
  c3.display();
  
  fill(255,255,0);
  c4.update(); 
  c4.display();
  
  fill(0,255,255);
  c5.update(); 
  c5.display();
}
 
//クラスの宣言
class Mediaproduce {
  float x, y, speed;
  int d;
 
  //初期化用メソッド(コンストラクタ) 
  Mediaproduce (float _x, float _y, int _d, float _speed) {
    x = _x;
    y = _y;
    d = _d;
    speed = _speed;
  }
 
  //円の位置を更新するメソッド
  void update() {
    x += speed;
    if (x > width) {
      x = 0;
    }
    
    y += speed;
    if (y > height) {
      y = 0;
    }
  }
 
  void display() {
    ellipse(x, y, d, d);
  }
}
パーティクルを表示するコード
ひとつの型から複数の実体を生成するというクラスの特徴を活用して、パーティクルを生成するオブジェクト指向プログラムを作成してみましょう。
ArrayList<ParticleSystem> systems;
void setup() {
  size(800, 800);
  systems = new ArrayList<ParticleSystem>();
}
void draw() {
  background(0);
  for (ParticleSystem ps: systems) {
    ps.run();
    ps.addParticle();
  }
}
void mousePressed() {
  systems.add(new ParticleSystem(1, new PVector(mouseX, mouseY)));
}
class CrazyParticle extends Particle {
  float theta;
  CrazyParticle(PVector l) {
    super(l);
    theta = 0.0;
  }
  void update() {
    super.update();
    float theta_vel = (velocity.x * velocity.mag()) / 10.0f;
    theta += theta_vel;
  }
}
class Particle {
  PVector location;
  PVector velocity;
  PVector acceleration;
  float lifespan;
  Particle(PVector l) {
    acceleration = new PVector(0.00,-0.05); //パーティクル生成の方向
    velocity = new PVector(random(-1,1),random(-2,0));
    location = l.get();
    lifespan = 300.0; //パーティクル生成の上限
  }
  void run() {
    update();
    display();
  }
  void update() {
    velocity.add(acceleration);
    location.add(velocity);
    lifespan -= 2.0;
  }
  void display() {
    stroke(255,0,0,lifespan); //パーティクルの線の色
    fill(255,0,0,lifespan); //パーティクルの塗り色
    ellipse(location.x,location.y,2,2); //パーティクルで生成される図形
  }
  boolean isDead() {
    return (lifespan < 0.0);
  }
}
class ParticleSystem {
  ArrayList<Particle> particles;
  PVector origin;
  
  ParticleSystem(int num, PVector v) {
    particles = new ArrayList<Particle>();
    origin = v.get();
    for (int i = 0; i < num; i++) { particles.add(new Particle(origin)); } } void run() { for (int i = particles.size()-1; i >= 0; i--) {
      Particle p = particles.get(i);
      p.run();
      if (p.isDead()) {
        particles.remove(i);
      }
    }
  }
  void addParticle() {
    Particle p;
    if (int(random(0, 2)) == 0) {
      p = new Particle(origin);
    } 
    else {
      p = new CrazyParticle(origin);
    }
    particles.add(p);
  }
  void addParticle(Particle p) {
    particles.add(p);
  }
  boolean dead() {
    return particles.isEmpty();
  }
}
総合課題4: パーティクルを用いたグラフィックスを作成する。 画面のサイズは自由とする。 以下の項目を用いて独自の作品を制作する。 ・背景に画像を使用する(写真やイラストなど)。 ・パーティクルの粒子のサイズを変更する。 ・パーティクルの生成方向を変更する。 ・パーティクルの配色を変更する。
