BOIDSv1.00 ~集ウ~ HOME > BOIDSとは > BOIDSv1.00 ~集ウ~

09.16 BOIDSv1.00 ~集ウ~

いわしは魚眼レンズである為後方の一部以外殆どというお話をしました。しかし人間も同じですが例えば電車に乗って車窓の景色を見た場合、すぐ横のものは移動しているため見えにくく遠くのものは見やすい傾向にあります。そして前回の話から視界は広くても視力は0.6~1.0くらいとあまりよくないことから、前方の一部しか実は見えていないのではないかと思い、今回はBOIDS「結合」論理を前方の一部の視界に変更し試してみました。


下記の論理を試しました。

<案1>
前方視界中の特定範囲内にあるポッド重心を算出し旋回する。


/************************************************************************
* 結合(Cohesion)の導入                         *
* 前方視野内の全個体重心に向かって速度を変更する            *
************************************************************************/
void cohesion(int index,Iwashi_str *IwashiThis)
{
  double     isAngle;
  int       isLeft;
  Vector_str   Vec;
  int       n;

  if (checkBox6->Checked == false)
  {
    centerIwashi.Pos.x = Esa.Pos.x;
    centerIwashi.Pos.y = Esa.Pos.y;
    n = 1;
  }
  else
  {
    centerIwashi.Pos.x = 0.0;
    centerIwashi.Pos.y = 0.0;
    n = 0;
  }

  for (int i = 0; i < iwashi_kazu; i++)
  {
    if (i != index)
    {
      isCrosDot(IwashiThis , &iwashi[i] , &isAngle , &isLeft);
        /* 角度と左右判定 */
      if (fabs(isAngle) <= _COHESION_VIEW_ANGLE)
      {
        n++;
        centerIwashi.Pos.x += iwashi[i].Pos.x;
        centerIwashi.Pos.y += iwashi[i].Pos.y;
      }
    }
  }

  if (n != 0)
  {
    centerIwashi.Pos.x /= n;
    centerIwashi.Pos.y /= n;

    if (isRight(&centerIwashi ,IwashiThis ))
    {
      Vec.x = IwashiThis->Vec.x * cos_cohesion + IwashiThis->Vec.y * sin_cohesion;
      Vec.y = -IwashiThis->Vec.x * sin_cohesion + IwashiThis->Vec.y * cos_cohesion;
    }
    else
    {
      Vec.x = IwashiThis->Vec.x * cos_cohesion - IwashiThis->Vec.y * sin_cohesion;
      Vec.y = IwashiThis->Vec.x * sin_cohesion + IwashiThis->Vec.y * cos_cohesion;
    }

    IwashiThis->Vec.x = Vec.x;
    IwashiThis->Vec.y = Vec.y;
  }
}



<案2>
視界内ポッドの先特定距離で最も近接しているポッドの方向へ旋回する。


/************************************************************************
* 結合(Cohesion)の導入                         *
* 前方視野内の全個体重心に向かって速度を変更する            *
************************************************************************/
void iwashi_cohesion(int index,Iwashi_str *IwashiThis)
{
  double     isAngle;
  int       isLeft;
  double     dist;
  double     distMIN;
  int       noMIN;
  int       n;
  Vector_str   Vec;

  mureIwashi.Vec.x = 0;
  mureIwashi.Vec.y = 0;

  n = 0;
  distMIN = (PodSize + _SP_COHESION_VIEW_DIST);
  dist = 0;
  noMIN = 0;
  for (int i = 0; i < iwashi_kazu; i++)
  {
    if (i != index)
    {
      isCrosDot(IwashiThis , &iwashi[i] , &isAngle , &isLeft);
      if (fabs(isAngle) <= _SP_COHESION_TURN_ANGLE)
      { /* 前方内にいる場合 */
        dist = distanceTo(&iwashi[i].Pos, &IwashiThis->Pos);
        if ( dist < distMIN )
        {
          n++;
          distMIN = dist;
          noMIN = i;
        }
      }
    }
  }

  if (n != 0)
  {
    if ( isRight( &iwashi[noMIN - 1], IwashiThis) == true)
    {
      Vec.x = IwashiThis->Vec.x * cos_sp_cohesion + IwashiThis->Vec.y * sin_sp_cohesion;
      Vec.y = -IwashiThis->Vec.x * sin_sp_cohesion + IwashiThis->Vec.y * cos_sp_cohesion;
    }
    else
    {
      Vec.x = IwashiThis->Vec.x * cos_sp_cohesion - IwashiThis->Vec.y * sin_sp_cohesion;
      Vec.y = IwashiThis->Vec.x * sin_sp_cohesion + IwashiThis->Vec.y * cos_sp_cohesion;
    }

    IwashiThis->Vec.x = Vec.x;
    IwashiThis->Vec.y = Vec.y;
  }
}





★結 果
結果は画面左のチェックボックス中の「結合」=案1、「iwashi」=案2のキャンセルを表します。これを約一分間隔で切り替えた動画を見てください。(この際「分離」「整合」等その他の処理は実行していません)

予想では案2は「金魚の糞」のように追尾型になるような気がしましたが、 結果的にいうと案1の方が効きが良かったのです。この予想を覆した大きな要因は個体数が多いということではないかと考えます。複数が隣接しているとターゲットが1つに限定できず瞬間的に複数に変わるため全体でみると追尾していないのと同じということです。一方、案1は個体数が増えれば増えるほど「重心位置」の急激な変化はなく、時間経過とともに一定の軌跡移動へ変化するため追尾しやすく、他の個体も同じ位置周辺を狙うようになりターゲットが絞りやすくなるのではないかと思われます。

ちょっと別の視点で考えてみます。要するに鰯を食べようとするものも同じ論理で複数になればなるほど食べようとしているものも「1つに定まらず」食べられないという、「群れ」の論理につながるのではないかと想像します。名古屋港水族館でも同じような説明をしえちました。

しかしトルネードにはならないなぁ。

【BOIDS MODEL V1 00 ~集ウ~】



HOME   > BOIDSv1.00 ~避ケル~ > BOIDSv1.00 ~集ウ~