00001 #ifndef rsdl_bins_txx_
00002 #define rsdl_bins_txx_
00003
00004
00005
00006
00007
00008 #include "rsdl_bins.h"
00009
00010 #include <vcl_cassert.h>
00011 #include <vcl_iostream.h>
00012 #include <vcl_cmath.h>
00013 #include <vcl_vector.h>
00014 #include <vcl_algorithm.h>
00015 #include <vcl_cstddef.h>
00016
00017
00018
00019
00020
00021
00022 template<unsigned N, typename CoordType, typename ValueType>
00023 struct rsdl_bins_point_dist_entry
00024 {
00025 typedef rsdl_bins<N,CoordType,ValueType> bin_class;
00026 typedef rsdl_bins_bin_entry_type<N,CoordType,ValueType> bin_entry_type;
00027 typedef typename bin_class::coord_type coord_type;
00028 typedef typename bin_class::point_type point_type;
00029
00030 rsdl_bins_point_dist_entry( point_type const& query_pt,
00031 bin_entry_type const* entry );
00032
00033 inline bool operator<( rsdl_bins_point_dist_entry const& other ) const;
00034
00035 bin_entry_type const* entry_;
00036 coord_type sqr_dist_;
00037 };
00038
00039
00040
00041
00042
00043 template<unsigned N, typename C, typename V>
00044 rsdl_bins<N,C,V>::
00045 rsdl_bins( point_type const& min_coord,
00046 point_type const& max_coord,
00047 point_type const& bin_sizes )
00048 {
00049 dist_tol_ = 0.0;
00050
00051 int total_size = 1;
00052 for ( unsigned i=0; i < N; ++i ) {
00053 bin_size_[i] = bin_sizes[i];
00054 min_pt_[i] = min_coord[i];
00055 size_[i] = coord_to_bin( max_coord[i], i ) + 1;
00056 assert( size_[i] > 0 );
00057 total_size *= size_[i];
00058 }
00059
00060 bins_.resize( total_size );
00061 }
00062
00063
00064 template<unsigned N, typename C, typename V>
00065 void
00066 rsdl_bins<N,C,V>::
00067 set_distance_tolerance( coord_type const& tol )
00068 {
00069 dist_tol_ = tol;
00070 }
00071
00072
00073 template<unsigned N, typename C, typename V>
00074 void
00075 rsdl_bins<N,C,V>::
00076 clear()
00077 {
00078 typedef typename vcl_vector< bin_type >::iterator vec_iter;
00079
00080 for ( vec_iter i = bins_.begin(); i != bins_.end(); ++i ) {
00081 i->clear();
00082 }
00083 }
00084
00085
00086 template<unsigned N, typename C, typename V>
00087 void
00088 rsdl_bins<N,C,V>::
00089 add_point( point_type const& pt, value_type const& val )
00090 {
00091 bins_[ bin_index( pt ) ].push_back( bin_entry_type( pt, val ) );
00092 }
00093
00094
00095 template<unsigned N, typename C, typename V>
00096 bool
00097 rsdl_bins<N,C,V>::
00098 get_value( point_type const& pt, value_type& val ) const
00099 {
00100 typedef typename bin_index_vector::iterator ind_iter;
00101 typedef typename bin_type::const_iterator entry_iter;
00102
00103 coord_type dist_tol_sqr = dist_tol_*dist_tol_;
00104
00105
00106
00107
00108 bin_index_vector indices = bin_indices( pt );
00109 for ( ind_iter bi = indices.begin(); bi != indices.end(); ++bi ) {
00110 bin_type const& bin = bins_[*bi];
00111 for ( entry_iter ei = bin.begin(); ei != bin.end(); ++ei ) {
00112 if ( ei->equal( pt, dist_tol_sqr ) ) {
00113 val = ei->value_;
00114 return true;
00115 }
00116 }
00117 }
00118
00119
00120
00121 return false;
00122 }
00123
00124
00125 template<unsigned N, typename C, typename V>
00126 void
00127 rsdl_bins<N,C,V>::
00128 n_nearest( point_type const& pt,
00129 unsigned n,
00130 vcl_vector< value_type >& values ) const
00131 {
00132 n_nearest_impl( pt, n, values, 0 );
00133 }
00134
00135
00136 template<unsigned N, typename C, typename V>
00137 void
00138 rsdl_bins<N,C,V>::
00139 n_nearest( point_type const& pt,
00140 unsigned n,
00141 vcl_vector< point_type >& points,
00142 vcl_vector< value_type >& values ) const
00143 {
00144 n_nearest_impl( pt, n, values, &points );
00145 }
00146
00147
00148 template<unsigned N, typename C, typename V>
00149 void
00150 rsdl_bins<N,C,V>::
00151 n_nearest_exhaustive( point_type const& pt,
00152 unsigned n,
00153 vcl_vector< value_type >& values ) const
00154 {
00155 n_nearest_exhaustive_impl( pt, n, values, 0 );
00156 }
00157
00158
00159 template<unsigned N, typename C, typename V>
00160 void
00161 rsdl_bins<N,C,V>::
00162 n_nearest_exhaustive( point_type const& pt,
00163 unsigned n,
00164 vcl_vector< point_type >& points,
00165 vcl_vector< value_type >& values ) const
00166 {
00167 n_nearest_exhaustive_impl( pt, n, values, &points );
00168 }
00169
00170
00171 template<unsigned N, typename C, typename V>
00172 bool
00173 rsdl_bins<N,C,V>::
00174 is_any_point_within_radius( point_type const& pt,
00175 coord_type const& radius ) const
00176 {
00177
00178
00179
00180 vcl_vector< value_type > values;
00181 points_within_radius( pt, radius, values );
00182
00183 return ! values.empty();
00184 }
00185
00186
00187 template<unsigned N, typename C, typename V>
00188 void
00189 rsdl_bins<N,C,V>::
00190 points_within_radius( point_type const& pt,
00191 coord_type const& radius,
00192 vcl_vector< value_type >& values ) const
00193 {
00194 points_within_radius_impl( pt, radius, values, 0 );
00195 }
00196
00197
00198 template<unsigned N, typename C, typename V>
00199 void
00200 rsdl_bins<N,C,V>::
00201 points_within_radius( point_type const& pt,
00202 coord_type const& radius,
00203 vcl_vector< point_type >& points,
00204 vcl_vector< value_type >& values ) const
00205 {
00206 points_within_radius_impl( pt, radius, values, &points );
00207 }
00208
00209
00210 template<unsigned N, typename C, typename V>
00211 void
00212 rsdl_bins<N,C,V>::
00213 points_in_bounding_box( point_type const& min_pt,
00214 point_type const& max_pt,
00215 vcl_vector< value_type >& values ) const
00216 {
00217 points_in_bounding_box_impl( min_pt, max_pt, values, 0 );
00218 }
00219
00220
00221 template<unsigned N, typename C, typename V>
00222 void
00223 rsdl_bins<N,C,V>::
00224 points_in_bounding_box( point_type const& min_pt,
00225 point_type const& max_pt,
00226 vcl_vector< point_type >& points,
00227 vcl_vector< value_type >& values ) const
00228 {
00229 points_in_bounding_box_impl( min_pt, max_pt, values, &points );
00230 }
00231
00232
00233
00234
00235
00236 template<unsigned N, typename C, typename V>
00237 int
00238 rsdl_bins<N,C,V>::
00239 coord_to_bin( coord_type x, unsigned d ) const
00240 {
00241 return int( vcl_floor( ( x - min_pt_[d] ) / bin_size_[d] ) );
00242 }
00243
00244
00245 template<unsigned N, typename C, typename V>
00246 void
00247 rsdl_bins<N,C,V>::
00248 point_to_bin( point_type const& pt, int ind[N] ) const
00249 {
00250 for ( unsigned d=0; d < N; ++d ) {
00251 ind[d] = coord_to_bin( pt[d], d );
00252 if ( ind[d] < 0 ) {
00253 ind[d] = 0;
00254 } else if ( ind[d] >= size_[d] ) {
00255 ind[d] = size_[d] - 1;
00256 }
00257 }
00258 }
00259
00260
00261 template<unsigned N, typename C, typename V>
00262 typename rsdl_bins<N,C,V>::bin_index_type
00263 rsdl_bins<N,C,V>::
00264 bin_index( point_type const& pt ) const
00265 {
00266 bin_index_type index = 0;
00267 bin_index_type skip = 1;
00268
00269 for ( unsigned d=0; d < N; ++d ) {
00270 int i = coord_to_bin( pt[d], d );
00271 if ( i < 0 ) {
00272 i = 0;
00273 } else if ( i >= size_[d] ) {
00274 i = size_[d] - 1;
00275 }
00276 index += i*skip;
00277 skip *= size_[d];
00278 }
00279
00280 return index;
00281 }
00282
00283
00284 template<unsigned N, typename C, typename V>
00285 typename rsdl_bins<N,C,V>::bin_index_type
00286 rsdl_bins<N,C,V>::
00287 bin_index( int bin[N] ) const
00288 {
00289 bin_index_type index = 0;
00290 bin_index_type skip = 1;
00291
00292 for ( unsigned d=0; d < N; ++d ) {
00293 assert( 0 <= bin[d] && bin[d] < size_[d] );
00294 index += bin[d]*skip;
00295 skip *= size_[d];
00296 }
00297
00298 return index;
00299 }
00300
00301
00302 template<unsigned N, typename C, typename V>
00303 typename rsdl_bins<N,C,V>::bin_index_vector
00304 rsdl_bins<N,C,V>::
00305 bin_indices( point_type const& pt ) const
00306 {
00307 bin_index_vector indices;
00308
00309 int bin_lo[N], bin_hi[N];
00310 point_to_bin( pt-dist_tol_, bin_lo );
00311 point_to_bin( pt+dist_tol_, bin_hi );
00312
00313 if ( bin_lo == bin_hi ) {
00314 indices.push_back( bin_index( bin_lo ) );
00315 } else {
00316 int cur[N];
00317 scan_region( bin_lo, bin_hi, cur, 0, indices );
00318 }
00319
00320 return indices;
00321 }
00322
00323 template<unsigned N, typename C, typename V>
00324 void
00325 rsdl_bins<N,C,V>::
00326 closest_face ( point_type const& pt,
00327 int bin_lo[N],
00328 int bin_hi[N],
00329 unsigned * face_dim,
00330 unsigned * face_dir,
00331 coord_type * face_dist,
00332 bool & face_inf_dist) const
00333 {
00334 face_inf_dist = true;
00335 coord_type best_dist=0;
00336
00337
00338 for ( unsigned dim=0; dim<N; ++dim )
00339 {
00340
00341 for ( unsigned dir=0; dir<2; ++dir )
00342 {
00343
00344
00345 if ( dir == 0 )
00346 if ( bin_lo[dim] == 0 )
00347 continue;
00348 if ( dir == 1 )
00349 if ( bin_hi[dim] == ( size_[dim] - 1 ) )
00350 continue;
00351
00352 coord_type face_x;
00353
00354 if ( dir == 0 )
00355 face_x = bin_lo[dim] * bin_size_[dim] + min_pt_[dim];
00356 else
00357 face_x = ( bin_hi[dim] + 1 ) * bin_size_[dim] + min_pt_[dim];
00358
00359 coord_type dist = vcl_fabs ( pt[dim] - face_x );
00360 if ( face_inf_dist || dist < best_dist ) {
00361 if (face_dim) *face_dim = dim;
00362 if (face_dir) *face_dir = dir;
00363 if (face_dist) *face_dist = dist;
00364 face_inf_dist = false;
00365 best_dist = dist;
00366 }
00367 }
00368 }
00369 }
00370
00371
00372 template<unsigned N, typename C, typename V>
00373 void
00374 rsdl_bins<N,C,V>::
00375 n_nearest_impl( point_type const& pt,
00376 unsigned n,
00377 vcl_vector< value_type >& values,
00378 vcl_vector< point_type >* points ) const
00379 {
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 bool bin_rng_empty = true;
00392
00393 int bin_rng_lo[N], bin_rng_hi[N];
00394
00395 int bin_new_lo[N], bin_new_hi[N];
00396
00397
00398 coord_type nth_dist_sqr = 0;
00399
00400
00401 vcl_vector< point_dist_entry > distances;
00402
00403 bool done = false;
00404 while ( ! done )
00405 {
00406
00407
00408
00409
00410
00411 bool add_new_bins = false;
00412
00413 if ( distances.size() < n ) {
00414 add_new_bins = true;
00415 }
00416 else {
00417
00418
00419 vcl_nth_element( distances.begin(),
00420 distances.begin() + (n-1),
00421 distances.end() );
00422
00423
00424 if ( distances.size() > n )
00425 distances.erase( distances.begin() + n, distances.end() );
00426 assert ( distances.size() == n );
00427
00428
00429 nth_dist_sqr = distances[n-1].sqr_dist_;
00430
00431 coord_type face_dist = 0;
00432 bool face_inf_dist;
00433 closest_face (pt, bin_rng_lo, bin_rng_hi,
00434 0, 0, &face_dist, face_inf_dist);
00435
00436 if ( face_inf_dist || nth_dist_sqr <= face_dist*face_dist )
00437 done = true;
00438 else
00439 add_new_bins = true;
00440 }
00441
00442
00443
00444
00445
00446 bool found_new_bins = false;
00447
00448 if ( add_new_bins )
00449 {
00450 if ( bin_rng_empty )
00451 {
00452
00453 point_to_bin( pt, bin_rng_lo );
00454 for (unsigned i=0; i<N; ++i) bin_rng_hi[i] = bin_rng_lo[i];
00455 bin_rng_empty = false;
00456
00457
00458 for (unsigned i=0; i<N; ++i) bin_new_lo[i] = bin_rng_lo[i];
00459 for (unsigned i=0; i<N; ++i) bin_new_hi[i] = bin_rng_hi[i];
00460 found_new_bins = true;
00461 }
00462 else
00463 {
00464
00465
00466 unsigned face_dim = 0;
00467 unsigned face_dir = 0;
00468 bool face_inf_dist;
00469
00470 closest_face (pt, bin_rng_lo, bin_rng_hi,
00471 &face_dim, &face_dir, 0, face_inf_dist);
00472
00473 if ( ! face_inf_dist )
00474 {
00475
00476
00477
00478
00479 for (unsigned i=0; i<N; ++i) bin_new_lo[i] = bin_rng_lo[i];
00480 for (unsigned i=0; i<N; ++i) bin_new_hi[i] = bin_rng_hi[i];
00481
00482 assert( face_dim < N );
00483
00484 if ( face_dir == 0 ) {
00485 bin_rng_lo[face_dim] -= 1;
00486 bin_new_lo[face_dim] = bin_rng_lo[face_dim];
00487 bin_new_hi[face_dim] = bin_rng_lo[face_dim];
00488 }
00489 else {
00490 bin_rng_hi[face_dim] += 1;
00491 bin_new_lo[face_dim] = bin_rng_hi[face_dim];
00492 bin_new_hi[face_dim] = bin_rng_hi[face_dim];
00493 }
00494
00495 found_new_bins = true;
00496 }
00497 }
00498 }
00499
00500
00501
00502 if ( found_new_bins )
00503 {
00504
00505
00506
00507
00508 bin_index_vector indices;
00509
00510 int cur[N];
00511 scan_region( bin_new_lo, bin_new_hi, cur, 0, indices );
00512
00513 typedef typename bin_index_vector::iterator ind_iter;
00514 typedef typename bin_type::const_iterator entry_iter;
00515
00516 for ( ind_iter bi = indices.begin(); bi != indices.end(); ++bi ) {
00517 bin_type const& bin = bins_[*bi];
00518 for ( entry_iter ei = bin.begin(); ei != bin.end(); ++ei ) {
00519 distances.push_back( point_dist_entry( pt, &(*ei) ) );
00520 }
00521 }
00522 }
00523
00524
00525
00526
00527
00528
00529
00530 if ( add_new_bins && ! found_new_bins ) {
00531 done = true;
00532 }
00533 }
00534
00535
00536
00537
00538
00539
00540
00541 typedef typename vcl_vector< point_dist_entry >::iterator point_dist_iter;
00542
00543 assert( distances.size() <= n );
00544
00545 for ( point_dist_iter i = distances.begin(); i != distances.end(); ++i ) {
00546 values.push_back( i->entry_->value_ );
00547 if ( points ) {
00548 points->push_back( i->entry_->point_ );
00549 }
00550 }
00551 }
00552
00553 #if 0
00554
00555
00556
00557
00558 template<unsigned N, typename C, typename V>
00559 void
00560 rsdl_bins<N,C,V>::
00561 n_nearest_impl( point_type const& pt,
00562 unsigned n,
00563 vcl_vector< value_type >& values,
00564 vcl_vector< point_type >* points ) const
00565 {
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 static bool rsdl_bins_bug_warning_s = false;
00590 if ( rsdl_bins_bug_warning_s ) {
00591 vcl_cerr << "Warning: results from current rsdl_bins<N,C,V>::n_nearest_impl "
00592 << "may be inaccurate. Please contact developers for details.\n";
00593 rsdl_bins_bug_warning_s = false;
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605 bin_index_vector indices;
00606
00607
00608 int bin_lo[N], bin_hi[N], cur[N];
00609
00610 point_to_bin( pt, bin_lo );
00611 for (unsigned int i=0; i<N; ++i) bin_hi[i] = bin_lo[i];
00612
00613 bool still_looking = true;
00614 unsigned found = 0;
00615 do {
00616 found += scan_bdy( bin_lo, bin_hi, cur, 0, indices );
00617 if ( found >= n ) {
00618
00619
00620
00621
00622 unsigned k = (bin_hi[0] - bin_lo[0]) / 2;
00623
00624 unsigned f = unsigned( vcl_ceil( double(k+1) * vcl_sqrt(double(N)) - double(k) ) );
00625 for (unsigned j=0; j<f; ++j) {
00626 for (unsigned i=0; i<N; ++i) {
00627
00628 --bin_lo[i];
00629 ++bin_hi[i];
00630 }
00631 found += scan_bdy( bin_lo, bin_hi, cur, 0, indices );
00632 }
00633 still_looking = false;
00634 } else {
00635 bool some_dimension_in_bounds = false;
00636 for ( unsigned i=0; i < N; ++i ) {
00637 --bin_lo[i];
00638 ++bin_hi[i];
00639 if ( bin_lo[i] >= 0 || bin_hi[i] < size_[i] )
00640 some_dimension_in_bounds = true;
00641 }
00642
00643 if ( !some_dimension_in_bounds ) {
00644 still_looking = false;
00645 }
00646 }
00647 } while ( still_looking );
00648
00649
00650
00651
00652 typedef typename bin_index_vector::iterator ind_iter;
00653 typedef typename bin_type::const_iterator entry_iter;
00654
00655 vcl_vector< point_dist_entry > distances;
00656
00657 for ( ind_iter bi = indices.begin(); bi != indices.end(); ++bi ) {
00658 bin_type const& bin = bins_[*bi];
00659 for ( entry_iter ei = bin.begin(); ei != bin.end(); ++ei ) {
00660 distances.push_back( point_dist_entry( pt, &(*ei) ) );
00661 }
00662 }
00663
00664
00665
00666
00667 typedef typename vcl_vector< point_dist_entry >::iterator point_dist_iter;
00668
00669 point_dist_iter mid;
00670 if ( distances.size() > n ) {
00671 mid = distances.begin() + n;
00672 vcl_partial_sort( distances.begin(), mid, distances.end() );
00673 } else {
00674 mid = distances.end();
00675 }
00676
00677 #define support_points_outside_boundaries 0
00678 #if support_points_outside_boundaries
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 double longest_distance = vcl_sqrt(double((mid-1)->sqr_dist_));
00690
00691
00692 double r = ((bin_hi[0] - bin_lo[0]) / 2) * bin_size_[0];
00693
00694
00695 if (longest_distance > r) {
00696 unsigned reg_incr = unsigned(vcl_ceil(longest_distance / bin_size_[0] - (bin_hi[0] - bin_lo[0])/2));
00697 for (unsigned j=0; j<reg_incr; ++j) {
00698 for (unsigned i=0; i<N; ++i) {
00699
00700 --bin_lo[i];
00701 ++bin_hi[i];
00702 }
00703 found += scan_bdy( bin_lo, bin_hi, cur, 0, indices );
00704 }
00705
00706 distances.clear();
00707 for ( ind_iter bi = indices.begin(); bi != indices.end(); ++bi ) {
00708 bin_type const& bin = bins_[*bi];
00709 for ( entry_iter ei = bin.begin(); ei != bin.end(); ++ei ) {
00710 distances.push_back( point_dist_entry( pt, &(*ei) ) );
00711 }
00712 }
00713
00714 if ( distances.size() > n ) {
00715 mid = distances.begin() + n;
00716 vcl_partial_sort( distances.begin(), mid, distances.end() );
00717 }
00718 else {
00719 mid = distances.end();
00720 }
00721 }
00722
00723 #endif // end of support points outside region boundaries logic
00724
00725 for ( point_dist_iter i = distances.begin(); i != mid; ++i ) {
00726 values.push_back( i->entry_->value_ );
00727 if ( points ) {
00728 points->push_back( i->entry_->point_ );
00729 }
00730 }
00731 }
00732
00733 #endif
00734
00735 template<unsigned N, typename C, typename V>
00736 void
00737 rsdl_bins<N,C,V>::
00738 n_nearest_exhaustive_impl( point_type const& pt,
00739 unsigned n,
00740 vcl_vector< value_type >& values,
00741 vcl_vector< point_type >* points ) const
00742 {
00743 typedef typename vcl_vector< bin_type >::const_iterator vec_iter;
00744 typedef typename bin_type::const_iterator entry_iter;
00745 typedef typename vcl_vector< point_dist_entry >::iterator point_dist_iter;
00746
00747 vcl_vector< point_dist_entry > distances;
00748 coord_type nth_dist_sqr = 0;
00749
00750
00751 for ( vec_iter bi = bins_.begin(); bi != bins_.end(); ++bi ) {
00752 bin_type const & bin = *bi;
00753
00754 for ( entry_iter ei = bin.begin(); ei != bin.end(); ++ei ) {
00755 bin_entry_type const & entry = *ei;
00756
00757
00758
00759 if ( distances.size() < n
00760 || vnl_vector_ssd( pt, entry.point_ ) < nth_dist_sqr )
00761 {
00762 distances.push_back( point_dist_entry( pt, &entry ) );
00763
00764 if ( distances.size() >= n )
00765 vcl_nth_element ( distances.begin(),
00766 distances.begin() + (n-1),
00767 distances.end() );
00768
00769
00770
00771 if ( distances.size() > n ) {
00772 distances.pop_back();
00773
00774 assert ( distances.size() == n );
00775 }
00776
00777
00778
00779
00780 if ( distances.size() == n )
00781 nth_dist_sqr = distances[n-1].sqr_dist_;
00782 }
00783 }
00784 }
00785
00786
00787
00788
00789
00790
00791 for ( point_dist_iter i = distances.begin(); i != distances.end(); ++i ) {
00792 values.push_back( i->entry_->value_ );
00793 if ( points ) {
00794 points->push_back( i->entry_->point_ );
00795 }
00796 }
00797 }
00798
00799 template<unsigned N, typename C, typename V>
00800 void
00801 rsdl_bins<N,C,V>::
00802 points_within_radius_impl( point_type const& pt,
00803 coord_type const& radius,
00804 vcl_vector< value_type >& values,
00805 vcl_vector< point_type >* points ) const
00806 {
00807
00808
00809
00810
00811
00812
00813 bin_index_vector indices;
00814
00815
00816 int bin_lo[N], bin_hi[N], cur[N];
00817
00818 point_to_bin( pt-radius, bin_lo );
00819 point_to_bin( pt+radius, bin_hi );
00820
00821 scan_region( bin_lo, bin_hi, cur, 0, indices );
00822
00823
00824
00825
00826 typedef typename bin_index_vector::iterator ind_iter;
00827 typedef typename bin_type::const_iterator entry_iter;
00828
00829 coord_type rad_sqr = radius * radius;
00830 for ( ind_iter bi = indices.begin(); bi != indices.end(); ++bi ) {
00831 bin_type const& bin = bins_[*bi];
00832 for ( entry_iter ei = bin.begin(); ei != bin.end(); ++ei ) {
00833 coord_type dist_sqr = vnl_vector_ssd( pt, ei->point_ );
00834 if ( dist_sqr < rad_sqr ) {
00835 values.push_back( ei->value_ );
00836 if ( points ) {
00837 points->push_back( ei->point_ );
00838 }
00839 }
00840 }
00841 }
00842 }
00843
00844
00845 template<unsigned N, typename C, typename V>
00846 void
00847 rsdl_bins<N,C,V>::
00848 points_in_bounding_box_impl( point_type const& min_pt,
00849 point_type const& max_pt,
00850 vcl_vector< value_type >& values,
00851 vcl_vector< point_type >* points ) const
00852 {
00853
00854
00855
00856
00857
00858 bin_index_vector indices;
00859
00860
00861 int bin_lo[N], bin_hi[N], cur[N];
00862
00863 point_to_bin( min_pt, bin_lo );
00864 point_to_bin( max_pt, bin_hi );
00865
00866 scan_region( bin_lo, bin_hi, cur, 0, indices );
00867
00868
00869
00870
00871 typedef typename bin_index_vector::iterator ind_iter;
00872 typedef typename bin_type::const_iterator entry_iter;
00873
00874 for ( ind_iter bi = indices.begin(); bi != indices.end(); ++bi ) {
00875 bin_type const& bin = bins_[*bi];
00876 for ( entry_iter ei = bin.begin(); ei != bin.end(); ++ei ) {
00877 bool in_range = true;
00878 for ( unsigned d=0; d < N; ++d ) {
00879 if ( ei->point_[d] < min_pt[d] || ei->point_[d] > max_pt[d] ) {
00880 in_range = false;
00881 break;
00882 }
00883 }
00884 if ( in_range ) {
00885 values.push_back( ei->value_ );
00886 if ( points ) {
00887 points->push_back( ei->point_ );
00888 }
00889 }
00890 }
00891 }
00892 }
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 template<unsigned N, typename C, typename V>
00919 vcl_size_t
00920 rsdl_bins<N,C,V>::
00921 scan_region( int lo[N], int hi[N], int cur[N], unsigned dim,
00922 bin_index_vector& indices ) const
00923 {
00924 vcl_size_t found = 0;
00925
00926 if ( dim==N ) {
00927
00928 bin_index_type ind = bin_index( cur );
00929 indices.push_back( ind );
00930 found = bins_[ind].size();
00931 } else {
00932 int bx = vcl_max( lo[dim], 0 );
00933 int ex = vcl_min( hi[dim]+1, size_[dim] );
00934 for ( int x=bx; x < ex; ++x ) {
00935 cur[dim] = x;
00936 found += scan_region( lo, hi, cur, dim+1, indices );
00937 }
00938 }
00939
00940 return found;
00941 }
00942
00943 #if 0
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 template<unsigned N, typename C, typename V>
00962 unsigned
00963 rsdl_bins<N,C,V>::
00964 scan_bdy( int lo[N], int hi[N], int cur[N], unsigned dim,
00965 bin_index_vector& indices ) const
00966 {
00967 unsigned found = 0;
00968
00969
00970
00971
00972 if ( dim < N ) {
00973 int bx = vcl_max( lo[dim], 0 );
00974 int ex = vcl_min( hi[dim]+1, size_[dim] );
00975 int x = bx;
00976 if ( x==lo[dim] ) {
00977 cur[dim] = x;
00978 found += scan_region( lo, hi, cur, dim+1, indices );
00979 ++x;
00980 }
00981 for ( ; x < ex-1; ++x ) {
00982 cur[dim] = x;
00983 found += scan_bdy( lo, hi, cur, dim+1, indices );
00984 }
00985 if ( x==hi[dim] ) {
00986 cur[dim] = x;
00987 found += scan_region( lo, hi, cur, dim+1, indices );
00988 }
00989 }
00990
00991 return found;
00992 }
00993
00994 #endif
00995
00996
00997
00998
00999
01000
01001 template<unsigned N, typename C, typename V>
01002 rsdl_bins_bin_entry_type<N,C,V>::
01003 rsdl_bins_bin_entry_type( point_type const& pt, const value_type val )
01004 : point_( pt ),
01005 value_( val )
01006 {
01007 }
01008
01009 template<unsigned N, typename C, typename V>
01010 bool
01011 rsdl_bins_bin_entry_type<N,C,V>::
01012 equal( point_type const& pt, double tol_sqr ) const
01013 {
01014 return vnl_vector_ssd( pt, point_ ) < tol_sqr;
01015 }
01016
01017
01018
01019
01020
01021
01022 template<unsigned N, typename C, typename V>
01023 rsdl_bins_point_dist_entry<N,C,V>::
01024 rsdl_bins_point_dist_entry( point_type const& query_pt,
01025 bin_entry_type const* entry )
01026 : entry_( entry ),
01027 sqr_dist_( vnl_vector_ssd( query_pt, entry->point_ ) )
01028 {
01029 }
01030
01031
01032 template<unsigned N, typename C, typename V>
01033 bool
01034 rsdl_bins_point_dist_entry<N,C,V>::
01035 operator<( rsdl_bins_point_dist_entry const& other ) const
01036 {
01037 return this->sqr_dist_ < other.sqr_dist_;
01038 }
01039
01040 #define INSTANTIATE_RSDL_BINS( n, V, C ) \
01041 template class rsdl_bins< n, V, C >; \
01042 template struct rsdl_bins_bin_entry_type< n, V, C >; \
01043 template struct rsdl_bins_point_dist_entry< n, V, C >
01044
01045 #endif // rsdl_bins_txx_