00001 #ifndef rsdl_kd_tree_h_
00002 #define rsdl_kd_tree_h_
00003
00004
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
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
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
00030 rsdl_bounding_box outer_box_;
00031
00032 rsdl_bounding_box inner_box_;
00033
00034 unsigned int depth_;
00035
00036 vcl_vector< int > point_indices_;
00037
00038 rsdl_kd_node* left_;
00039
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_; }
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
00062 rsdl_kd_tree( const rsdl_kd_tree& ): vbl_ref_count() {}
00063
00064
00065 rsdl_kd_tree& operator=( const rsdl_kd_tree& ) { return *this; }
00066
00067 public:
00068
00069 rsdl_kd_tree( const vcl_vector< rsdl_point >& points,
00070 double min_angle = 0,
00071 int points_per_leaf=4 );
00072
00073
00074 ~rsdl_kd_tree();
00075
00076
00077
00078
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
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
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_;
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_