Skip to content

Commit

Permalink
formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
jhako committed Feb 9, 2016
1 parent c587f6c commit edbbc55
Show file tree
Hide file tree
Showing 12 changed files with 495 additions and 493 deletions.
100 changes: 50 additions & 50 deletions src/behavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,80 +17,80 @@ const double KF = 0.3; //逃避

vec2d Behavior::separation(Fish* self, World* p_world, std::list<Fish*>& neighbors)
{
if(neighbors.size() == 0)
return vec2d();
if (neighbors.size() == 0)
return vec2d();

//近傍の各対象に対し、距離に反比例する力を計算
vec2d force;
for(std::list<Fish*>::iterator it = neighbors.begin();
//近傍の各対象に対し、距離に反比例する力を計算
vec2d force;
for (std::list<Fish*>::iterator it = neighbors.begin();
it != neighbors.end(); ++it)
{
vec2d tovec = self->get_pos() - (*it)->get_pos();
force += tovec.norm() / tovec.length();
}
return force*KS;
{
vec2d tovec = self->get_pos() - (*it)->get_pos();
force += tovec.norm() / tovec.length();
}
return force*KS;
}


vec2d Behavior::alignment(Fish* self, World* p_world, std::list<Fish*>& neighbors)
{
if(neighbors.size() == 0) return vec2d();
//近傍の全対象の向きの平均を計算し、それに合わせるような力を計算
vec2d ave;
for(std::list<Fish*>::iterator it = neighbors.begin();
if (neighbors.size() == 0) return vec2d();

//近傍の全対象の向きの平均を計算し、それに合わせるような力を計算
vec2d ave;
for (std::list<Fish*>::iterator it = neighbors.begin();
it != neighbors.end(); ++it)
{
ave += (*it)->get_dire();
}
ave /= neighbors.size();
return (ave - self->get_dire())*KA;
{
ave += (*it)->get_dire();
}
ave /= neighbors.size();
return (ave - self->get_dire())*KA;

}

vec2d Behavior::cohesion(Fish* self, World* p_world, std::list<Fish*>& neighbors)
{
if(neighbors.size() == 0) return vec2d();
if (neighbors.size() == 0) return vec2d();

//近傍全対象の中心を計算し、そこに向かう力を与える
vec2d center;
int num = 0;
for(std::list<Fish*>::iterator it = neighbors.begin();
//近傍全対象の中心を計算し、そこに向かう力を与える
vec2d center;
int num = 0;
for (std::list<Fish*>::iterator it = neighbors.begin();
it != neighbors.end(); ++it)
{
center += (*it)->get_pos();
++num;
}
center /= num;
return (center - self->get_pos()).norm()*self->get_maxspeed()*KC;
{
center += (*it)->get_pos();
++num;
}
center /= num;
return (center - self->get_pos()).norm()*self->get_maxspeed()*KC;
}

vec2d Behavior::randomwalk(Fish* self, World* p_world)
{
//前方に半径rの円を仮定し、その円上にあるランダムな点に
//向かう力を計算する(振動をさけ、滑らかな動きを実現するため)
vec2d center = self->get_pos() + self->get_dire() * 0.5;
double r = 0.2;
double rd = 0.4;
rw_rad += (double)(rand())/RAND_MAX * rd - rd/2.0;
return (center+vec2d(0,r).rotate(rw_rad) - self->get_pos())*KR;
//前方に半径rの円を仮定し、その円上にあるランダムな点に
//向かう力を計算する(振動をさけ、滑らかな動きを実現するため)
vec2d center = self->get_pos() + self->get_dire() * 0.5;
double r = 0.2;
double rd = 0.4;
rw_rad += (double)(rand()) / RAND_MAX * rd - rd / 2.0;
return (center + vec2d(0, r).rotate(rw_rad) - self->get_pos())*KR;
}

vec2d Behavior::seek(Fish* self, World* p_world, Fish* target)
{
//対象の移動先を計算し、そこに向かうような力を与える
//ただし、滑らかな回転を行うように移動先を考慮する(係数lookahead)
vec2d totarget = target->get_pos() - self->get_pos();
double lookahead = totarget.length() / (self->get_maxspeed() + target->get_velocity().length());
vec2d tovec = target->get_pos() + target->get_velocity() * lookahead;
return (tovec - self->get_pos()).norm()*self->get_maxspeed() * KSe;
//対象の移動先を計算し、そこに向かうような力を与える
//ただし、滑らかな回転を行うように移動先を考慮する(係数lookahead)
vec2d totarget = target->get_pos() - self->get_pos();
double lookahead = totarget.length() / (self->get_maxspeed() + target->get_velocity().length());
vec2d tovec = target->get_pos() + target->get_velocity() * lookahead;
return (tovec - self->get_pos()).norm()*self->get_maxspeed() * KSe;
}

vec2d Behavior::flee(Fish* self, World* p_world, Fish* enemy)
{
//対象から逃避するような力を計算(Behavior::seekと同様の原理)
vec2d toenemy = enemy->get_pos() - self->get_pos();
double lookahead = toenemy.length() / (self->get_maxspeed() + enemy->get_velocity().length());
vec2d tovec = enemy->get_pos() + enemy->get_velocity() * lookahead;
return (self->get_pos() - enemy->get_pos()).norm()*self->get_maxspeed() * KF;
//対象から逃避するような力を計算(Behavior::seekと同様の原理)
vec2d toenemy = enemy->get_pos() - self->get_pos();
double lookahead = toenemy.length() / (self->get_maxspeed() + enemy->get_velocity().length());
vec2d tovec = enemy->get_pos() + enemy->get_velocity() * lookahead;
return (self->get_pos() - enemy->get_pos()).norm()*self->get_maxspeed() * KF;
}
30 changes: 15 additions & 15 deletions src/behavior.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ class World;
//--Fishの振る舞いを計算するクラス--
class Behavior
{
//randomwalkにおける円周上の点の以前の位置
double rw_rad;
//randomwalkにおける円周上の点の以前の位置
double rw_rad;

public:
Behavior(): rw_rad(0.0){}
Behavior() : rw_rad(0.0){}

//分離行動
vec2d separation(Fish* self, World* p_world, std::list<Fish*>& neighbors);
//整列行動
vec2d alignment(Fish* self, World* p_world, std::list<Fish*>& neighbors);
//結合行動
vec2d cohesion(Fish* self, World* p_world, std::list<Fish*>& neighbors);
//追従行動
vec2d seek(Fish* self, World* p_world, Fish* target);
//逃避行動
vec2d flee(Fish* self, World* p_world, Fish* enemy);
//放浪行動
vec2d randomwalk(Fish* self, World* p_world);
//分離行動
vec2d separation(Fish* self, World* p_world, std::list<Fish*>& neighbors);
//整列行動
vec2d alignment(Fish* self, World* p_world, std::list<Fish*>& neighbors);
//結合行動
vec2d cohesion(Fish* self, World* p_world, std::list<Fish*>& neighbors);
//追従行動
vec2d seek(Fish* self, World* p_world, Fish* target);
//逃避行動
vec2d flee(Fish* self, World* p_world, Fish* enemy);
//放浪行動
vec2d randomwalk(Fish* self, World* p_world);
};
186 changes: 93 additions & 93 deletions src/fish.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,122 +14,122 @@ const int RADIUS = 50;

void Fish::init(vec2d pos_, vec2d velo_)
{
pos = pos_; velo = velo_; dire = vec2d(1.0,1.0);
behavior = new Behavior();
static int staticID = 0;
id = staticID++;
partidx = -99;
pos = pos_; velo = velo_; dire = vec2d(1.0, 1.0);
behavior = new Behavior();
static int staticID = 0;
id = staticID++;
partidx = -99;
}

Fish::Fish(vec2d pos_, vec2d velo_)
: max_speed(2.3)
: max_speed(2.3)
{
init(pos_, velo_);
static TexImage img("osakana.png");
tex = &img;
init(pos_, velo_);
static TexImage img("osakana.png");
tex = &img;
}

Fish::Fish(vec2d pos_, vec2d velo_, TexImage* tex_, double maxspd)
: tex(tex_), max_speed(maxspd)
: tex(tex_), max_speed(maxspd)
{
init(pos_, velo_);
init(pos_, velo_);
}

Fish::~Fish()
{
delete behavior;
delete behavior;
}

void Fish::update(World* p_world)
{
//近傍にいる魚を調べ、neighborsに追加する
std::list<Fish*> neighbors;
std::vector<Fish*> lfish = p_world->get_neighborfishes(partidx);
for(int i = 0; i < lfish.size(); ++i)
{
double lsq = (pos - lfish.at(i)->get_pos()).lengthsq();

if(lsq < 0.0001)
continue; //自分自身
if(lsq < RADIUS*RADIUS)
//近傍にいる魚を調べ、neighborsに追加する
std::list<Fish*> neighbors;
std::vector<Fish*> lfish = p_world->get_neighborfishes(partidx);
for (int i = 0; i < lfish.size(); ++i)
{
neighbors.push_back(lfish.at(i));
double lsq = (pos - lfish.at(i)->get_pos()).lengthsq();

if (lsq < 0.0001)
continue; //自分自身
if (lsq < RADIUS*RADIUS)
{
neighbors.push_back(lfish.at(i));
}
}
}

//最も近傍にいる敵を探す
Fish* nearest_enemy = NULL;
std::vector<Shark*>& lshark = p_world->get_sharks();
for(int i = 0; i < lshark.size(); ++i)
{
double lsq = (pos - lshark.at(i)->get_pos()).lengthsq();
if(lsq < RADIUS*RADIUS)

//最も近傍にいる敵を探す
Fish* nearest_enemy = NULL;
std::vector<Shark*>& lshark = p_world->get_sharks();
for (int i = 0; i < lshark.size(); ++i)
{
double lsq = (pos - lshark.at(i)->get_pos()).lengthsq();
if (lsq < RADIUS*RADIUS)
{
if (!nearest_enemy)
{
nearest_enemy = lshark.at(i);
continue;
}
if (lsq < (nearest_enemy->get_pos() - pos).lengthsq())
{
nearest_enemy = lshark.at(i);
}
}
}

vec2d force;
double fmax = 6.65;

//敵からの逃避行動、分離・整列・結合行動(群れ)、放浪行動を行う
//上から順に優先度が高く、作用する力がfmaxを超えた時点で計算終了
for (;;)
{
if(!nearest_enemy)
{
nearest_enemy = lshark.at(i);
continue;
}
if(lsq < (nearest_enemy->get_pos() - pos).lengthsq())
{
nearest_enemy = lshark.at(i);
}
if (nearest_enemy)
force += behavior->flee(this, p_world, nearest_enemy);
if (force.lengthsq() > fmax*fmax) break;
force += behavior->separation(this, p_world, neighbors);
if (force.lengthsq() > fmax*fmax) break;
force += behavior->alignment(this, p_world, neighbors);
if (force.lengthsq() > fmax*fmax) break;
force += behavior->cohesion(this, p_world, neighbors);
if (force.lengthsq() > fmax*fmax) break;
force += behavior->randomwalk(this, p_world);
break;
}
}

vec2d force;
double fmax = 6.65;

//敵からの逃避行動、分離・整列・結合行動(群れ)、放浪行動を行う
//上から順に優先度が高く、作用する力がfmaxを超えた時点で計算終了
for(;;)
{
if(nearest_enemy)
force += behavior->flee(this, p_world, nearest_enemy);
if(force.lengthsq() > fmax*fmax) break;
force += behavior->separation(this, p_world, neighbors);
if(force.lengthsq() > fmax*fmax) break;
force += behavior->alignment(this, p_world, neighbors);
if(force.lengthsq() > fmax*fmax) break;
force += behavior->cohesion(this, p_world, neighbors);
if(force.lengthsq() > fmax*fmax) break;
force += behavior->randomwalk(this, p_world);
break;
}

//作用する力をfmaxに丸める
if(force.lengthsq() > fmax*fmax) force = force.norm()*fmax;

double M = 1.20; //魚の質量

velo += force / M;

//向きを更新
if(velo.lengthsq() > 0.001)
dire = velo.norm();

//速度を最大速度で丸める
if(velo.lengthsq() > max_speed*max_speed)
velo = velo.norm()*max_speed;

//位置の更新
pos += velo;

//端はない(上下左右端で接続されている)
if(pos.x < 0)
pos.x += p_world->get_width();
if(pos.x > p_world->get_width())
pos.x -= p_world->get_width();
if(pos.y < 0)
pos.y += p_world->get_height();
if(pos.y > p_world->get_height())
pos.y -= p_world->get_height();

//作用する力をfmaxに丸める
if (force.lengthsq() > fmax*fmax) force = force.norm()*fmax;

double M = 1.20; //魚の質量

velo += force / M;

//向きを更新
if (velo.lengthsq() > 0.001)
dire = velo.norm();

//速度を最大速度で丸める
if (velo.lengthsq() > max_speed*max_speed)
velo = velo.norm()*max_speed;

//位置の更新
pos += velo;

//端はない(上下左右端で接続されている)
if (pos.x < 0)
pos.x += p_world->get_width();
if (pos.x > p_world->get_width())
pos.x -= p_world->get_width();
if (pos.y < 0)
pos.y += p_world->get_height();
if (pos.y > p_world->get_height())
pos.y -= p_world->get_height();
}


void Fish::render(World* p_world)
{
//向きに合わせて画像を回転させ、描画
tex->render(pos.x, pos.y,
atan2(dire.y, dire.x)+3.14159265358979323846/2.0);
//向きに合わせて画像を回転させ、描画
tex->render(pos.x, pos.y,
atan2(dire.y, dire.x) + 3.14159265358979323846 / 2.0);
}
Loading

0 comments on commit edbbc55

Please sign in to comment.