core/vgl/algo/vgl_rtree.h
Go to the documentation of this file.
00001 // This is core/vgl/algo/vgl_rtree.h
00002 #ifndef vgl_rtree_h_
00003 #define vgl_rtree_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \author fsm
00010 // \brief Templated rtree class and associated classes and functions
00011 //--------------------------------------------------------------------------------
00012 
00013 #include <vcl_vector.h>
00014 // forward declare all classes.
00015 template <class V, class B, class C> class vgl_rtree_probe;
00016 template <class V, class B, class C> class vgl_rtree_node;
00017 template <class V, class B, class C> class vgl_rtree_iterator_base;
00018 template <class V, class B, class C> class vgl_rtree_iterator;
00019 template <class V, class B, class C> class vgl_rtree_const_iterator;
00020 template <class V, class B, class C> class vgl_rtree;
00021 
00022 //: Function predicate object for querying the tree.
00023 template <class V, class B, class C>
00024 class vgl_rtree_probe
00025 {
00026  public:
00027   virtual ~vgl_rtree_probe() { }
00028   //: return true if the probe "meets" the given object.
00029   virtual bool meets(V const &v) const { B b; C::init(b, v); return meets(b); }
00030   virtual bool meets(B const &b) const =0;
00031 };
00032 
00033 //: max. number of Vs stored in a node.
00034 // should be a template argument?
00035 #define vgl_rtree_MAX_VERTICES (8)
00036 
00037 //: max. number of children of a given node.
00038 // should be a template argument?
00039 #define vgl_rtree_MAX_CHILDREN (8)
00040 
00041 //: Represent a node in the rtree.
00042 template <class V, class B, class C>
00043 class vgl_rtree_node
00044 {
00045  public:
00046   typedef vgl_rtree_node<V, B, C> node;
00047 
00048   // contains bound on all Vs in this node and below.
00049   B bounds;
00050 
00051   // pointer to parent. 0 if none.
00052   node *parent;
00053 
00054 
00055   // number of vertex elements in this node and its children.
00056   unsigned total_vts;
00057 
00058   // number of vertex elements in this node.
00059   unsigned local_vts;
00060 
00061   // the elements are stored in this array.
00062   V vts[vgl_rtree_MAX_VERTICES];
00063 
00064 
00065   // 1 + number of nodes below this one.
00066   unsigned total_chs;
00067 
00068   // number of children of this node.
00069   unsigned local_chs;
00070 
00071   // pointers to children are stored in this array.
00072   node *chs[vgl_rtree_MAX_CHILDREN];
00073 
00074   // -------------------- methods
00075 
00076   vgl_rtree_node(node *parent, V const &v);
00077   ~vgl_rtree_node();
00078 
00079   // get all Vs which meet the given region.
00080   void get(B const &region, vcl_vector<V> &) const;
00081 
00082   // get all Vs whose bounds meet the given probe.
00083   void get(vgl_rtree_probe<V, B, C> const &region, vcl_vector<V> &) const;
00084 
00085   // get all Vs.
00086   void get_all(vcl_vector<V> &vs) const;
00087 
00088   // find node containing a V equal to the given one.
00089   bool find(V const &v, node **n, int *i) const;
00090   bool find(B const &b, V const &v, node **n, int *i) const;
00091 
00092   // add another V to the tree. return node it was added to.
00093   node *add(V const &v);
00094 
00095   // remove ith vertex from node.
00096   void erase(unsigned int i);
00097 
00098   void print() const;
00099 
00100  private:
00101   friend class vgl_rtree_iterator_base<V, B, C>;
00102 
00103   // the following methods are not used by the vgl_rtree.
00104   unsigned int find_index_in_parent() const;
00105   void compute_bounds();
00106   void update_total_vts(int diff);
00107   void update_total_chs(int diff);
00108   void update_vertex_count(int diff);
00109   void update_child_count (int diff);
00110 };
00111 
00112 //--------------------------------------------------------------------------------
00113 
00114 //: Base class for both rtree iterators.
00115 template <class V, class B, class C>
00116 class vgl_rtree_iterator_base
00117 {
00118  public:
00119   typedef vgl_rtree_node<V, B, C> node;
00120   node *current;
00121   unsigned int i;
00122 
00123   vgl_rtree_iterator_base(node *root) : current(root), i(0) { }
00124   vgl_rtree_iterator_base() : current(0), i(0) { }
00125 
00126   void operator_pp();
00127   void operator_mm();
00128 };
00129 
00130 template <class V, class B, class C>
00131 bool operator==(vgl_rtree_iterator_base<V, B, C> const &a,
00132                 vgl_rtree_iterator_base<V, B, C> const &b);
00133 
00134 template <class V, class B, class C>
00135 inline bool operator!=(vgl_rtree_iterator_base<V, B, C> const &a,
00136                        vgl_rtree_iterator_base<V, B, C> const &b)
00137 { return !( a == b ); }
00138 
00139 //: Iterator for rtree.
00140 template <class V, class B, class C>
00141 class vgl_rtree_iterator : public vgl_rtree_iterator_base<V, B, C>
00142 {
00143  public:
00144   typedef vgl_rtree_iterator_base<V, B, C> base;
00145   typedef vgl_rtree_iterator<V, B, C> self;
00146   typedef vgl_rtree_node<V, B, C> node;
00147 
00148   vgl_rtree_iterator(node *root) : base(root) { }
00149   vgl_rtree_iterator() { }
00150 
00151   V &operator*() const { return base::current->vts[base::i]; }
00152 
00153   self &operator++() { base::operator_pp(); return *this; }
00154   self &operator--() { base::operator_mm(); return *this; }
00155 
00156   self operator++(int) { self tmp = *this; base::operator_pp(); return tmp; }
00157   self operator--(int) { self tmp = *this; base::operator_mm(); return tmp; }
00158 };
00159 
00160 //: const_iterator for rtree.
00161 template <class V, class B, class C>
00162 class vgl_rtree_const_iterator : public vgl_rtree_iterator_base<V, B, C>
00163 {
00164  public:
00165   typedef vgl_rtree_iterator_base<V, B, C> base;
00166   typedef vgl_rtree_const_iterator<V, B, C> self;
00167   typedef vgl_rtree_node<V, B, C> node;
00168 
00169   vgl_rtree_const_iterator(node *root) : base(root) { }
00170   vgl_rtree_const_iterator(vgl_rtree_iterator<V, B, C> const &that) : base(that) { }
00171   vgl_rtree_const_iterator() { }
00172 
00173   V const &operator*() const { return base::current->vts[base::i]; }
00174 
00175   self &operator++() { base::operator_pp(); return *this; }
00176   self &operator--() { base::operator_mm(); return *this; }
00177 
00178   self operator++(int) { self tmp = *this; base::operator_pp(); return tmp; }
00179   self operator--(int) { self tmp = *this; base::operator_mm(); return tmp; }
00180 };
00181 
00182 //--------------------------------------------------------------------------------
00183 
00184 //: Templated rtree class.
00185 // The rtree is templated over the element
00186 // type V, the type B of the bounding region used (e.g.
00187 // axis-aligned bounding boxes are common but there are other
00188 // possibilities such as boxes which are axis-aligned ones or even
00189 // bounding ellipsoids) and a type C which is used as a namespace
00190 // for some functionality needed by the rtree.
00191 //
00192 // The rtree is a container of Vs which may contain multiple
00193 // copies of the same element. The container for client use is
00194 // called vgl_rtree<V, B, C> and is defined at the bottom of the
00195 // file.
00196 //
00197 // Note that the iterators are bidirectional but only forward
00198 // advancement has been implement so far (it's tedious work).
00199 // Moreover, beware that changing an element through an iterator
00200 // will not update the rtree, so may lead to the data structure
00201 // being corrupted.
00202 //
00203 // -  V : element type
00204 // -  B : bounds type
00205 // -  C : mystery type
00206 //
00207 // The C-device makes it possible to have an rtree of Vs using Bs
00208 // without having to modify the class definitions of V or B. It
00209 // may be better to have C's signatures non-static and store a C
00210 // on every tree node, but I don't know about this.
00211 //
00212 // It is assumed that the cost of copying (e.g. by assignment) Vs
00213 // and Bs is not too high. In any case, I suggest you inline and
00214 // optimize heavily when compiling this source file.
00215 //
00216 // V must have the following signatures:
00217 // \code
00218 //   V::V();
00219 //   V::V(V const &);
00220 //   V::operator==(V const &) or operator==(V const &, V const &);
00221 // \endcode
00222 //
00223 // B must have the following signatures :
00224 // \code
00225 //   B::B();
00226 //   B::B(const &);
00227 //   B::operator==(V const &) or operator==(B const &, B const &);
00228 // \endcode
00229 //
00230 // C must have the following (static method) signatures :
00231 // \code
00232 //   void  C::init  (B &, V const &);
00233 //   void  C::update(B &, V const &);
00234 //   void  C::update(B &, B const &);
00235 //   bool  C::meet  (B const &, V const &);
00236 //   bool  C::meet  (B const &, B const &);
00237 //   float C::volume(B const &);
00238 // \endcode
00239 //
00240 // The volume() method is used by the rtree to make decisions
00241 // about where to put new elements.
00242 template <class V, class B, class C>
00243 class vgl_rtree
00244 {
00245  public:
00246   vgl_rtree() : root(0) { }
00247   ~vgl_rtree() {
00248     if (root)
00249       delete root;
00250     root = 0;
00251   }
00252 
00253   //
00254   typedef vgl_rtree_probe<V, B, C> probe;
00255 
00256   //: iterators
00257   typedef vgl_rtree_iterator      <V, B, C> iterator;
00258   typedef vgl_rtree_const_iterator<V, B, C> const_iterator;
00259 
00260   iterator       begin() { return root ? iterator(root) : iterator(); }
00261   const_iterator begin() const { return root ? const_iterator(root) : const_iterator(); }
00262 
00263   iterator       end() { return iterator(); }
00264   const_iterator end() const { return const_iterator(); }
00265 
00266   //: add an element to the rtree.
00267   void add(V const &v) {
00268     if (root)
00269       root->add(v);
00270     else
00271       root = new node(0/*parent*/, v);
00272   }
00273 
00274   //: remove one element from the rtree.
00275   void remove(V const &v) {
00276     if (root) {
00277       B tmp;
00278       C::init(tmp, v);
00279       node *n;
00280       int i;
00281       if (root->find(tmp, v, &n, &i))
00282         n->erase(i);
00283 
00284       if (root->total_vts == 0) {
00285         delete root;
00286         root = 0;
00287       }
00288     }
00289   }
00290 
00291   //: return true iff the rtree contains an element equal to v.
00292   bool contains(V const &v) const {
00293     node *n;
00294     int i;
00295     return root ? root->find(v, &n, &i) : false;
00296   }
00297 #if 0
00298   iterator       find(V const &v);
00299   const_iterator find(V const &v) const;
00300 #endif
00301 
00302   //: erase the element pointed to by the iterator.
00303   // may invalidate \e all iterators into the rtree.
00304   void erase(iterator i) {
00305     i.current->erase(i.i);
00306     if (root->total_vts == 0) {
00307       delete root;
00308       root = 0;
00309     }
00310   }
00311 
00312   //: get elements in the given region.
00313   void get(B const &region, vcl_vector<V> &vs) const {
00314     if (root)
00315       root->get(region, vs);
00316   }
00317 
00318   //: get elements which meet the given probe.
00319   void get(vgl_rtree_probe<V, B, C> const &region, vcl_vector<V> &vs) const {
00320     if (root)
00321       root->get(region, vs);
00322   }
00323 
00324   //: get all elements in the tree.
00325   void get_all(vcl_vector<V> &vs) const {
00326     if (root)
00327       root->get_all(vs);
00328   }
00329 
00330   //: return true iff the tree has no elements.
00331   bool empty() const {
00332     return root ? root->total_vts==0 : true;
00333   }
00334 
00335   //: return number of elements stored in the tree.
00336   unsigned size() const {
00337     return root ? root->total_vts : 0;
00338   }
00339 
00340   //: return number of nodes used by the tree.
00341   unsigned nodes() const {
00342     return root ? root->total_chs : 0;
00343   }
00344 
00345   // for internal use only.
00346   typedef vgl_rtree_node<V, B, C> node;
00347   node *secret_get_root() const { return root; } // for debugging purposes.
00348 
00349   void print() const {
00350     root->print();
00351   }
00352 
00353  private:
00354   node *root;
00355   // disallow assignment
00356   vgl_rtree<V, B, C>& operator=(vgl_rtree<V, B, C> const &) { return *this; }
00357   vgl_rtree(vgl_rtree<V, B, C> const &) { }
00358 };
00359 
00360 #define VGL_RTREE_INSTANTIATE(V, B, C) extern "you must include vgl_rtree.txx first"
00361 
00362 #endif // vgl_rtree_h_