00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef OCTREE_HPP
00021 #define OCTREE_HPP
00022
00023 #include <TinyVector.hpp>
00024 #include <StaticPow.hpp>
00025
00026 #include <ErrorHandler.hpp>
00027
00028 #include <stack>
00029
00030 template <typename Content,
00031 size_t GivenDimension>
00032 class Octree
00033 {
00034 public:
00035 class iterator;
00036
00037 enum {
00038 Dimension = GivenDimension
00039 };
00040
00041 private:
00042 class __SubTree;
00043
00044 class __Node
00045 {
00046 public:
00047 enum Type {
00048 subtree,
00049 leaf
00050 };
00051
00052 virtual const typename __Node::Type type() const = 0;
00053
00054 __Node()
00055 {
00056 ;
00057 }
00058
00059 __Node(const __Node& n)
00060 {
00061 ;
00062 }
00063
00064 virtual ~__Node()
00065 {
00066 ;
00067 }
00068 };
00069
00070 class __Leaf
00071 : public __Node
00072 {
00073 private:
00074 const TinyVector<Dimension, real_t> __position;
00075 Content __value;
00076 public:
00077 const typename __Node::Type type() const
00078 {
00079 return __Node::leaf;
00080 }
00081
00082 void setValue(const Content& value)
00083 {
00084 __value = value;
00085 }
00086
00087 const TinyVector<Dimension, real_t>& position() const
00088 {
00089 return __position;
00090 }
00091
00092 Content& value()
00093 {
00094 return __value;
00095 }
00096
00097 const Content& value() const
00098 {
00099 return __value;
00100 }
00101
00102 __Leaf(const TinyVector<Dimension, real_t> position)
00103 :__position(position)
00104 {
00105 ;
00106 }
00107
00108 __Leaf(const __Leaf& l)
00109 : __Node(l),
00110 __position(l.__position),
00111 __value(l.__value)
00112 {
00113 ;
00114 }
00115
00116 ~__Leaf()
00117 {
00118 ;
00119 }
00120 };
00121
00122
00123 class __SubTree
00124 : public __Node
00125 {
00126 private:
00127 TinyVector<StaticPow<2,Dimension>::value,
00128 __Node*> __nodes;
00129
00130 public:
00131 __Node* node(const size_t i)
00132 {
00133 return __nodes[i];
00134 }
00135
00136 const typename __Node::Type type() const
00137 {
00138 return __Node::subtree;
00139 }
00140
00141 typename Octree<Content, Dimension>::iterator&
00142 fuzzySearch(const TinyVector<Dimension, real_t>& X,
00143 const TinyVector<Dimension, real_t>& center,
00144 const real_t size,
00145 typename Octree<Content, Dimension>::iterator& cell)
00146 {
00147 int num=0;
00148 TinyVector<Dimension,int> I;
00149
00150 for (size_t i=0; i<Dimension; ++i) {
00151 I[i] = (X[i]>center[i]);
00152 num += (I[i] << (Dimension-1-i));
00153 }
00154
00155 cell.addAddress(this);
00156 cell.localNumber() = num;
00157
00158 if (__nodes[num]==0) {
00166 cell.localNumber() = -1;
00167 cell++;
00168 } else {
00169 double newS = 0.5*size;
00170
00171 TinyVector<Dimension> newCenter = center;
00172 for (size_t i=0; i<Dimension; ++i) {
00173 newCenter[i] += (I[i]*2-1)*newS;
00174 }
00175
00176 if ((*__nodes[num]).type() == __Node::subtree) {
00177 (static_cast<__SubTree&>(*__nodes[num])).fuzzySearch(X,newCenter,newS,cell);
00178 } else {
00179 cell.__leaf = static_cast<__Leaf*>(__nodes[num]);
00180 }
00181 }
00182
00183 return cell;
00184 }
00185
00186 void addLeaf(const TinyVector<Dimension, real_t>& center,
00187 const real_t s,
00188 __Leaf* l)
00189 {
00190 int num=0;
00191 TinyVector<Dimension,int> I;
00192
00193 for (size_t i=0; i<Dimension; ++i) {
00194 I[i] = ((*l).position()[i]>center[i]);
00195
00196 num += (I[i] << (Dimension-1-i));
00197 }
00198
00199 if (__nodes[num]==0) {
00200 __nodes[num] = l;
00201 } else {
00202 double newS = 0.5*s;
00203
00204 TinyVector<Dimension> newCenter = center;
00205 for (size_t i=0; i<Dimension; ++i) {
00206 newCenter[i] += (I[i]*2-1)*newS;
00207 }
00208
00209 if ((*__nodes[num]).type() == __Node::subtree) {
00210 (static_cast<__SubTree&>(*__nodes[num])).addLeaf(newCenter,newS,l);
00211 } else {
00212 __Leaf* oldleaf=static_cast<__Leaf*>(__nodes[num]);
00213 __SubTree* s =new __SubTree();
00214 __nodes[num]=s;
00215 s->addLeaf(newCenter, newS, l);
00216 s->addLeaf(newCenter, newS, oldleaf);
00217 }
00218 }
00219 }
00220
00221 iterator begin()
00222 {
00223 iterator i;
00224 i.addAddress(this);
00225 i++;
00226 return i;
00227 }
00228
00229 __SubTree()
00230 : __nodes(0)
00231 {
00232 ;
00233 }
00234
00235 __SubTree(const __SubTree& s)
00236 : __Node(s),
00237 __nodes(s)
00238 {
00239 ;
00240 }
00241
00242 ~__SubTree()
00243 {
00244 ;
00245 }
00246 };
00247
00248 private:
00249 __Node* __node;
00251 TinyVector<Dimension> __center;
00252 real_t __size;
00254 public:
00255 class iterator
00256 {
00257 public:
00258 typedef std::pair <__SubTree*, int> LocalAddress;
00259
00260 friend class Octree<Content, Dimension>;
00261 friend class __SubTree;
00262
00263 private:
00264 __Leaf* __leaf;
00265
00266 std::stack<LocalAddress> __address;
00267
00268 public:
00269
00270 size_t depth()
00271 {
00272 return __address.size();
00273 }
00274
00275 __SubTree* currentFather()
00276 {
00277 if (__address.size() > 0) {
00278 return __address.top().first;
00279 } else {
00280 return 0;
00281 }
00282 }
00283
00284 iterator& operator++(int)
00285 {
00286 __SubTree* father = currentFather();
00287 __leaf = 0;
00288 if (father != 0) {
00289 __address.top().second++;
00290
00291 if (__address.top().second < 8) {
00292 __Node* n = father->node(__address.top().second);
00293 if (n != 0) {
00294 if(n->type() == __Node::leaf) {
00295 __leaf = static_cast<__Leaf*>(n);
00296 } else {
00297 __SubTree* t = static_cast<__SubTree*>(n);
00298 this->addAddress(t);
00299 (*this)++;
00300 }
00301 } else {
00302 (*this)++;
00303 }
00304 } else {
00305 __address.pop();
00306 (*this)++;
00307 }
00308 }
00309 return *this;
00310 }
00311
00312 const int& localNumber() const
00313 {
00314 return __address.top().second;
00315 }
00316
00317 int& localNumber()
00318 {
00319 return __address.top().second;
00320 }
00321
00322 void addAddress(__SubTree* a)
00323 {
00324 LocalAddress l;
00325 l.first = a;
00326 l.second = -1;
00327 __address.push(l);
00328 }
00329
00330 operator __Leaf*()
00331 {
00332 return __leaf;
00333 }
00334
00335 iterator()
00336 : __leaf(0)
00337 {
00338 ;
00339 }
00340
00341 iterator(const iterator& i)
00342 : __leaf(i.__leaf),
00343 __address(i.__address)
00344 {
00345 ;
00346 }
00347
00348 ~iterator()
00349 {
00350 ;
00351 }
00352 };
00353
00354 iterator begin() const
00355 {
00356 iterator i;
00357 if (__node != 0) {
00358 if ((*__node).type() == __Node::leaf) {
00359 } else {
00360 __SubTree& s = static_cast<__SubTree&>(*__node);
00361 i = s.begin();
00362 }
00363 }
00364 return i;
00365 }
00366
00367 iterator end() const
00368 {
00369 return iterator();
00370 }
00371
00372
00373 iterator search(const TinyVector<Dimension, real_t>& X)
00374 {
00375 throw ErrorHandler(__FILE__,__LINE__,
00376 "not implemented",
00377 ErrorHandler::unexpected);
00378 }
00379
00388 iterator fuzzySearch(const TinyVector<Dimension, real_t>& X) const
00389 {
00390 iterator i;
00391 if(__node == 0) {
00392 return this->end();
00393 } else if((*__node).type() != __Node::subtree) {
00394 i.__leaf = static_cast<__Leaf*>(__node);
00395 return i;
00396 } else {
00397 return static_cast<__SubTree&>(*__node).fuzzySearch(X, __center, __size, i);
00398 }
00399
00400 return i;
00401 }
00402
00403 void setSize(const TinyVector<Dimension>& a, const TinyVector<Dimension>& b)
00404 {
00405 __center = a+b;
00406 __center *= 0.5;
00407
00408 __size = std::abs(a[0]-__center[0]);
00409 for (size_t i=1; i<Dimension; ++i) {
00410 __size = std::max(__size,std::abs(a[i]-__center[i]));
00411 }
00412 }
00413
00414 void add(const Content& c, const TinyVector<Dimension, real_t>& position)
00415 {
00416 if (__node == 0) {
00417 __node = new __Leaf(position);
00418 dynamic_cast<__Leaf&>(*__node).setValue(c);
00419 } else {
00420 if ((*__node).type() == __Node::leaf) {
00421 __Leaf* l = dynamic_cast<__Leaf*>(__node);
00422 if(__size == 0) {
00423 setSize(l->position(), position);
00424 }
00425 __SubTree* s = new __SubTree();
00426 __node = s;
00427
00428 s->addLeaf(__center,__size,l);
00429 __Leaf* newLeaf = new __Leaf(position);
00430 newLeaf->setValue(c);
00431 s->addLeaf(__center,__size,newLeaf);
00432
00433 } else {
00434 __Leaf* newLeaf = new __Leaf(position);
00435 newLeaf->setValue(c);
00436 (dynamic_cast<__SubTree&>(*__node)).addLeaf(__center,__size,newLeaf);
00437 }
00438 }
00439 }
00440
00441 Octree()
00442 : __node(0),
00443 __center(0),
00444 __size(0)
00445 {
00446 ;
00447 }
00448
00449 Octree(const TinyVector<Dimension, real_t>& a, const TinyVector<Dimension, real_t>& b)
00450 : __node(0)
00451 {
00452 this->setSize(a,b);
00453 }
00454
00455 ~Octree()
00456 {
00457 ;
00458 }
00459
00460 };
00461
00462 #endif // OCTREE_HPP