OverSim
MovementGenerator.cc
Go to the documentation of this file.
1 //
2 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 //
18 
24 #include "MovementGenerator.h"
25 
26 std::ostream& operator<<(std::ostream& Stream, const NeighborMapEntry& e)
27 {
28  return Stream << "Positon: " << e.position << " Direction: " << e.direction;
29 }
30 
31 MovementGenerator::MovementGenerator(double areaDimension, double speed, NeighborMap *Neighbors, GlobalCoordinator* coordinator, CollisionList* CollisionRect)
32 {
33  this->areaDimension = areaDimension;
34  this->speed = speed;
35  this->Neighbors = Neighbors;
36  this->coordinator = coordinator;
37  this->CollisionRect = CollisionRect;
38 
39  Vector2D center(areaDimension / 2, areaDimension / 2);
40  position.x = uniform(0.0, areaDimension);
41  position.y = uniform(0.0, areaDimension);
42  direction = center - position;
44  if(CollisionRect != NULL) {
45  generateScenery(coordinator->getSeed());
46  }
47 }
48 
50 {
51  return position;
52 }
53 
55 {
56  bool obstacleHit = false;
57 
58  if(position.x < 0.0) {
59  position.x = 0.0;
60  }
61  if(position.x > areaDimension) {
63  }
64  if(position.y < 0.0) {
65  position.y = 0.0;
66  }
67  if(position.y > areaDimension) {
69  }
70 
71  double cosAngle = direction.x;
72  SCDir scDirection;
73  if(cosAngle > 0.71) {
74  scDirection = DIR_RIGHT;
75  }
76  else if(cosAngle < -0.71) {
77  scDirection = DIR_LEFT;
78  }
79  else if(direction.y > 0.0) {
80  scDirection = DIR_UP;
81  }
82  else {
83  scDirection = DIR_DOWN;
84  }
85 
86  if(CollisionRect != NULL) {
87  CollisionList::iterator i;
88  for(i = CollisionRect->begin(); i != CollisionRect->end(); ++i) {
89  if(i->collide(position)) {
90  switch(scDirection) {
91  case DIR_UP:
92  position.y = i->bottom();
93  direction.x = 1.0;
94  direction.y = 0.0;
95  break;
96  case DIR_DOWN:
97  position.y = i->top();
98  direction.x = -1.0;
99  direction.y = 0.0;
100  break;
101  case DIR_LEFT:
102  position.x = i->right();
103  direction.x = 0.0;
104  direction.y = 1.0;
105  break;
106  case DIR_RIGHT:
107  position.x = i->left();
108  direction.x = 0.0;
109  direction.y = -1.0;
110  break;
111  }
112  obstacleHit = true;
113  }
114  }
115  }
116 
117  return obstacleHit;
118 }
119 
121 {
122  Vector2D separation, alignment, cohesion, toTarget;
123  int NeighborCount = 0;
124 
125  for(itNeighbors = Neighbors->begin(); itNeighbors != Neighbors->end(); ++itNeighbors)
126  if(position.distanceSqr(itNeighbors->second.position) < 2.5 && direction.cosAngle(itNeighbors->second.position - position) > -0.75) {
127  separation += position - itNeighbors->second.position;
128  alignment += itNeighbors->second.direction;
129  cohesion += itNeighbors->second.position;
130  ++NeighborCount;
131  }
132 
133  if(NeighborCount > 0) {
134  cohesion /= (double)NeighborCount;
135  cohesion = cohesion - position;
136  separation.normalize();
137  alignment.normalize();
138  cohesion.normalize();
139  }
140  toTarget = target - position;
141  toTarget.normalize();
142 
143  direction = separation * 0.4 + alignment * 0.1 + cohesion * 0.35 + toTarget * 0.25;
145 }
146 
147 void MovementGenerator::generateScenery(unsigned int seed)
148 {
149  int dimension = (int)(areaDimension - 10.0);
150  int sceneryType;
151  double sceneryX, sceneryY;
152 
153  srand(seed);
154 
155  for(int i = 0; i < dimension; i += 10) {
156  for(int j = 0; j < dimension; j+= 10) {
157  sceneryType = rand() % 3;
158  switch(sceneryType) {
159  case 0: { // mud
160  // do nothing except calling rand() for deterministic scenery generation
161  sceneryX = rand();
162  sceneryY = rand();
163  } break;
164  case 1: { // rock
165  sceneryX = 1 + (rand() % 8);
166  sceneryY = 1 + (rand() % 8);
167  CollisionRect->insert(CollisionRect->begin(), BoundingBox2D(i + sceneryX - 0.25, j + sceneryY - 0.5, i + sceneryX + 1.25, j + sceneryY + 0.25));
168  } break;
169  case 2: { // tree
170  sceneryX = 1 + (rand() % 6);
171  sceneryY = 1 + (rand() % 5);
172  CollisionRect->insert(CollisionRect->begin(), BoundingBox2D(i + sceneryX, j + sceneryY + 2.0, i + sceneryX + 3.0, j + sceneryY + 3.5));
173  } break;
174  }
175  }
176  }
177 }