contrib/rpl/rsdl/rsdl_bins.h

Go to the documentation of this file.
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_

Generated on Mon Mar 8 05:26:57 2010 for contrib/rpl/rsdl by  doxygen 1.5.1