contrib/brl/bbas/bsol/bsol_point_index_2d.cxx
Go to the documentation of this file.
00001 #include "bsol_point_index_2d.h"
00002 //:
00003 // \file
00004 #include <vsol/vsol_point_2d.h>
00005 #include <vsol/vsol_box_2d.h>
00006 #include "bsol_algs.h"
00007 #ifdef DEBUG
00008 #include <vcl_iostream.h>
00009 #endif
00010 
00011 static void clear_flag(vsol_point_2d_sptr& p)
00012 {
00013   p->unset_user_flag(VSOL_FLAG1);
00014 }
00015 
00016 static void set_flag(vsol_point_2d_sptr &  p)
00017 {
00018   p->set_user_flag(VSOL_FLAG1);
00019 }
00020 
00021 static bool flag(vsol_point_2d_sptr const&  p)
00022 {
00023   return p->get_user_flag(VSOL_FLAG1);
00024 }
00025 
00026 
00027 //------------------------------------------------------------------------
00028 //: Constructors
00029 //------------------------------------------------------------------------
00030 bsol_point_index_2d::bsol_point_index_2d(int nrows, int ncols,
00031                                          vsol_box_2d_sptr const& bb)
00032 {
00033   nrows_ = nrows;
00034   ncols_ = ncols;
00035   //initialize the array
00036   point_array_.resize(nrows);
00037   for (int r = 0; r<nrows; r++)
00038     point_array_[r].resize(ncols);
00039   b_box_ = bb;
00040   row_spacing_ = 1;
00041   col_spacing_ = 1;
00042   if (!bb)
00043     return;
00044   double w = b_box_->width(), h = b_box_->height();
00045 
00046   if (nrows)
00047     row_spacing_ = h/nrows;
00048   if (ncols)
00049     col_spacing_ = w/ncols;
00050 }
00051 
00052 bsol_point_index_2d::
00053 bsol_point_index_2d(int nrows, int ncols,
00054                     vcl_vector<vsol_point_2d_sptr> const& points)
00055 {
00056   nrows_ = nrows;
00057   ncols_ = ncols;
00058   //initialize the array
00059   point_array_.resize(nrows);
00060   for (int r = 0; r<nrows; r++)
00061     point_array_[r].resize(ncols);
00062   vbl_bounding_box<double,2> box = bsol_algs::bounding_box(points);
00063   b_box_ = new vsol_box_2d(box);
00064 
00065   double w = b_box_->width(), h = b_box_->height();
00066   row_spacing_ = 1;
00067   col_spacing_ = 1;
00068   if (nrows)
00069     row_spacing_ = h/nrows;
00070   if (ncols)
00071     col_spacing_ = w/ncols;
00072   this->add_points(points);
00073 }
00074 
00075 //: Destructor
00076 bsol_point_index_2d::~bsol_point_index_2d()
00077 {
00078 }
00079 
00080 //:offset to origin of bounds and convert to cell integer coordinates
00081 bool bsol_point_index_2d::trans(const double x, const double y,
00082                                 int& row, int& col)
00083 {
00084   if (!bsol_algs::in(b_box_, x, y))
00085     return false;
00086   col = (int)((x-b_box_->get_min_x())/col_spacing_);
00087   row = (int)((y-b_box_->get_min_y())/row_spacing_);
00088   return true;
00089 }
00090 
00091 //---------------------------------------------------------------------
00092 //: Add a point to the index.
00093 //  Should check for duplicate points, but not doing that right now.
00094 //---------------------------------------------------------------------
00095 bool bsol_point_index_2d::add_point(vsol_point_2d_sptr const& p)
00096 {
00097   double x = p->x(), y = p->y();
00098   int row=0, col=0;
00099   if (!trans(x, y, row, col))
00100     return false;
00101   if (row<0||row>=nrows_||col<0||col>=ncols_)
00102     return false;
00103   point_array_[row][col].push_back(p);
00104   return true;
00105 }
00106 
00107 bool bsol_point_index_2d::add_points(vcl_vector<vsol_point_2d_sptr> const& points)
00108 {
00109   bool ok = true;
00110   for (vcl_vector<vsol_point_2d_sptr>::const_iterator pit = points.begin();
00111        pit != points.end(); pit++)
00112     if (!this->add_point(*pit))
00113       ok = false;
00114   return ok;
00115 }
00116 
00117 bool bsol_point_index_2d::find_point(vsol_point_2d_sptr const& p)
00118 {
00119   int row=0, col=0;
00120   if (!this->trans(p->x(), p->y(), row, col))
00121     return false;
00122   if (row<0||row>=nrows_||col<0||col>=ncols_)
00123     return false;
00124   vcl_vector<vsol_point_2d_sptr>& points =  point_array_[row][col];
00125   for (vcl_vector<vsol_point_2d_sptr>::iterator pit = points.begin();
00126        pit!=points.end(); pit++)
00127     if ((*pit)==p)
00128       return true;
00129   return false;
00130 }
00131 
00132 //:find the points within a radius of p
00133 bool bsol_point_index_2d::in_radius(const double radius,
00134                                     vsol_point_2d_sptr const& p,
00135                                     vcl_vector<vsol_point_2d_sptr>& points)
00136 {
00137   if (!p)
00138     return false;
00139   bool found_points = false;
00140   // find the cell corresponding to p
00141   double x = p->x(), y = p->y();
00142   int row = 0, col =0;
00143   this->trans(x, y, row, col);
00144   //get points from surrounding cells
00145   int row_radius = (int)(radius/row_spacing_),
00146       col_radius = (int)(radius/col_spacing_);
00147   //include points near cell boundaries
00148   row_radius++; col_radius++;
00149   for (int ro = -row_radius; ro<=row_radius; ro++)
00150     for (int co = -col_radius; co<=col_radius; co++)
00151     {
00152       int r = row+ro, c = col+co;
00153       if (r<0||r>=nrows_||c<0||c>=ncols_)
00154         continue;
00155       vcl_vector<vsol_point_2d_sptr>& points_in_cell = point_array_[r][c];
00156       int n = points_in_cell.size();
00157       if (!n)
00158         continue;
00159       for (int i = 0; i<n; i++)
00160         if (!flag(points_in_cell[i]))
00161         {
00162           points.push_back(points_in_cell[i]);
00163           found_points = true;
00164         }
00165     }
00166   return found_points;
00167 }
00168 
00169 //:find the closest point with the specified radius.  If none return false.
00170 bool bsol_point_index_2d::closest_in_radius(const double radius,
00171                                             vsol_point_2d_sptr const& p,
00172                                             vsol_point_2d_sptr& point)
00173 {
00174   vcl_vector<vsol_point_2d_sptr> points;
00175   this->in_radius(radius, p, points);
00176   double d =0;
00177   point = bsol_algs::closest_point(p, points, d);
00178   if (!point||d>radius)
00179     return false;
00180 #ifdef DEBUG
00181   vcl_cout << "p("<< p->x() << ' ' << p->y()<< "):P(" << point->x() << ' ' << point->y() << "):" << d << vcl_endl;
00182 #endif
00183   return true;
00184 }
00185 
00186 void bsol_point_index_2d::clear()
00187 {
00188   for (int r =0; r<nrows_; r++)
00189     for (int c = 0; c<ncols_; c++)
00190       point_array_[r][c].clear();
00191 }
00192 
00193 bool bsol_point_index_2d::mark_point(vsol_point_2d_sptr& p)
00194 {
00195   if (!p||!this->find_point(p))
00196     return false;
00197   set_flag(p);
00198   return true;
00199 }
00200 
00201 bool bsol_point_index_2d::unmark_point(vsol_point_2d_sptr& p)
00202 {
00203   if (!p||!this->find_point(p))
00204     return false;
00205   clear_flag(p);
00206   return true;
00207 }
00208 
00209 bool bsol_point_index_2d::marked(vsol_point_2d_sptr const& p)
00210 {
00211   if (!p||!this->find_point(p))
00212     return false;
00213   return flag(p);
00214 }
00215 
00216 vcl_vector<vsol_point_2d_sptr> bsol_point_index_2d::points()
00217 {
00218   vcl_vector<vsol_point_2d_sptr> out;
00219   for (int r = 0; r<nrows_; r++)
00220     for (int c = 0; c<ncols_; c++)
00221     {
00222       vcl_vector<vsol_point_2d_sptr>& points = point_array_[r][c];
00223       for (vcl_vector<vsol_point_2d_sptr>::iterator pit = points.begin();
00224            pit!= points.end(); pit++)
00225         out.push_back(*pit);
00226     }
00227  return out;
00228 }
00229 
00230 void bsol_point_index_2d::clear_marks()
00231 {
00232   vcl_vector<vsol_point_2d_sptr> pts = this->points();
00233   for (vcl_vector<vsol_point_2d_sptr>::iterator pit = pts.begin();
00234        pit!= pts.end(); pit++)
00235     clear_flag(*pit);
00236 }
00237 
00238 //: origin of the index space
00239 void bsol_point_index_2d::origin(double& x0, double& y0)
00240 {
00241   x0 = 0;   y0 = 0;
00242   if (!b_box_)
00243     return;
00244   x0 = b_box_->get_min_x();
00245   y0 = b_box_->get_min_y();
00246 }
00247 
00248 //: number of points in a cell at r, c
00249 int bsol_point_index_2d::n_points(const int row, const int col)
00250 {
00251   if (row<0||row>=nrows_||col<0||col>=ncols_)
00252     return 0;
00253   int n = point_array_[row][col].size();
00254   return n;
00255 }
00256 
00257 //: number of points in a cell at x, y
00258 int bsol_point_index_2d::n_points(const double x, const double y)
00259 {
00260   int row=0, col=0;
00261   if (!trans(x, y, row, col))
00262     return 0;
00263   if (row<0||row>=nrows_||col<0||col>=ncols_)
00264     return 0;
00265   return point_array_[row][col].size();
00266 }
00267 
00268 //: total number of points in the index
00269 int bsol_point_index_2d::n_points()
00270 {
00271   int n = 0;
00272   for (int r = 0; r<nrows_; r++)
00273     for (int c = 0; c<ncols_; c++)
00274       n += n_points(r, c);
00275   return n;
00276 }
00277 
00278 //:the points in an index cell
00279 vcl_vector<vsol_point_2d_sptr> bsol_point_index_2d::
00280 points(const int row, const int col)
00281 {
00282   vcl_vector<vsol_point_2d_sptr> out;
00283   if (row<0||row>=nrows_||col<0||col>=ncols_)
00284     return out;
00285   return point_array_[row][col];
00286 }
00287 
00288 //: the box corresponding to an index cell, r, c
00289 vsol_box_2d_sptr bsol_point_index_2d::index_cell(const int row, const int col)
00290 {
00291   vsol_box_2d_sptr box = new vsol_box_2d();
00292   if (row<0||row>=nrows_||col<0||col>=ncols_)
00293     return box;
00294   //the cell origin
00295   double x0, y0;
00296   this->origin(x0, y0);
00297   double xmin = col_spacing_*col   + x0;
00298   double ymin = row_spacing_*row   + y0;
00299   box->add_point(xmin, ymin);
00300   box->add_point(xmin+col_spacing_, ymin+row_spacing_);
00301   return box;
00302 }
00303 
00304 vsol_box_2d_sptr bsol_point_index_2d::
00305 index_cell(const double x, const double y)
00306 {
00307   vsol_box_2d_sptr null;
00308   int row=0, col=0;
00309   if (!trans(x, y, row, col))
00310     return null;
00311   if (row<0||row>=nrows_||col<0||col>=ncols_)
00312     return null;
00313   return this->index_cell(row, col);
00314 }
00315 
00316 vsol_box_2d_sptr bsol_point_index_2d::point_bounds()
00317 {
00318   vsol_box_2d_sptr box = new vsol_box_2d();
00319   for (int r = 0; r<nrows_; r++)
00320     for (int c = 0; c<ncols_; c++)
00321     {
00322       vcl_vector<vsol_point_2d_sptr>& points = point_array_[r][c];
00323       for (vcl_vector<vsol_point_2d_sptr>::iterator pit = points.begin();
00324            pit!= points.end(); pit++)
00325         box->add_point((*pit)->x(), (*pit)->y());
00326     }
00327   return box;
00328 }