Boids 3.1 – コード説明

概要

Boids 3.1で、いよいよEnemyを導入する。大まかな流れは以下の通り。

  • Creatureクラスを継承したEnemyCreatureクラスを定義する
  • EnemyCreature特有の行動はEnemy同士の分離(separation)のみ
  • BoidCreatureはEnemyCreatureを避ける行動をとる
  • BoidCreatureの群とEnemyCreatureの群を、それぞれのClusterオブジェクトに登録。

EnemyCreatureクラスの追加

Creatureクラスを継承したEnemyCreatureクラスを追加する。そのメソッド構成は以下の通り。specificBehaviorについては、Enemyに特別な行動ルールはなく、分離(separation)のみ実装している。separation()メソッドはBoidCreatureとまったく同じロジック。

Controlerクラスの変更

パラメータ関係

Controlerクラスのパラメータ設定用setterを追加(後述)

Enemy発生用メソッドの追加

BoidCreatureクラスと同じ内容で、createEnemyCreature()メソッドを追加

generate()メソッドを変更

generate()メソッドで、Boidに加えてEnemyも指定個体数だけ発生させるよう追加。

BoidがEnemyから逃げる動作

BoidCreatureクラスに新たにavoidEnemy()メソッドを追加し、specificBehavior()でこれを呼び出すよう変更。avoidEnemy()メソッドの内容は以下の通り。

  • 基本のロジックはsepration()メソッドと同じ
  • ただし分離の相手方がEnemyの群になる
  • 敵から回避する角度は、仲間との分離の角度より大きくする(パラメータで与える)

実行部分

ページ読み込み時の実行部分は以下の通りで、2つのボタンのクリックに対する処理を定義。

  • GENERATEボタンが押された時は、BoidCreatureの群とEnemyCreatureの群を発生させる
  • START/STOPボタンが押されたときは、ControlerクラスのstartAndStop()メソッドを呼び出す

コード全体

HTML

CoffeeScript

クラス構成

Fieldクラス

Creatureクラス

BoidCreatureクラス

EnemyCreatureクラス

Clusterクラス

Controlerクラス

 


↑ Boids 3.0のコード説明へ

 

Boids 3.0 – コード説明

概要

Boids 3.xシリーズで敵(Enemy)を導入する準備として、クラス構成の改良などを行った。

Boids 2.xまではBoidだけだった生物の種類に、新たにEnemyという別の種類が加わるが、どちらについても以下の特徴は共通している。

  • 複数個体をClusterオブジェクトにまとめて扱われる
  • Field内を移動する
  • 壁との衝突を避ける

そこで、これらの特徴に関する部分をCreatureクラスから抜き出したものを新たにCreatureとしてテンプレート化し、Boid特有の動作についてはCreatureクラスを継承したBoidCreatureで実装した。

このほか、BoidとEnemy2つの群を扱うことから、Clusterで処理していた画面の消去処理を外に出すなどの変更を行っている。

Creatureクラスのテンプレート化

Boids 2.3

まず、元となったBoids 2.3のコードの構成を確認する。壁の回避、分離、結合、整列に関するメソッドを定義し、これらをmove()メソッドで呼び出している。

Boids 3.0

Boids 3.0では2.3のCreatureクラスをCreatureBoidCreatureに分け、CreatureクラスにはBoidとEnemyに共通する動作を書き、Boidに特有の動作についてはBoidCreatureのメソッドで実装した。

Creatureクラス

Creatureクラスは以下のメソッドを持っている。

wallAvoidance()
壁との衝突を回避するメソッド。
specificBehavior()
このクラスを継承するクラスごとに特有の動作を記述するためのメソッド。抽象クラスのabstractメソッドに相当し、継承したクラスにおいてその内容が実装される。
determinePosition()
上記2つのメソッドで計算された位置と速度から、次の時間ステップにおける位置を決定するメソッド。

BoidCreatureクラス

BoidCreatureクラスはCreatureクラスを継承し、specificBehavior()メソッドを実装する。

BoidCreatureクラスで分離、結合、整列に関するメソッドを定義し、specificBehavior()メソッドでそれらを呼び出している。

描画処理の変更

Boid 3.xでは、BoidとEnemyという2つの生物をそれぞれ別のClusterオブジェクトに登録して扱う。Boids 2.3までは、アニメーションフレーム再描画のための画面消去処理をClusterクラスのdraw()メソッドで行っていたが、このままだとBoid、Enemyそれぞれの描画の際に画像が消去されて、どちらか一方が画面に表示されなくなる。

そこで、画面消去処理をClusterではなくControlergenerate()メソッドとstartAndStop()メソッドに置いた。

 


↑ Boids 2.3のコード説明へ

↓ Boids 3.1のコード説明へ

 

CoffeeScript – Boids 3.x – 天敵

Boids 3.xの概要

Boids 3.xでは、群として行動している集団に「敵(Enemy)」を投入する。BoidがEnemyを避けるように行動ルールを加え、群としてどのような行動パターンとなるかを確認する。

Boids 3.0 – 基本コード

敵を導入する準備として、Creatureクラスの抽象化・テンプレート化などの大幅な改定を行った。挙動はBoids 2.3と変わらない。

Boids 3.0のコード説明




Boids 3.1 – 敵の導入

このバージョンで「敵(Enemy)」を導入する。

  • Boidの群の個体数に比べて、Enemyの個体数は高々数個程度
  • Enemyは互いの衝突を分離行動によって避けるが、Boidに対しては意識しない
  • BoidはEnemyが視野に入ると回避行動をとる
    • 回避行動は分離行動より大きい角度で方向を転換させるのみ

デモンストレーションのBoidsの様子は、あたかも小魚が天敵の魚を避けるような行動パターンをとっている。BoidがEnemyを回避するのはEnemyが前方にいるときだけだが、群としての回避パターンはよく再現できている。

Boids 3.1のコード説明









Boids Mobile






 



Lifegame Mobile (CoffeeScript)



    


    



Boids – 群の行動

動物の群の行動をシミュレートする”Boids”という考え方をCoffeeScriptで組んでみたもの。個体がそれぞれ独立して一定のルールに従って行動する結果、群としての整然とした行動をとるようになる。

スマートフォン用はこちら







Boidsの考え方や開発過程はこちら

このアプリケーションのコード説明はこちら


Boids 2.3 – コード説明

概要

Boids 2.3では、分離(Separation)、結合(Cohesion)に加えて「整列(Alignment)」のルールを導入する。整列行動の考え方は、ここでは以下の通りとした。

  1. 前方視野内に個体が存在する場合、それらの個体の平均速度を求める
  2. 進行方向を、群の平均速度の方へ向けて少し変更する

なおこのバージョンで、個体生成時にランダムに与える速度の計算方法を変更した。

速度計算の変更

これまで、個体を生成したときに与える速さは、上限値V_MAXを定数としておいて、V_MAX~VMAX/2の範囲で一様乱数を発生させていた。

Boids 2.3では、速さの上限値vMAXに加えて下限値vMINCreatureクラスのクラス変数に持たせて、この間の一様乱数で速さを設定する。

これに伴って、以下を追加

  • HTMLの<script>要素に定数V_MINを追加
  • ControlerクラスにvMinのセッターを追加
  • セッターを通してV_MINの値をCreature._vMinにセット

整列のアルゴリズム

平均速度の算出

次図において、先方視野内に個体が存在する場合、それらの平均速度vmeanを計算する。

    $$ {\bf v}_{\rm mean} = \frac{1}{n} \sum^n_{i=1} {\bf v}_i $$

なお視野内の判定は、ベクトルの前後判定と個体との距離計算によっている。

boid2x_alignment_vmean

進路変更

先の図のように、自身の進行方向に対する平均速度の方向によって、以下の手順で進路を変更する。

  1. 平均速度ベクトルの向きが自身の進行方向より左右どちらに向いているかを判定
  2. 平均速度ベクトルが進行方向より右に向いているなら右へ、左に向いているなら左へ方向を少し変化させる。

これらの考え方はBoids 2.1の分離行動における回避動作と同じ。

コード内容

初期パラメータ定義

HTMLで定義する初期パラメータに、整列に関する以下の変数を追加する。

  • 整列判定の視野の深さ(BD23_ALIGNMENT_FIELD_DEPTH)
  • 整列行動における速度の変更角(BD23_ALIGNMENT_ANGLE)

なお、このバージョンで分離行動の視野の深さの変数名を変更している。

クラス変数

初期パラメータの保存のため、Creatureクラスのクラス変数を追加する。

パラメータのセッター

Controlerクラスに、Creatureクラス変数へのセッターを定義する。

パラメータのセット

HTMLで定義されたパラメータをControlerオブジェクトのセッターによってセットする。

Ceatureクラスの変更 – alignment()メソッドの追加

Creatureクラスのmove()メソッドがalignment()メソッドを呼び出すようにする。

alignment()メソッドを新たに定義する。

  • 速度の方向を変化させる回転行列のcos、sinに対応したローカル変数cssnを定義している
  • 平均速度の参照がvMeanプロパティに保存されるが、視野内に個体が存在しないときはnullとなる
  • 速度の回転方向は、右がマイナス方向、左がプラス方向となることに注意

全コード

以下に、分離、結合、整列の3ルールすべてを適用したBoids 2.3の全コードを示す。


↑ Boids 2.2のコード説明へ

↑ Boids 3.0のコード説明へ

Boids 2.2 – コード説明

概要

Boids 2.2では、分離(Separation)に加えて「結合(Cohesion)」のルールを導入する。結合行動の考え方は、ここでは以下の通りとした。

  1. 前方視角内に個体が存在する場合、それらの重心位置を求める
  2. 進行方向を、重心の方へ向けて少し変更する

結合のアルゴリズム

重心の算出

次図において、進行方向に直角な直線hより前方側の個体が存在する場合、それらの重心位置gを計算する。

    $$ {\bf g} = \frac{1}{n} \sum^n_{i=1} {\bf p}_i $$

なお、視野角の前方判定はベクトルの前後判定によって行っている。

boid2x_cohesion_gravity_center

進路変更

先の図のように、自身の進行方向に対する群の重心の位置によって、以下の手順で進路を変更する。

  1. 重心位置が自身の進行方向に対して左右どちら側にあるかを判定
  2. 重心位置がが進行方向より右側にあるなら右へ、左側にあるなら左へ方向を少し変化させる。

これらの考え方はBoids 2.1の分離行動における回避動作と同じ。

コード内容

初期パラメータ定義

HTMLで定義する初期パラメータに、結合に関する以下の変数を追加する。

  • 結合の進行方向の変化(BD22_COHESION_ANGLE)

クラス変数

初期パラメータの保存のため、Creatureクラスのクラス変数を追加する。

パラメータのセッター

Controlerクラスに、Creatureクラス変数へのセッターを定義する。

パラメータのセット

HTMLで定義されたパラメータをControlerオブジェクトのセッターによってセットする。

Ceatureクラスの変更 – cohesion()メソッドの追加

Creatureクラスのmove()メソッドがcohesion()メソッドを呼び出すようにする。

coheion()メソッドを新たに定義する。

  • 速度の方向を変化させる回転行列のcos、sinに対応したローカル変数cssnを定義している
  • 重心位置への参照がclusterCenterプロパティに保存されるが、視野内に個体が存在しないときはnullとなる
  • 速度の回転方向は、右がマイナス方向、左がプラス方向となることに注意


↑ Boids 2.1のコード説明へ

↓ Boids 2.3のコード説明へ

Boids 2.1 – コード説明

概要

Boids 2.1では、いよいよBoidsのルールの一つ「分離(Separation)」を導入する。分離行動の考え方は、ここでは以下の通りとした。

  1. 視野内に個体が存在するとき、最も距離が近い個体を選択する
  2. その直近個体と反対方向に、自身の進行方向を変化させる

分離のアルゴリズム

視野

個体は自身の進行方向の左右90度以内、180度の視野角を持ち、その視野角内で一定距離以内の個体に反応するものとする。

視野内外の判定の概念は下図の通りで、個体Pは視野内と判定され、個体Qは視野外として無視される。

boids2x_perspective

視野内外判定の手順は以下の通り。

  1. 前後判定の方法により、視野角内の個体があればそれを選定
  2. その個体について\overline{\rm SP}} \leqq lならば次へ進む
  3. その個体が最も近いなら入れ替え

回避動作

回避対象が自身の進路の右にいるなら左に、進路の左にいるなら右に、方向ベクトルの角度を変更する。進路変更の角度は予め設定しておく。

boids2x_separation_avoidance

回避動作の手順は以下の通り。

  1. 左右判定の方法により、回避対象が進行方向の左右どちらにあるかを判定
  2. 回避対象が進行方向の左にあるなら右へ、右にあるなら左へ方向を少し変化させる。

ここで方向ベクトルの変化量θは予め設定しておき、これに対応するcos、sinによる回転行列を適用して方向を変える。cos、sinの値は、できるだけ計算量が少なくなるようにする。

コード内容

初期パラメータ定義

HTMLで定義する初期パラメータに、分離に関する以下の変数を追加する。

  • 分離に関する視野の深さ(BD21_VIEW_FIELD_LENGTH)
  • 回避行動の進行方向の変化(BD21_SEPARATION_ANGLE)

クラス変数

初期パラメータの保存のため、Creatureクラスのクラス変数を追加する。

パラメータのセッター

Controlerクラスに、Creatureクラス変数へのセッターを定義する。

パラメータのセット

HTMLで定義されたパラメータをControlerオブジェクトのセッターによってセットする。

Ceatureクラスの変更 – separation()メソッドの追加

Creatureクラスのmove()メソッドがseparation()メソッドを呼び出すようにする。

separation()メソッドを新たに定義する。

  • 速度の方向を変化させる回転行列のcos、sinに対応したローカル変数cssnを定義している
  • 最も近い個体への参照がnearestCreatureプロパティに保存されるが、視野内に個体が存在しないときはnullとなる
  • 速度の回転方向は、右がマイナス方向、左がプラス方向となることに注意

 


↑ Boids 2.0のコード説明へ

↓ Boids 2.2のコード説明へ

 

Boids 2.0 – コード説明

概要

Boids 2.0は以後のBoids 2.xシリーズの土台となるもので、Boids 1.2に対して以下を変更している。

  • 位置と速度を持ったCreatureクラスのうち、位置と速度の保持、互いの位置関係の判定に関する性質を汎用のMovingAgentクラスとしてまとめ、taustation-geo2dパッケージに含めた
  • 初期パラメータをHTMLのスクリプトに置き、再コンパイルしなくてもパラメータを変更しやすくなるようにした。

MovingAgentクラスの導入

CreatureクラスはMovingAgentクラスを継承し、それらのメソッドを利用する。

 MovingAgentのプロパティを継承するため、位置と速度の指定が変更。たとえばCreatureクラスのインスタンスがcreatureだとすると、以下のようになる。

  • 位置のx座標は、creature:pos.x
  • 位置のy座標は、creature:pos.y
  • 速度のx成分は、creature:v.x
  • 速度のy成分は、creature:v.y

HTMLでの初期パラメータ設定

概要

各種パラメータの設定を、CoffeeScriptの再コンパイルやアップロードをしなくても、HTMLで設定・変更できるようにした。

  • 必要なパラメータをHTMLのスクリプトで定義
  •  以下のパラメータをセットするセッターを、全てControlerクラスのメソッドとして集約
    • 個体に関するパラメータはCreatureのクラス変数
    • アニメーションのインターバルはControlerクラスのプロパティ
  • スクリプト読み込み時に、Controlerオブジェクトのセッターにグローバル・パラメータ変数を渡してパラメータ設定

初期パラメータ定義

HTMLにパラメータをグローバル変数としてスクリプト記述。

注意点は、スクリプトはJavascriptにコンパイルされているので、直接読み込まれるグローバル変数もJavascriptの変数として書くこと。特に各定義の文末にセミコロン(;)を付けること。

クラス変数

上記のパラメータのうち、個体の運動に関わるものを、Creatureクラスのクラス変数として定義。

なお、アニメーションのフレーム・インターバル(interval_sec)は、Controlerクラスのクラス変数として定義している。

パラメータのセッター

上記のクラス変数にパラメータをセットするセッターを、Controlerクラスのメソッドとして集約。

パラメーターのセット

スクリプト実行時に、上記セッターを通してグローバル変数のパラメータを設定する。

Boids 2.0の全コード


↓ Boids 2.1のコード説明へ