00001
00002 #ifndef rsdl_bins_2d__txx_
00003 #define rsdl_bins_2d__txx_
00004
00005 #include "rsdl_bins_2d.h"
00006
00007 #include <vcl_cassert.h>
00008 #include <vcl_iostream.h>
00009 #include <vcl_vector.h>
00010
00011 #include <vnl/vnl_math.h>
00012 #include <vnl/vnl_vector_fixed.h>
00013
00014
00015 template < class COORD_T, class VALUE_T >
00016 rsdl_bins_2d< COORD_T, VALUE_T > ::
00017 rsdl_bins_2d()
00018 : bins_(1,1), min_pt_(0,0), max_pt_(1,1), bin_sizes_(1,1), num_bins_x_(1), num_bins_y_(1),
00019 dist_tolerance_sqr_( 0 )
00020 {
00021 }
00022
00023
00024 template < class COORD_T, class VALUE_T >
00025 rsdl_bins_2d< COORD_T, VALUE_T > ::
00026 rsdl_bins_2d( const vnl_vector_fixed< COORD_T, 2 > & min_pt,
00027 const vnl_vector_fixed< COORD_T, 2 > & max_pt,
00028 const vnl_vector_fixed< COORD_T, 2 > & bin_sizes )
00029 : min_pt_( min_pt ), max_pt_( max_pt ), bin_sizes_( bin_sizes ), dist_tolerance_sqr_( 0 )
00030 {
00031 assert( min_pt_[0] <= max_pt_[0] );
00032 assert( min_pt_[1] <= max_pt_[1] );
00033
00034 num_bins_x_ = int( vcl_ceil( double( max_pt_[0] - min_pt_[0] ) / bin_sizes_[0] ) );
00035 num_bins_y_ = int( vcl_ceil( double( max_pt_[1] - min_pt_[1] ) / bin_sizes_[1] ) );
00036
00037
00038 if( num_bins_x_ <=0 ) num_bins_x_ = 1;
00039 if( num_bins_y_ <=0 ) num_bins_y_ = 1;
00040
00041 bins_.resize( num_bins_x_, num_bins_y_ );
00042 }
00043
00044
00045 template < class COORD_T, class VALUE_T >
00046 rsdl_bins_2d< COORD_T, VALUE_T > ::
00047 ~rsdl_bins_2d()
00048 {
00049 }
00050
00051 template < class COORD_T, class VALUE_T >
00052 void
00053 rsdl_bins_2d< COORD_T, VALUE_T > ::
00054 reset( const vnl_vector_fixed< COORD_T, 2 > & min_pt,
00055 const vnl_vector_fixed< COORD_T, 2 > & max_pt,
00056 const vnl_vector_fixed< COORD_T, 2 > & bin_sizes )
00057 {
00058 min_pt_ = min_pt;
00059 max_pt_ = max_pt;
00060 bin_sizes_ = bin_sizes;
00061
00062 assert( min_pt_[0] <= max_pt_[0] );
00063 assert( min_pt_[1] <= max_pt_[1] );
00064
00065 num_bins_x_ = int( vcl_ceil( double( max_pt_[0] - min_pt_[0] ) / bin_sizes_[0] ) );
00066 num_bins_y_ = int( vcl_ceil( double( max_pt_[1] - min_pt_[1] ) / bin_sizes_[1] ) );
00067
00068 bins_.resize( 2, 2);
00069
00070 bins_.resize( num_bins_x_, num_bins_y_ );
00071 }
00072
00073 template < class COORD_T, class VALUE_T >
00074 void
00075 rsdl_bins_2d< COORD_T, VALUE_T > ::
00076 remove_all_points( )
00077 {
00078 for ( int bin_x = 0; bin_x < num_bins_x_; ++ bin_x ) {
00079 for ( int bin_y = 0; bin_y < num_bins_y_; ++ bin_y ) {
00080 bins_ (bin_x, bin_y).clear ();
00081 }
00082 }
00083 }
00084
00085
00086 template < class COORD_T, class VALUE_T >
00087 void
00088 rsdl_bins_2d< COORD_T, VALUE_T > ::
00089 add_point( const vnl_vector_fixed< COORD_T, 2 > & pt,
00090 const VALUE_T & value )
00091 {
00092 int bin_x, bin_y;
00093 this->point_to_bin( pt[0], pt[1], bin_x, bin_y );
00094 bins_( bin_x, bin_y ).push_back( bin_entry_type_ ( pt, value ) );
00095 }
00096
00097
00098 template < class COORD_T, class VALUE_T >
00099 bool
00100 rsdl_bins_2d< COORD_T, VALUE_T > ::
00101 get_value( const vnl_vector_fixed< COORD_T, 2 > & pt, VALUE_T& value )
00102 {
00103 int bin_x, bin_y;
00104 this->point_to_bin( pt[0], pt[1], bin_x, bin_y );
00105
00106 COORD_T distance = vcl_sqrt(dist_tolerance_sqr_);
00107 int min_bin_x, min_bin_y;
00108 this->point_to_bin( pt[0]-distance, pt[1]-distance, min_bin_x, min_bin_y );
00109
00110 int max_bin_x, max_bin_y;
00111 this->point_to_bin( pt[0]+distance, pt[1]+distance, max_bin_x, max_bin_y );
00112
00113 for ( int bin_x = min_bin_x; bin_x <= max_bin_x; ++ bin_x )
00114 for ( int bin_y = min_bin_y; bin_y <= max_bin_y; ++ bin_y )
00115 for (typename bin_vector_type_::iterator p = bins_(bin_x,bin_y).begin();
00116 p != bins_( bin_x, bin_y ).end(); ++p )
00117 if ( vnl_vector_ssd( pt, p->point_ ) <= dist_tolerance_sqr_ ) {
00118 value = p->value_;
00119 return true;
00120 }
00121
00122 return false;
00123 }
00124
00125
00126 template < class COORD_T, class VALUE_T >
00127 bool
00128 rsdl_bins_2d< COORD_T, VALUE_T > ::
00129 change_point( const vnl_vector_fixed< COORD_T, 2 > & pt,
00130 const VALUE_T & value )
00131 {
00132 int bin_x, bin_y;
00133 this->point_to_bin( pt[0], pt[1], bin_x, bin_y );
00134
00135 COORD_T distance = vcl_sqrt(dist_tolerance_sqr_);
00136 int min_bin_x, min_bin_y;
00137 this->point_to_bin( pt[0]-distance, pt[1]-distance, min_bin_x, min_bin_y );
00138
00139 int max_bin_x, max_bin_y;
00140 this->point_to_bin( pt[0]+distance, pt[1]+distance, max_bin_x, max_bin_y );
00141
00142 for ( int bin_x = min_bin_x; bin_x <= max_bin_x; ++ bin_x )
00143 for ( int bin_y = min_bin_y; bin_y <= max_bin_y; ++ bin_y )
00144 for (typename bin_vector_type_::iterator p = bins_(bin_x,bin_y).begin();
00145 p != bins_( bin_x, bin_y ).end(); ++p )
00146 if ( vnl_vector_ssd( pt, p->point_ ) <= dist_tolerance_sqr_ ) {
00147 p->value_ = value;
00148 return true;
00149 }
00150
00151 return false;
00152 }
00153
00154
00155 template < class COORD_T, class VALUE_T >
00156 bool
00157 rsdl_bins_2d< COORD_T, VALUE_T > ::
00158 change_point( const vnl_vector_fixed< COORD_T, 2 > & pt,
00159 const VALUE_T& old_val,
00160 const VALUE_T& new_val )
00161 {
00162 int bin_x, bin_y;
00163 this->point_to_bin( pt[0], pt[1], bin_x, bin_y );
00164
00165 COORD_T distance = vcl_sqrt(dist_tolerance_sqr_);
00166 int min_bin_x, min_bin_y;
00167 this->point_to_bin( pt[0]-distance, pt[1]-distance, min_bin_x, min_bin_y );
00168
00169 int max_bin_x, max_bin_y;
00170 this->point_to_bin( pt[0]+distance, pt[1]+distance, max_bin_x, max_bin_y );
00171
00172 for ( int bin_x = min_bin_x; bin_x <= max_bin_x; ++ bin_x )
00173 for ( int bin_y = min_bin_y; bin_y <= max_bin_y; ++ bin_y )
00174 for (typename bin_vector_type_::iterator p = bins_(bin_x,bin_y).begin();
00175 p != bins_( bin_x, bin_y ).end(); ++p )
00176 if ( vnl_vector_ssd( pt, p->point_ ) <= dist_tolerance_sqr_ &&
00177 p->value_ == old_val) {
00178 p->value_ = new_val;
00179 return true;
00180 }
00181
00182 return false;
00183 }
00184
00185
00186 template < class COORD_T, class VALUE_T >
00187 bool
00188 rsdl_bins_2d< COORD_T, VALUE_T > ::
00189 remove_point( const vnl_vector_fixed< COORD_T, 2 > & pt )
00190 {
00191 int bin_x, bin_y;
00192 this->point_to_bin( pt[0], pt[1], bin_x, bin_y );
00193
00194 COORD_T distance = vcl_sqrt(dist_tolerance_sqr_);
00195 int min_bin_x, min_bin_y;
00196 this->point_to_bin( pt[0]-distance, pt[1]-distance, min_bin_x, min_bin_y );
00197
00198 int max_bin_x, max_bin_y;
00199 this->point_to_bin( pt[0]+distance, pt[1]+distance, max_bin_x, max_bin_y );
00200
00201 for ( int bin_x = min_bin_x; bin_x <= max_bin_x; ++ bin_x )
00202 for ( int bin_y = min_bin_y; bin_y <= max_bin_y; ++ bin_y )
00203 for (typename bin_vector_type_::iterator p = bins_(bin_x,bin_y).begin();
00204 p != bins_( bin_x, bin_y ).end(); ++p )
00205 if ( vnl_vector_ssd( pt, p->point_ ) <= dist_tolerance_sqr_ ) {
00206 bins_( bin_x, bin_y ).erase( p );
00207 return true;
00208 }
00209
00210 return false;
00211 }
00212
00213
00214 template < class COORD_T, class VALUE_T >
00215 bool
00216 rsdl_bins_2d< COORD_T, VALUE_T > ::
00217 remove_point( const vnl_vector_fixed< COORD_T, 2 > & pt,
00218 const VALUE_T & value )
00219 {
00220 int bin_x, bin_y;
00221 this->point_to_bin( pt[0], pt[1], bin_x, bin_y );
00222
00223 COORD_T distance = vcl_sqrt(dist_tolerance_sqr_);
00224 int min_bin_x, min_bin_y;
00225 this->point_to_bin( pt[0]-distance, pt[1]-distance, min_bin_x, min_bin_y );
00226
00227 int max_bin_x, max_bin_y;
00228 this->point_to_bin( pt[0]+distance, pt[1]+distance, max_bin_x, max_bin_y );
00229
00230 for ( int bin_x = min_bin_x; bin_x <= max_bin_x; ++ bin_x )
00231 for ( int bin_y = min_bin_y; bin_y <= max_bin_y; ++ bin_y )
00232 for (typename bin_vector_type_::iterator p = bins_(bin_x,bin_y).begin();
00233 p != bins_( bin_x, bin_y ).end(); ++p )
00234 if ( vnl_vector_ssd( pt, p->point_ ) <= dist_tolerance_sqr_
00235 && p->value_ == value ) {
00236 bins_( bin_x, bin_y ).erase( p );
00237 return true;
00238 }
00239
00240 return false;
00241 }
00242
00243
00244 template < class COORD_T, class VALUE_T >
00245 void
00246 rsdl_bins_2d< COORD_T, VALUE_T > ::
00247 n_nearest( const vnl_vector_fixed< COORD_T, 2 >& query_pt,
00248 int n,
00249 vcl_vector< VALUE_T >& values ) const
00250 {
00251 vcl_vector< vnl_vector_fixed< COORD_T, 2 > > points;
00252 n_nearest( query_pt, n, points, values );
00253 }
00254
00255
00256 template < class COORD_T, class VALUE_T >
00257 void
00258 rsdl_bins_2d< COORD_T, VALUE_T > ::
00259 n_nearest( const vnl_vector_fixed< COORD_T, 2 > & query_pt,
00260 int n,
00261 vcl_vector< vnl_vector_fixed< COORD_T, 2 > > & points,
00262 vcl_vector< VALUE_T > & values ) const
00263 {
00264 assert( n >= 1 );
00265 points.clear();
00266 values.clear();
00267 vcl_vector< double > sq_distances( n );
00268
00269 int num_found = 0;
00270
00271 int c_bin_x, c_bin_y;
00272 this->point_to_bin( query_pt[0], query_pt[1], c_bin_x, c_bin_y );
00273
00274 int infinity_norm_dist = 0;
00275
00276 vcl_vector< int > bin_xs, bin_ys;
00277 bin_xs.push_back( c_bin_x );
00278 bin_ys.push_back( c_bin_y );
00279
00280 bool still_testing;
00281
00282 do {
00283 still_testing = false;
00284 for ( unsigned int i=0; i<bin_xs.size(); ++ i ) {
00285 if ( num_found < n ||
00286 this->min_sq_distance_to_bin( query_pt[0], query_pt[1], bin_xs[i], bin_ys[i] )
00287 < sq_distances[ num_found - 1 ] ) {
00288 still_testing = true;
00289 for (typename bin_vector_type_::const_iterator p = bins_( bin_xs[i], bin_ys[i] ).begin();
00290 p != bins_( bin_xs[i], bin_ys[i] ).end(); ++p )
00291 {
00292 COORD_T sq_d = vnl_vector_ssd( query_pt, p->point_ );
00293
00294 if ( num_found < n || sq_d < sq_distances[ num_found- 1] ) {
00295 if ( num_found < n ) {
00296 points.push_back( p -> point_ );
00297 values.push_back( p -> value_ );
00298 ++ num_found ;
00299 }
00300
00301 int j = num_found-2;
00302 while ( j >= 0 && sq_d < sq_distances[ j ] ) {
00303 points[ j+1 ] = points[ j ];
00304 values[ j+1 ] = values[ j ];
00305 sq_distances[ j+1 ] = sq_distances[ j ];
00306 -- j;
00307 }
00308 points[ j+1 ] = p -> point_;
00309 values[ j+1 ] = p -> value_;
00310 sq_distances[ j+1 ] = sq_d;
00311 }
00312 }
00313 }
00314 }
00315
00316 if ( still_testing )
00317 {
00318 infinity_norm_dist ++ ;
00319 bin_xs.clear(); bin_ys.clear();
00320
00321
00322 int lower_x_for_y = vnl_math_max( c_bin_x - infinity_norm_dist, 0 );
00323 int upper_x_for_y = vnl_math_min( c_bin_x + infinity_norm_dist, num_bins_x_-1 );
00324
00325
00326 if ( c_bin_y - infinity_norm_dist >= 0 ) {
00327 for ( int bin_x = lower_x_for_y; bin_x <= upper_x_for_y; ++ bin_x ) {
00328 bin_xs.push_back( bin_x );
00329 bin_ys.push_back( c_bin_y - infinity_norm_dist );
00330 }
00331 }
00332
00333
00334 if ( c_bin_y + infinity_norm_dist < num_bins_y_ ) {
00335 for ( int bin_x = lower_x_for_y; bin_x <= upper_x_for_y; ++ bin_x ) {
00336 bin_xs.push_back( bin_x );
00337 bin_ys.push_back( c_bin_y + infinity_norm_dist );
00338 }
00339 }
00340
00341 int lower_y_for_x = vnl_math_max( c_bin_y - infinity_norm_dist+1, 0 );
00342 int upper_y_for_x = vnl_math_min( c_bin_y + infinity_norm_dist-1, num_bins_y_-1 );
00343
00344
00345 if ( c_bin_x - infinity_norm_dist >= 0 ) {
00346 for ( int bin_y = lower_y_for_x; bin_y <= upper_y_for_x; ++ bin_y ) {
00347 bin_xs.push_back( c_bin_x - infinity_norm_dist );
00348 bin_ys.push_back( bin_y );
00349 }
00350 }
00351
00352
00353 if ( c_bin_x + infinity_norm_dist < num_bins_x_ ) {
00354 for ( int bin_y = lower_y_for_x; bin_y <= upper_y_for_x; ++ bin_y ) {
00355 bin_xs.push_back( c_bin_x + infinity_norm_dist );
00356 bin_ys.push_back( bin_y );
00357 }
00358 }
00359 }
00360 } while ( still_testing );
00361 }
00362
00363 template < class COORD_T, class VALUE_T >
00364 bool
00365 rsdl_bins_2d< COORD_T, VALUE_T > ::
00366 is_any_point_within_radius( const vnl_vector_fixed< COORD_T, 2 > & query_pt,
00367 COORD_T radius ) const
00368 {
00369 radius += vcl_sqrt(dist_tolerance_sqr_);
00370 COORD_T sq_radius = radius * radius;
00371
00372 int min_bin_x, min_bin_y;
00373 this->point_to_bin( query_pt[0] - radius, query_pt[1] - radius, min_bin_x, min_bin_y );
00374
00375 int max_bin_x, max_bin_y;
00376 this->point_to_bin( query_pt[0] + radius, query_pt[1] + radius, max_bin_x, max_bin_y );
00377
00378 for ( int bin_x = min_bin_x; bin_x <= max_bin_x; ++ bin_x )
00379 for ( int bin_y = min_bin_y; bin_y <= max_bin_y; ++ bin_y )
00380 for ( typename bin_vector_type_::const_iterator p = bins_(bin_x,bin_y).begin();
00381 p != bins_( bin_x, bin_y ).end(); ++p )
00382 if ( vnl_vector_ssd( query_pt, p->point_ ) < sq_radius )
00383 return true;
00384
00385 return false;
00386 }
00387
00388
00389 template < class COORD_T, class VALUE_T >
00390 void
00391 rsdl_bins_2d< COORD_T, VALUE_T > ::
00392 points_within_radius( const vnl_vector_fixed< COORD_T, 2> & query_pt,
00393 COORD_T radius,
00394 vcl_vector< VALUE_T > & values ) const
00395 {
00396 vcl_vector< vnl_vector_fixed< COORD_T, 2 > > points;
00397 points_within_radius( query_pt, radius, points, values );
00398 }
00399
00400
00401 template < class COORD_T, class VALUE_T >
00402 void
00403 rsdl_bins_2d< COORD_T, VALUE_T > ::
00404 points_within_radius( const vnl_vector_fixed< COORD_T, 2 > & query_pt,
00405 COORD_T radius,
00406 vcl_vector< vnl_vector_fixed< COORD_T, 2 > > & points,
00407 vcl_vector< VALUE_T > & values ) const
00408 {
00409 radius += vcl_sqrt(dist_tolerance_sqr_);
00410 COORD_T sq_radius = radius * radius;
00411
00412 int min_bin_x, min_bin_y;
00413 this->point_to_bin( query_pt[0] - radius, query_pt[1] - radius, min_bin_x, min_bin_y );
00414
00415 int max_bin_x, max_bin_y;
00416 this->point_to_bin( query_pt[0] + radius, query_pt[1] + radius, max_bin_x, max_bin_y );
00417
00418 points.clear();
00419 values.clear();
00420
00421 for ( int bin_x = min_bin_x; bin_x <= max_bin_x; ++ bin_x )
00422 for ( int bin_y = min_bin_y; bin_y <= max_bin_y; ++ bin_y )
00423 for ( typename bin_vector_type_::const_iterator p = bins_(bin_x,bin_y).begin();
00424 p != bins_( bin_x, bin_y ).end(); ++p )
00425 if ( vnl_vector_ssd( query_pt, p->point_ ) < sq_radius ) {
00426 points.push_back( p->point_ );
00427 values.push_back( p->value_ );
00428 }
00429 }
00430
00431
00432 template < class COORD_T, class VALUE_T >
00433 bool
00434 rsdl_bins_2d< COORD_T, VALUE_T > ::
00435 is_any_point_in_bounding_box( const vnl_vector_fixed<COORD_T,2>& min_query_pt,
00436 const vnl_vector_fixed<COORD_T,2>& max_query_pt) const
00437 {
00438 COORD_T distance = vcl_sqrt(dist_tolerance_sqr_);
00439 int min_bin_x, min_bin_y;
00440 this->point_to_bin( min_query_pt[0]-distance, min_query_pt[1]-distance, min_bin_x, min_bin_y );
00441
00442 int max_bin_x, max_bin_y;
00443 this->point_to_bin( max_query_pt[0]+distance, max_query_pt[1]+distance, max_bin_x, max_bin_y );
00444
00445 for ( int bin_x = min_bin_x; bin_x <= max_bin_x; ++ bin_x )
00446 for ( int bin_y = min_bin_y; bin_y <= max_bin_y; ++ bin_y )
00447 for (typename bin_vector_type_::const_iterator p = bins_(bin_x,bin_y).begin();
00448 p != bins_( bin_x, bin_y ).end(); ++p )
00449 if ( min_query_pt[0] <= p->point_[0] && p->point_[0] <= max_query_pt[0] &&
00450 min_query_pt[1] <= p->point_[1] && p->point_[1] <= max_query_pt[1] )
00451 return true;
00452
00453 return false;
00454 }
00455
00456
00457 template < class COORD_T, class VALUE_T >
00458 void
00459 rsdl_bins_2d< COORD_T, VALUE_T > ::
00460 points_in_bounding_box( const vnl_vector_fixed<COORD_T,2>& min_query_pt,
00461 const vnl_vector_fixed<COORD_T,2>& max_query_pt,
00462 vcl_vector< VALUE_T >& values ) const
00463 {
00464 vcl_vector< vnl_vector_fixed< COORD_T, 2 > > points;
00465 points_in_bounding_box( min_query_pt, max_query_pt, points, values );
00466 }
00467
00468
00469 template < class COORD_T, class VALUE_T >
00470 void
00471 rsdl_bins_2d< COORD_T, VALUE_T > ::
00472 points_in_bounding_box( const vnl_vector_fixed< COORD_T, 2 > & min_query_pt,
00473 const vnl_vector_fixed< COORD_T, 2 > & max_query_pt,
00474 vcl_vector< vnl_vector_fixed< COORD_T, 2 > > & points,
00475 vcl_vector< VALUE_T > & values ) const
00476 {
00477 COORD_T distance = vcl_sqrt(dist_tolerance_sqr_);
00478 int min_bin_x, min_bin_y;
00479 this->point_to_bin( min_query_pt[0]-distance, min_query_pt[1]-distance, min_bin_x, min_bin_y );
00480
00481 int max_bin_x, max_bin_y;
00482 this->point_to_bin( max_query_pt[0]+distance, max_query_pt[1]+distance, max_bin_x, max_bin_y );
00483
00484 points.clear();
00485 values.clear();
00486
00487 for ( int bin_x = min_bin_x; bin_x <= max_bin_x; ++ bin_x )
00488 for ( int bin_y = min_bin_y; bin_y <= max_bin_y; ++ bin_y )
00489 for (typename bin_vector_type_::const_iterator p = bins_(bin_x,bin_y).begin();
00490 p != bins_( bin_x, bin_y ).end(); ++p )
00491 if ( min_query_pt[0] <= p->point_[0] && p->point_[0] <= max_query_pt[0] &&
00492 min_query_pt[1] <= p->point_[1] && p->point_[1] <= max_query_pt[1] ) {
00493 points.push_back( p->point_ );
00494 values.push_back( p->value_ );
00495 }
00496 }
00497
00498
00499 template < class COORD_T, class VALUE_T >
00500 void
00501 rsdl_bins_2d< COORD_T, VALUE_T > ::
00502 point_to_bin( COORD_T x, COORD_T y, int& bin_x, int& bin_y ) const
00503 {
00504 bin_x = int( ( x - min_pt_[0] ) / bin_sizes_[0] );
00505
00506 if ( bin_x < 0 )
00507 bin_x = 0;
00508 else if ( bin_x >= num_bins_x_ )
00509 bin_x = num_bins_x_ - 1;
00510
00511 bin_y = int( ( y - min_pt_[1] ) / bin_sizes_[1] );
00512
00513 if ( bin_y < 0 )
00514 bin_y = 0;
00515 else if ( bin_y >= num_bins_y_ )
00516 bin_y = num_bins_y_ - 1;
00517 }
00518
00519
00520 template < class COORD_T, class VALUE_T >
00521 COORD_T
00522 rsdl_bins_2d< COORD_T, VALUE_T > ::
00523 min_sq_distance_to_bin( COORD_T x, COORD_T y, int bin_x, int bin_y ) const
00524 {
00525 COORD_T sq_dist = 0;
00526
00527 COORD_T min_x = min_pt_[0] + bin_x * bin_sizes_[0];
00528 COORD_T max_x = min_pt_[0] + (bin_x + 1) * bin_sizes_[0];
00529
00530 if ( x < min_x )
00531 sq_dist += vnl_math_sqr( min_x - x );
00532 else if ( x > max_x )
00533 sq_dist += vnl_math_sqr( x - max_x );
00534
00535 COORD_T min_y = min_pt_[1] + bin_y * bin_sizes_[1];
00536 COORD_T max_y = min_pt_[1] + (bin_y + 1) * bin_sizes_[1];
00537
00538 if ( y < min_y )
00539 sq_dist += vnl_math_sqr( min_y - y );
00540 else if ( y > max_y )
00541 sq_dist += vnl_math_sqr( y - max_y );
00542
00543 return sq_dist;
00544 }
00545
00546 template < class COORD_T, class VALUE_T >
00547 void
00548 rsdl_bins_2d< COORD_T, VALUE_T > ::
00549 change_value( const VALUE_T& old_val, const VALUE_T& new_val )
00550 {
00551 for ( int bin_x = 0; bin_x < num_bins_x_; ++ bin_x )
00552 for ( int bin_y = 0; bin_y < num_bins_y_; ++ bin_y )
00553 for (typename bin_vector_type_::iterator p = bins_(bin_x,bin_y).begin();
00554 p != bins_( bin_x, bin_y ).end(); ++p )
00555 if ( p->value_ == old_val )
00556 p->value_ = new_val;
00557 }
00558
00559 template < class COORD_T, class VALUE_T >
00560 unsigned
00561 rsdl_bins_2d< COORD_T, VALUE_T > ::
00562 num_pts() const
00563 {
00564 unsigned num = 0;
00565 for ( int bin_x = 0; bin_x < num_bins_x_; ++ bin_x )
00566 for ( int bin_y = 0; bin_y < num_bins_y_; ++ bin_y )
00567 num += bins_( bin_x, bin_y).size();
00568 return num;
00569 }
00570
00571 template < class COORD_T, class VALUE_T >
00572 vcl_ostream& operator<< ( vcl_ostream& ostr,
00573 const vcl_vector< rsdl_bins_2d_entry< COORD_T, VALUE_T > > & entries )
00574 {
00575 for ( unsigned int i=0; i<entries.size(); ++ i )
00576 ostr << i << ": point = " << entries[i].point_ << ", value = " << entries[i].value_ << '\n';
00577 return ostr;
00578 }
00579
00580
00581 #define RSDL_BINS_2D_INSTANTIATE( COORD_T, VALUE_T ) \
00582 template class rsdl_bins_2d_entry< COORD_T, VALUE_T >; \
00583 template class rsdl_bins_2d< COORD_T, VALUE_T >; \
00584 template vcl_ostream& \
00585 operator<< ( vcl_ostream& ostr, \
00586 const vcl_vector< rsdl_bins_2d_entry< COORD_T, VALUE_T > > & entry )
00587
00588 #endif // rsdl_bins_2d__txx_