00001 #ifndef rsdl_bins_h_ 00002 #define rsdl_bins_h_ 00003 //: 00004 // \file 00005 // \author Amitha Perera 00006 // \date Feb 2003 00007 // 00008 // Provide an n-dimensional bin structure for fast point retrieval. 00009 00010 #include <vcl_vector.h> 00011 #include <vnl/vnl_vector_fixed.h> 00012 #include <vcl_cstddef.h> // for std::size_t 00013 00014 // these two classes are helper classes for rsdl_bins, and should ideally 00015 // be declared in rsdl_bins and defined only in the .txx, but MSVC6 and 7 00016 // don't handle nested templated classes well. So, they become external 00017 // classes. 00018 // 00019 template<unsigned N, typename C, typename V> 00020 struct rsdl_bins_point_dist_entry; 00021 template<unsigned N, typename C, typename V> 00022 struct rsdl_bins_bin_entry_type; 00023 00024 00025 //: N-dimensional bin structure for fast point retrieval. 00026 // 00027 // This data structure stores point locations in bins so that 00028 // neighbourhood queries can be performed efficiently by not having to 00029 // consider the whole data set. 00030 // 00031 // The points are of type vnl_vector_fixed<\a CoordType, \a N>. With 00032 // every point is associated a value, of type \a ValueType. 00033 // 00034 // The structure will store any point location, including those 00035 // outside the range of the underlying bin storage. Such points are 00036 // stored in the nearest available bin. 00037 // 00038 // Location equality is performed to within a tolerance (see 00039 // set_distance_tolerance). This affects get_value, for 00040 // example. 00041 // 00042 template<unsigned N, typename CoordType, typename ValueType> 00043 class rsdl_bins 00044 { 00045 public: 00046 //: The type of each element of a (vector) point 00047 typedef CoordType coord_type; 00048 00049 //: The type of data object associated with each location. 00050 typedef ValueType value_type; 00051 00052 //: The location object type. 00053 typedef vnl_vector_fixed<CoordType,N> point_type; 00054 00055 public: 00056 //: 00057 // Construct bins of size \a bin_sizes with enough bins to span \a 00058 // min_coord to \a max_coord. 00059 // 00060 // The equality comparison tolerance is set to 0. 00061 // 00062 rsdl_bins( point_type const& min_coord, 00063 point_type const& max_coord, 00064 point_type const& bin_sizes ); 00065 00066 //: Remove all points from the bins. 00067 void clear(); 00068 00069 //: Update the tolerance used in equality checking. 00070 // 00071 // Two points with Euclidean distance <= \a tol will compare equal. 00072 // 00073 void set_distance_tolerance( coord_type const& tol ); 00074 00075 //: Adds the point \a pt with value \a val. 00076 void add_point( point_type const& pt, value_type const& val ); 00077 00078 //: Retrieves the value at \a pt, if possible. 00079 // 00080 // If a point equal to \a pt, to within the current tolerance, 00081 // is found, \a val will be set to the associated value, and the 00082 // function will return true. Otherwise, the function will return 00083 // false. 00084 // 00085 // If multiple points compare equal, one will be arbitrarily 00086 // selected. 00087 // 00088 bool get_value( point_type const& pt, value_type& val ) const; 00089 00090 //: Return the values of the \a n nearest neighbours. 00091 // 00092 // If the structure has fewer than \a n points, it will return all 00093 // the values stored. 00094 // 00095 void n_nearest( point_type const& pt, 00096 unsigned n, 00097 vcl_vector< value_type >& values ) const; 00098 00099 //: Return the values and locations of the \a n nearest neighbours. 00100 // 00101 // If the structure has fewer than \a n points, it will return all 00102 // the points stored. 00103 // 00104 void n_nearest( point_type const& pt, 00105 unsigned n, 00106 vcl_vector< point_type >& points, 00107 vcl_vector< value_type >& values ) const; 00108 00109 //: Return the values of the \a n nearest neighbours. 00110 // 00111 // A slow exhaustive search version of n_nearest, used for testing 00112 // and validation. 00113 // 00114 void n_nearest_exhaustive( point_type const& pt, 00115 unsigned n, 00116 vcl_vector< value_type >& values ) const; 00117 00118 //: Return the values and locations of the \a n nearest neighbours. 00119 // 00120 // A slow exhaustive search version of n_nearest, used for testing 00121 // and validation. 00122 // 00123 void n_nearest_exhaustive( point_type const& pt, 00124 unsigned n, 00125 vcl_vector< point_type >& points, 00126 vcl_vector< value_type >& values ) const; 00127 00128 //: Check if there is at least one point within \a radius of \a pt. 00129 // 00130 bool is_any_point_within_radius( point_type const& pt, 00131 coord_type const& radius ) const; 00132 00133 //: Return values of all the points within \a radius of \a pt. 00134 // 00135 void points_within_radius( point_type const& pt, 00136 coord_type const& radius, 00137 vcl_vector< value_type >& values ) const; 00138 00139 //: Return values and locations of all the points within \a radius of \a pt. 00140 // 00141 void points_within_radius( point_type const& pt, 00142 coord_type const& radius, 00143 vcl_vector< point_type >& points, 00144 vcl_vector< value_type >& values ) const; 00145 00146 //: Return values of all the points within the bounding box. 00147 // 00148 // The boundaries of the bounding box are included in the region 00149 // searched. 00150 // 00151 void points_in_bounding_box( point_type const& min_pt, 00152 point_type const& max_pt, 00153 vcl_vector< value_type >& values ) const; 00154 00155 //: Return values and locations of all the points within the bounding box. 00156 // 00157 // The boundaries of the bounding box are included in the region 00158 // searched. 00159 // 00160 void points_in_bounding_box( point_type const& min_pt, 00161 point_type const& max_pt, 00162 vcl_vector< point_type >& points, 00163 vcl_vector< value_type >& values ) const; 00164 // INTERNALS 00165 public: 00166 typedef rsdl_bins_bin_entry_type<N,CoordType,ValueType> bin_entry_type; 00167 00168 // See comment in .txx 00169 typedef rsdl_bins_point_dist_entry<N,CoordType,ValueType> point_dist_entry; 00170 00171 //: 00172 // Data stored at each bin 00173 // 00174 typedef vcl_vector< bin_entry_type > bin_type; 00175 00176 //: 00177 // The type of an index into the bins_ storage structure. 00178 // 00179 typedef typename bin_type::size_type bin_index_type; 00180 00181 //: 00182 // A vector of indices into the bins_ storage structure. 00183 // 00184 typedef vcl_vector< bin_index_type > bin_index_vector; 00185 00186 //: 00187 // Converts the coordinate \a x to a bin coordinate for dimension \a 00188 // d. Requires that min_pt_[d] and bin_size_[d] are initialized. The 00189 // resulting coordinate is not necessarily within the allocated 00190 // range. 00191 // 00192 int coord_to_bin( coord_type x, unsigned d ) const; 00193 00194 //: 00195 // Converts the point to a set of bin indices. 00196 // 00197 void point_to_bin( point_type const& pt, int ind[N] ) const; 00198 00199 //: 00200 // Convert the point into an index into the bin data structure bins_. 00201 // 00202 bin_index_type bin_index( point_type const& pt ) const; 00203 00204 //: 00205 // Convert the bin coordinates into an index into the bin data 00206 // structure bins_. 00207 // 00208 bin_index_type bin_index( int bin[N] ) const; 00209 00210 //: 00211 // The list of possible bin indices that could hold pt given the 00212 // current distance tolerance. 00213 bin_index_vector bin_indices( point_type const& pt ) const; 00214 00215 //: 00216 // For a rectangular subset of bins bounded by \a bin_lo and \a 00217 // bin_hi, find the face that is closest to point \pt. Faces that 00218 // are at the edge of the whole set of bins are treated as faces at 00219 // infinity, since the bins at these faces hold points out to 00220 // infinity. The closest face is returned as dimension \a face_dim 00221 // and direction \a face_dir if those pointers are not NULL. The 00222 // distance to the closest face is returned via \a face_dist if that 00223 // pointer is not NULL. If the subset of bins is the full set of 00224 // bins, then \a face_inf_dist will be true, indicating infinite 00225 // distance to the nearest face. Return values \a face_dim, \a 00226 // face_dir, and \a face_dist will only be valid if \a face_inf_dist 00227 // is false. 00228 // 00229 // This function is a helper to \a n_nearest_impl. 00230 // 00231 void closest_face ( point_type const& pt, 00232 int bin_lo[N], 00233 int bin_hi[N], 00234 unsigned * face_dim, 00235 unsigned * face_dir, 00236 coord_type * face_dist, 00237 bool & face_inf_dist) const; 00238 00239 //: 00240 // Implementation of n_nearest. See the documentation for that. 00241 // 00242 // This version will add the results to values, and, if points is 00243 // not null, to points. 00244 // 00245 void n_nearest_impl( point_type const& pt, 00246 unsigned n, 00247 vcl_vector< value_type >& values, 00248 vcl_vector< point_type >* points ) const; 00249 00250 //: 00251 // Implementation of n_nearest_exhaustive. See the documentation for that. 00252 // 00253 // This version will add the results to values, and, if points is 00254 // not null, to points. 00255 // 00256 void n_nearest_exhaustive_impl( point_type const& pt, 00257 unsigned n, 00258 vcl_vector< value_type >& values, 00259 vcl_vector< point_type >* points ) const; 00260 00261 //: 00262 // Implementation of points_within_radius. See the documentation for 00263 // that. 00264 // 00265 // This version will add the results to values, and, if points is 00266 // not null, to points. 00267 // 00268 void points_within_radius_impl( point_type const& pt, 00269 coord_type const& radius, 00270 vcl_vector< value_type >& values, 00271 vcl_vector< point_type >* points ) const; 00272 00273 //: 00274 // Implementation of points_in_bounding_box. See the documentation 00275 // for that. 00276 // 00277 // This version will add the results to values, and, if points is 00278 // not null, to points. 00279 // 00280 void points_in_bounding_box_impl( point_type const& min_pt, 00281 point_type const& max_pt, 00282 vcl_vector< value_type >& values, 00283 vcl_vector< point_type >* points ) const; 00284 00285 // documentation in .txx 00286 vcl_size_t scan_region( int lo[N], int hi[N], int cur[N], unsigned dim, 00287 bin_index_vector& indices ) const; 00288 00289 #if 0 00290 // documentation in .txx 00291 unsigned scan_bdy( int lo[N], int hi[N], int cur[N], unsigned dim, 00292 bin_index_vector& indices ) const; 00293 #endif 00294 00295 private: 00296 //: 00297 // The number of bins along each dimension. The numbers are ints and 00298 // not unsigned ints because the logic for off-the-bottom is easier 00299 // if we allow -ve indices. 00300 // 00301 int size_[N]; 00302 00303 //: 00304 // The size of the bins along each dimension. 00305 // 00306 coord_type bin_size_[N]; 00307 00308 //: 00309 // The offsets for bin(0,0,0) 00310 coord_type min_pt_[N]; 00311 00312 //: 00313 // Distance tolerance used to compare if two points are the same. 00314 // 00315 coord_type dist_tol_; 00316 00317 //: 00318 // Storage for all the bins. 00319 vcl_vector< bin_type > bins_; 00320 }; 00321 00322 00323 //: 00324 // This is just a (location,value) pair that has a 00325 // equal-within-threshold function. Used in rsdl_bins to store the 00326 // points in the bins. 00327 // 00328 template<unsigned N, typename CoordType, typename ValueType> 00329 struct rsdl_bins_bin_entry_type 00330 { 00331 // For some reason, MSVC7 doesn't like rsdl_bins<N,CoordType,ValueType>::coord_type. 00332 // It complains that rsdl_bins is undefined, but doesn't complain about the same 00333 // declaration in rsdl_bins_point_dist_entry (in the .txx). Go figure. 00334 00335 typedef CoordType coord_type; 00336 typedef ValueType value_type; 00337 typedef vnl_vector_fixed<CoordType,N> point_type; 00338 00339 rsdl_bins_bin_entry_type( point_type const& pt, const value_type val ); 00340 00341 inline bool equal( point_type const& pt, double tol_sqr ) const; 00342 00343 point_type point_; 00344 value_type value_; 00345 }; 00346 00347 00348 #endif // rsdl_bins_h_
1.5.1