O --- O
libPEDSIM Documentation
[HOME] [EXAMPLES] [ECOSYSTEM] [DOCUMENTATION] [DOWNLOAD]
O --- O
ped_tree.cpp
1 //
2 // pedsim - A microscopic pedestrian simulation system.
3 // Copyright (c) by Christian Gloor
4 //
5 
6 #include "ped_agent.h"
7 #include "ped_scene.h"
8 #include "ped_tree.h"
9 
10 #include <cassert>
11 #include <cstddef>
12 
13 using namespace std;
14 
15 
19 Ped::Ttree::Ttree(Ped::Tscene *pscene, int pdepth, double px, double py, double pw, double ph) : scene(pscene) {
20  // more initializations here. not really necessary to put them into the initializator list, too.
21  isleaf = true;
22  x = px;
23  y = py;
24  w = pw;
25  h = ph;
26  depth = pdepth;
27  tree1 = NULL;
28  tree2 = NULL;
29  tree3 = NULL;
30  tree4 = NULL;
31 };
32 
33 
38  clear();
39 }
40 
41 
42 void Ped::Ttree::clear() {
43  if(isleaf) {
44  agents.clear();
45  }
46  else {
47  tree1->clear();
48  delete tree1;
49  tree2->clear();
50  delete tree2;
51  tree3->clear();
52  delete tree3;
53  tree4->clear();
54  delete tree4;
55  isleaf = true;
56  }
57 }
58 
59 
66  if (isleaf) {
67  agents.insert(a);
68  scene->treehash[a] = this;
69  }
70  else {
71  const Tvector pos = a->getPosition();
72  if ((pos.x >= x+w/2) && (pos.y >= y+h/2)) tree3->addAgent(a); // 3
73  if ((pos.x <= x+w/2) && (pos.y <= y+h/2)) tree1->addAgent(a); // 1
74  if ((pos.x >= x+w/2) && (pos.y <= y+h/2)) tree2->addAgent(a); // 2
75  if ((pos.x <= x+w/2) && (pos.y >= y+h/2)) tree4->addAgent(a); // 4
76  }
77 
78  if (agents.size() > 8) {
79  isleaf = false;
80  addChildren();
81  while (!agents.empty()) {
82  const Ped::Tagent *a = (*agents.begin());
83  const Tvector pos = a->getPosition();
84  if ((pos.x >= x+w/2) && (pos.y >= y+h/2)) tree3->addAgent(a); // 3
85  if ((pos.x <= x+w/2) && (pos.y <= y+h/2)) tree1->addAgent(a); // 1
86  if ((pos.x >= x+w/2) && (pos.y <= y+h/2)) tree2->addAgent(a); // 2
87  if ((pos.x <= x+w/2) && (pos.y >= y+h/2)) tree4->addAgent(a); // 4
88  agents.erase(a);
89  }
90  }
91 }
92 
93 
98  tree1 = new Ped::Ttree(scene, depth+1, x, y, w/2, h/2);
99  tree2 = new Ped::Ttree(scene, depth+1, x+w/2, y, w/2, h/2);
100  tree3 = new Ped::Ttree(scene, depth+1, x+w/2, y+h/2, w/2, h/2);
101  tree4 = new Ped::Ttree(scene, depth+1, x, y+h/2, w/2, h/2);
102 }
103 
104 
105 Ped::Ttree* Ped::Ttree::getChildByPosition(double xIn, double yIn) {
106  if((xIn <= x+w/2) && (yIn <= y+h/2))
107  return tree1;
108  if((xIn >= x+w/2) && (yIn <= y+h/2))
109  return tree2;
110  if((xIn >= x+w/2) && (yIn >= y+h/2))
111  return tree3;
112  if((xIn <= x+w/2) && (yIn >= y+h/2))
113  return tree4;
114 
115  // this should never happen
116  return NULL;
117 }
118 
119 
126  const Tvector pos = a->getPosition();
127  if ((pos.x < x) || (pos.x > (x+w)) || (pos.y < y) || (pos.y > (y+h))) {
128  scene->placeAgent(a);
129  agents.erase(a);
130  }
131 }
132 
133 
134 bool Ped::Ttree::removeAgent(const Ped::Tagent *a) {
135  if(isleaf) {
136  size_t removedCount = agents.erase(a);
137  return (removedCount > 0);
138  }
139  else {
140  const Tvector pos = a->getPosition();
141  return getChildByPosition(pos.x, pos.y)->removeAgent(a);
142  }
143 }
144 
145 
152  if (isleaf)
153  return agents.size();
154 
155  int count = 0;
156  count += tree1->cut();
157  count += tree2->cut();
158  count += tree3->cut();
159  count += tree4->cut();
160  if (count < 5) {
161  assert(tree1->isleaf == true);
162  assert(tree2->isleaf == true);
163  assert(tree3->isleaf == true);
164  assert(tree4->isleaf == true);
165  agents.insert(tree1->agents.begin(), tree1->agents.end());
166  agents.insert(tree2->agents.begin(), tree2->agents.end());
167  agents.insert(tree3->agents.begin(), tree3->agents.end());
168  agents.insert(tree4->agents.begin(), tree4->agents.end());
169  isleaf = true;
170  for (set<const Ped::Tagent*>::iterator it = agents.begin(); it != agents.end(); ++it) {
171  const Tagent *a = (*it);
172  scene->treehash[a] = this;
173  }
174  delete tree1;
175  delete tree2;
176  delete tree3;
177  delete tree4;
178  }
179  return count;
180 }
181 
182 
188 set<const Ped::Tagent*> Ped::Ttree::getAgents() const {
189  if (isleaf)
190  return agents;
191 
192  set<const Ped::Tagent*> ta;
193  set<const Ped::Tagent*> t1 = tree1->getAgents();
194  set<const Ped::Tagent*> t2 = tree2->getAgents();
195  set<const Ped::Tagent*> t3 = tree3->getAgents();
196  set<const Ped::Tagent*> t4 = tree4->getAgents();
197  ta.insert(t1.begin(), t1.end());
198  ta.insert(t2.begin(), t2.end());
199  ta.insert(t3.begin(), t3.end());
200  ta.insert(t4.begin(), t4.end());
201  return ta;
202 }
203 
204 
205 void Ped::Ttree::getAgents(list<const Ped::Tagent*>& outputList) const {
206  if(isleaf) {
207  for(const Ped::Tagent* currentAgent : agents)
208  outputList.push_back(currentAgent);
209  }
210  else {
211  tree1->getAgents(outputList);
212  tree2->getAgents(outputList);
213  tree3->getAgents(outputList);
214  tree4->getAgents(outputList);
215  }
216 }
217 
218 
226 bool Ped::Ttree::intersects(double px, double py, double pr) const {
227  if (((px+pr) > x) && ((px-pr) < (x+w)) && ((py+pr) > y) && ((py-pr) < (y+h)))
228  return true; // x+-r/y+-r is inside
229  else
230  return false;
231 }
virtual bool intersects(double px, double py, double pr) const
Definition: ped_tree.cpp:226
virtual ~Ttree()
Definition: ped_tree.cpp:37
virtual void addAgent(const Ped::Tagent *a)
Definition: ped_tree.cpp:65
virtual int cut()
Definition: ped_tree.cpp:151
virtual void addChildren()
Definition: ped_tree.cpp:97
Ttree(Ped::Tscene *scene, int depth, double x, double y, double w, double h)
Definition: ped_tree.cpp:19
virtual void moveAgent(const Ped::Tagent *a)
Definition: ped_tree.cpp:125
virtual set< const Ped::Tagent * > getAgents() const
Definition: ped_tree.cpp:188
O --- O

⁠(c) Christian Gloor [ c|h|g|l|o|o|r|@|s|i|l|m|a|r|i|l|.|o|r|g| ]