Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

rsdl_kd_tree.h

Go to the documentation of this file.
00001 #ifndef rsdl_kd_tree_h_
00002 #define rsdl_kd_tree_h_
00003 //:
00004 // \file
00005 
00006 #include <vcl_vector.h>
00007 #include <rsdl/rsdl_point.h>
00008 #include <rsdl/rsdl_bounding_box.h>
00009 #include <vbl/vbl_ref_count.h>
00010 
00011 class rsdl_kd_node
00012 {
00013  public:
00014   //: ctor for internal node
00015   rsdl_kd_node( const rsdl_bounding_box& outer_box,
00016                 const rsdl_bounding_box& inner_box,
00017                 unsigned int depth )
00018     : outer_box_(outer_box), inner_box_(inner_box), depth_(depth),
00019       point_indices_(0), left_(0), right_(0) {}
00020 
00021   //: ctor for leaf node
00022   rsdl_kd_node( const rsdl_bounding_box& outer_box,
00023                 const rsdl_bounding_box& inner_box,
00024                 unsigned int depth,
00025                 const vcl_vector<int>& indices )
00026     : outer_box_(outer_box), inner_box_(inner_box), depth_(depth),
00027       point_indices_(indices), left_(0), right_(0) {}
00028 
00029   //: outer bounding box in both cartesian and angular dimensions
00030   rsdl_bounding_box outer_box_;
00031   //: inner bounding box in both cartesian and angular dimensions
00032   rsdl_bounding_box inner_box_;
00033   //: depth of node in the tree
00034   unsigned int depth_;
00035   //: indices of the points stored at this leaf
00036   vcl_vector< int > point_indices_;
00037   //: left child
00038   rsdl_kd_node* left_;
00039   //: right child
00040   rsdl_kd_node* right_;
00041 };
00042 
00043 
00044 class rsdl_kd_heap_entry
00045 {
00046  public:
00047   rsdl_kd_heap_entry() {}
00048   rsdl_kd_heap_entry( double dist, rsdl_kd_node* p )
00049     : dist_(dist), p_(p) {}
00050   bool operator< ( const rsdl_kd_heap_entry& right ) const
00051   { return right.dist_ < this->dist_; }  // kludge because max heap
00052 
00053   double dist_;
00054   rsdl_kd_node* p_;
00055 };
00056 
00057 
00058 class rsdl_kd_tree : public vbl_ref_count
00059 {
00060  private:
00061   //: copy ctor is private, for now, to prevent its use
00062   rsdl_kd_tree( const rsdl_kd_tree& /*old*/ ): vbl_ref_count() {}
00063 
00064   //: operator= is private, for now, to prevent its use
00065   rsdl_kd_tree& operator=( const rsdl_kd_tree& /*old*/ ) { return *this; }
00066 
00067  public:
00068   //: ctor requires the points and values associated with the tree;
00069   rsdl_kd_tree( const vcl_vector< rsdl_point >& points,
00070                 double min_angle = 0,
00071                 int points_per_leaf=4 );
00072 
00073   //: dtor deletes the nodes in tree
00074   ~rsdl_kd_tree();
00075 
00076   //: find the n points nearest to the query point (and their associate indices).
00077   // max_leaves = -1 to not use approximate nearest neighbor queries;
00078   // if max_leaves is not -1 then use_heap must be true
00079   void n_nearest( const rsdl_point& query_point,
00080                   int n,
00081                   vcl_vector< rsdl_point >& closest_points,
00082                   vcl_vector< int >& indices,
00083                   bool use_heap = false,
00084                   int max_leaves = -1 );
00085 
00086   //: find all points within a query's bounding box
00087   void points_in_bounding_box( const rsdl_bounding_box& box,
00088                                vcl_vector< rsdl_point >& closest_points,
00089                                vcl_vector< int >& indices );
00090 
00091   //: find all points within a given distance of the query_point.
00092   void points_in_radius( const rsdl_point& query_point,
00093                          double radius,
00094                          vcl_vector< rsdl_point >& points,
00095                          vcl_vector< int >& indices );
00096 
00097  private:
00098   rsdl_kd_node* root_;
00099 
00100   vcl_vector< rsdl_point > points_;
00101 
00102   unsigned int Nc_, Na_; // number of cartesian and angular dimensions
00103   double min_angle_;
00104 
00105   int leaf_count_;
00106   int leaves_examined_;
00107   int internal_count_;
00108   int internal_examined_;
00109 
00110  private:
00111   void destroy_tree( rsdl_kd_node*& p );
00112 
00113   rsdl_kd_node* build_kd_tree( int points_per_leaf,
00114                                const rsdl_bounding_box& outer_box,
00115                                int depth,
00116                                vcl_vector< int >& indices );
00117 
00118   rsdl_bounding_box build_inner_box( const vcl_vector< int >& indices );
00119 
00120   void greatest_variation( const vcl_vector<int>& indices,
00121                            bool& use_cartesian, int& dim );
00122 
00123   void n_nearest_with_stack( const rsdl_point& query_point,
00124                              int n,
00125                              rsdl_kd_node* root,
00126                              vcl_vector< int >& closest_indices,
00127                              vcl_vector< double >& sq_distances,
00128                              int & num_found );
00129 
00130   void n_nearest_with_heap( const rsdl_point& query_point,
00131                             int n,
00132                             rsdl_kd_node* root,
00133                             vcl_vector< int >& closest_indices,
00134                             vcl_vector< double >& sq_distances,
00135                             int & num_found,
00136                             int max_leaves);
00137 
00138   void update_closest( const rsdl_point& query_point,
00139                        int n,
00140                        rsdl_kd_node* p,
00141                        vcl_vector< int >& closest_indices,
00142                        vcl_vector< double >& sq_distances,
00143                        int & num_found );
00144 
00145   bool bounded_at_leaf ( const rsdl_point& query_point,
00146                          int n,
00147                          rsdl_kd_node* current,
00148                          const vcl_vector< double >& sq_distances,
00149                          int & num_found );
00150 
00151   void points_in_bounding_box( rsdl_kd_node* current,
00152                                const rsdl_bounding_box& box,
00153                                vcl_vector< int >& indices );
00154 
00155   void report_all_in_subtree( rsdl_kd_node* current,
00156                               vcl_vector< int >& indices );
00157 };
00158 
00159 #endif // rsdl_kd_tree_h_

Generated on Thu Jan 10 14:49:34 2008 for contrib/rpl/rsdl by  doxygen 1.4.4