00001 #include "bsol_point_index_2d.h"
00002
00003
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
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
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
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
00076 bsol_point_index_2d::~bsol_point_index_2d()
00077 {
00078 }
00079
00080
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
00093
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
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
00141 double x = p->x(), y = p->y();
00142 int row = 0, col =0;
00143 this->trans(x, y, row, col);
00144
00145 int row_radius = (int)(radius/row_spacing_),
00146 col_radius = (int)(radius/col_spacing_);
00147
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
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
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
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
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
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
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
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
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 }