Boid (bird-oid object)

  • 인공 생명체라는 의미
  • 새처럼 모여 규칙에 따라 군집행동을 하는 각 개체

Flocking의 3요소

결합 Cohesion

Vector Boid::Cohesion(const vector<Boid>& Boids)
{
  float neighbordist = 50; // 이웃 Boid에 포함시킬 최대 반경
  Vector sum(0, 0);
  int count = 0;

  // 각 Boid의 위치를 모두 총함
  for (int i = 0; i < Boids.size(); i++) {
    float d = location.distance(Boids[i].location);
    if ((d > 0) && (d < neighbordist)) {
      sum.addVector(Boids[i].location);
      count++;
    }
  }

  // 평균 위치 계싼해서 그 위치를 추적
  if (count > 0) {
    sum.divScalar(count);
    return seek(sum);
  } else {
    Vector temp(0,0);
    return temp;
  }
}
  • Boid가 주변 Boid의 곁으로 가려는 성질
  • 모든 Boid 위치의 평균값을 기준으로 각 에이전트들을 일정 반경에 배치

정렬 Alignment

Vector Boid::Alignment(const vector<Boid>& Boids)
{
  float neighbordist = 50; // 이웃 Boid에 포함시킬 최대 반경

  Vector sum(0, 0);
  int count = 0;

  // 각 Boid의 방향을 모두 총함
  for (int i = 0; i < Boids.size(); i++) {
    float d = location.distance(Boids[i].location);
    if ((d > 0) && (d < neighbordist)) { 
      sum.addVector(Boids[i].velocity);
      count++;
    }
  }

  // If there are boids close enough for alignment...
  if (count > 0) {
    sum.divScalar((float)count);// velocity 평균값
    sum.normalize();            // velocity를 normalize
    sum.mulScalar(maxSpeed);    // 여기에 Boid 객체의 고유 maxSpeed 곱
        
    // Steer = Desired - Velocity
    Vector steer;
    steer = steer.subTwoVector(sum, velocity); //sum = desired(average)
    steer.limit(maxForce);
    return steer;
  } else {
    Vector temp(0, 0);
    return temp;
  }
}
  • 한 Boid가 진행하는 방향이 다른 Boid들의 방향과 유사하도록 조정

분산 Separation

Vector Boid::Separation(const vector<Boid>& boids)
{
  // 이웃 Boid와의 최소 유지 거리
  float desiredseparation = 20;
  Vector steer(0, 0);
  int count = 0;
    
  // 각 Boid와의 거리를 모두 총함
  for (int i = 0; i < boids.size(); i++) {
    float d = location.distance(boids[i].location);
    // 이웃 Boid가 너무 가까우면 거리 벌림
    if ((d > 0) && (d < desiredseparation)) {
      Vector diff(0,0);
      diff = diff.subTwoVector(location, boids[i].location);
      diff.normalize();
      diff.divScalar(d);      // Weight by distance
      steer.addVector(diff);
      count++;
    }
  }
  // 평균 거리를 계산
  if (count > 0)
    steer.divScalar((float)count);
  if (steer.magnitude() > 0) {
    // Steering = Desired - Velocity
    steer.normalize();
    steer.mulScalar(maxSpeed);
    steer.subVector(velocity);
    steer.limit(maxForce);
  }
  return steer;
}
  • Boid가 이웃과 항상 적정 거리를 두어 떨어져 있도록 하는 것
  • Alignment 역시 진행 방향(벡터)을 조정하지만, Separation은 Boid 간 떨어지도록 유도

출처