boids

2016.11.22

群行動シミュレーション

群れのシミュレーションで有名な「boids」です。
パーティクル一つ一つは、X座標、Y座標、X方向の速度、Y方向の速度の4つを保持するだけの単純なオブジェクトで、各パーティクルは「凝集」「連帯」「分離」の単純な3つの演算を積み重ねることで動作します。
単純なロジックの組み合わせによって、一見複雑に見える結果が生まれることを「創発的」と言うそうですが、「boids」はそれを体感する良いサンプルだと思います。

パーティクルの定義

まずは位置と速度を管理するだけの単純なパーティクルをBoidクラスとして定義します。

[boid.js]

メイン処理の定義

パーティクルができたら「凝集」「連帯」「分離」といった行動原理となる演算を実装していきます。
先ほど定義したBoidクラスもここで使用します。
クラス化するかベタで書くかはお好みで。

 

Pixi.js初期処理

canvasの操作は2Dの描画速度に定評のあるpixi.jsを利用しています。
webGLも非webGLも同じ実装でいけるので互換性を気にすることなく実装に集中できます。

凝集

一定範囲内にある他のパーティクルに近寄ろうとします。
※引数のindexは処理対象となるパーティクルの番号です。

連帯

一定範囲内にある他のパーティクルに追随しようとします。
※引数のindexは処理対象となるパーティクルの番号です。

分離

一定範囲内にある他のパーティクルから一定以上の距離を取ろうとします。
※引数のindexは処理対象となるパーティクルの番号です。

速度制限

動作の基本原理は「凝集」「連帯」「分離」でOKなのですが、座標や速度を加算していく一方なので、そのままでは速度が無尽蔵に速くなっていってしまいます。
ですので、一定以上の速度を超えないように速度制限をかけていきます。

描画

ではいよいよ描画です。
先ほど定義した処理をパーティクル一つ一つに対して適用していきます。
実行した結果を元に次の処理を実行して演算を重ねていくようなイメージです。

 

今回のサンプルでは見やすさと、動きの変化をわかりやすくする意味でのインタラクティブ性として以下2点のルールも追加しました。

  • 画面端に来たら逆サイドから出直す(境界ループ)
  • マウス位置もしくはタッチした位置をよける(障害物)

処理定義用クラスの全コードはこちらです。

[boids.js]

パフォーマンス

演算は各パーティクル同志の総当たりになりますので結構重くなります。
1pxのドットで、PCで300個、スマホで100個がおおよその限界かなといった印象です。
今回は省いていますが、実案件では1個当たりの描画に画像を使うケースは多いでしょうし、それに伴って「向き」の概念を入れたくなったりすると思いますので、実際の個数は半分以下がパフォーマンス面で現実的なラインになるかなと思います。