Flocking

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 간 떨어지도록 유도

출처

Categories: ,

Updated: