MovementGenerator.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include "MovementGenerator.h"
00025
00026 std::ostream& operator<<(std::ostream& Stream, const NeighborMapEntry& e)
00027 {
00028 return Stream << "Positon: " << e.position << " Direction: " << e.direction;
00029 }
00030
00031 MovementGenerator::MovementGenerator(double areaDimension, double speed, NeighborMap *Neighbors, GlobalCoordinator* coordinator, CollisionList* CollisionRect)
00032 {
00033 this->areaDimension = areaDimension;
00034 this->speed = speed;
00035 this->Neighbors = Neighbors;
00036 this->coordinator = coordinator;
00037 this->CollisionRect = CollisionRect;
00038
00039 Vector2D center(areaDimension / 2, areaDimension / 2);
00040 position.x = uniform(0.0, areaDimension);
00041 position.y = uniform(0.0, areaDimension);
00042 direction = center - position;
00043 direction.normalize();
00044 if(CollisionRect != NULL) {
00045 generateScenery(coordinator->getSeed());
00046 }
00047 }
00048
00049 Vector2D MovementGenerator::getPosition()
00050 {
00051 return position;
00052 }
00053
00054 bool MovementGenerator::testBounds()
00055 {
00056 bool obstacleHit = false;
00057
00058 if(position.x < 0.0) {
00059 position.x = 0.0;
00060 }
00061 if(position.x > areaDimension) {
00062 position.x = areaDimension;
00063 }
00064 if(position.y < 0.0) {
00065 position.y = 0.0;
00066 }
00067 if(position.y > areaDimension) {
00068 position.y = areaDimension;
00069 }
00070
00071 double cosAngle = direction.x;
00072 SCDir scDirection;
00073 if(cosAngle > 0.71) {
00074 scDirection = DIR_RIGHT;
00075 }
00076 else if(cosAngle < -0.71) {
00077 scDirection = DIR_LEFT;
00078 }
00079 else if(direction.y > 0.0) {
00080 scDirection = DIR_UP;
00081 }
00082 else {
00083 scDirection = DIR_DOWN;
00084 }
00085
00086 if(CollisionRect != NULL) {
00087 CollisionList::iterator i;
00088 for(i = CollisionRect->begin(); i != CollisionRect->end(); ++i) {
00089 if(i->collide(position)) {
00090 switch(scDirection) {
00091 case DIR_UP:
00092 position.y = i->bottom();
00093 direction.x = 1.0;
00094 direction.y = 0.0;
00095 break;
00096 case DIR_DOWN:
00097 position.y = i->top();
00098 direction.x = -1.0;
00099 direction.y = 0.0;
00100 break;
00101 case DIR_LEFT:
00102 position.x = i->right();
00103 direction.x = 0.0;
00104 direction.y = 1.0;
00105 break;
00106 case DIR_RIGHT:
00107 position.x = i->left();
00108 direction.x = 0.0;
00109 direction.y = -1.0;
00110 break;
00111 }
00112 obstacleHit = true;
00113 }
00114 }
00115 }
00116
00117 return obstacleHit;
00118 }
00119
00120 void MovementGenerator::flock()
00121 {
00122 Vector2D separation, alignment, cohesion, toTarget;
00123 int NeighborCount = 0;
00124
00125 for(itNeighbors = Neighbors->begin(); itNeighbors != Neighbors->end(); ++itNeighbors)
00126 if(position.distanceSqr(itNeighbors->second.position) < 2.5 && direction.cosAngle(itNeighbors->second.position - position) > -0.75) {
00127 separation += position - itNeighbors->second.position;
00128 alignment += itNeighbors->second.direction;
00129 cohesion += itNeighbors->second.position;
00130 ++NeighborCount;
00131 }
00132
00133 if(NeighborCount > 0) {
00134 cohesion /= (double)NeighborCount;
00135 cohesion = cohesion - position;
00136 separation.normalize();
00137 alignment.normalize();
00138 cohesion.normalize();
00139 }
00140 toTarget = target - position;
00141 toTarget.normalize();
00142
00143 direction = separation * 0.4 + alignment * 0.1 + cohesion * 0.35 + toTarget * 0.25;
00144 direction.normalize();
00145 }
00146
00147 void MovementGenerator::generateScenery(unsigned int seed)
00148 {
00149 int dimension = (int)(areaDimension - 10.0);
00150 int sceneryType;
00151 double sceneryX, sceneryY;
00152
00153 srand(seed);
00154
00155 for(int i = 0; i < dimension; i += 10) {
00156 for(int j = 0; j < dimension; j+= 10) {
00157 sceneryType = rand() % 3;
00158 switch(sceneryType) {
00159 case 0: {
00160
00161 sceneryX = rand();
00162 sceneryY = rand();
00163 } break;
00164 case 1: {
00165 sceneryX = 1 + (rand() % 8);
00166 sceneryY = 1 + (rand() % 8);
00167 CollisionRect->insert(CollisionRect->begin(), BoundingBox2D(i + sceneryX - 0.25, j + sceneryY - 0.5, i + sceneryX + 1.25, j + sceneryY + 0.25));
00168 } break;
00169 case 2: {
00170 sceneryX = 1 + (rand() % 6);
00171 sceneryY = 1 + (rand() % 5);
00172 CollisionRect->insert(CollisionRect->begin(), BoundingBox2D(i + sceneryX, j + sceneryY + 2.0, i + sceneryX + 3.0, j + sceneryY + 3.5));
00173 } break;
00174 }
00175 }
00176 }
00177 }