00001 #include "bsol_algs.h"
00002
00003
00004
00005 #include <vcl_compiler.h>
00006 #ifdef VCL_VC_6
00007
00008 # pragma warning(disable:4018 )
00009 #endif
00010
00011 #include <vnl/vnl_numeric_traits.h>
00012 #include <vsol/vsol_point_2d_sptr.h>
00013 #include <vsol/vsol_point_2d.h>
00014 #include <vsol/vsol_point_3d.h>
00015 #include <vsol/vsol_line_2d.h>
00016 #include <vsol/vsol_box_2d.h>
00017 #include <vsol/vsol_box_3d.h>
00018 #include <vsol/vsol_polygon_2d.h>
00019 #include <vsol/vsol_digital_curve_2d.h>
00020 #include <vgl/vgl_point_2d.h>
00021 #include <vgl/vgl_homg_point_2d.h>
00022 #include <vgl/vgl_box_2d.h>
00023 #include <vgl/vgl_intersection.h>
00024 #include <vgl/algo/vgl_convex_hull_2d.h>
00025
00026
00027 bsol_algs::~bsol_algs()
00028 {
00029 }
00030
00031
00032
00033
00034 vbl_bounding_box<double,2> bsol_algs::
00035 bounding_box(vcl_vector<vsol_point_2d_sptr> const& points)
00036 {
00037 vbl_bounding_box<double, 2> b;
00038 for (vcl_vector<vsol_point_2d_sptr>::const_iterator pit = points.begin();
00039 pit != points.end(); pit++)
00040 b.update((*pit)->x(), (*pit)->y());
00041 return b;
00042 }
00043
00044
00045
00046
00047 vbl_bounding_box<double,2> bsol_algs::
00048 bounding_box(vcl_vector<vsol_line_2d_sptr> const & lines)
00049 {
00050 vbl_bounding_box<double, 2> b;
00051 for (vcl_vector<vsol_line_2d_sptr>::const_iterator lit = lines.begin();
00052 lit != lines.end(); lit++)
00053 {
00054 vsol_point_2d_sptr p0 = (*lit)->p0();
00055 vsol_point_2d_sptr p1 = (*lit)->p1();
00056 b.update(p0->x(), p0->y());
00057 b.update(p1->x(), p1->y());
00058 }
00059 return b;
00060 }
00061
00062
00063
00064
00065 vbl_bounding_box<double,3> bsol_algs::
00066 bounding_box(vcl_vector<vsol_point_3d_sptr> const& points)
00067 {
00068 vbl_bounding_box<double, 3> b;
00069 for (vcl_vector<vsol_point_3d_sptr>::const_iterator pit = points.begin();
00070 pit != points.end(); pit++)
00071 b.update((*pit)->x(), (*pit)->y(), (*pit)->z());
00072 return b;
00073 }
00074
00075
00076
00077
00078 bool bsol_algs::in(vsol_box_2d_sptr const & b, double x, double y)
00079 {
00080 if (!b)
00081 return false;
00082 double xmin = b->get_min_x(), ymin = b->get_min_y();
00083 double xmax = b->get_max_x(), ymax = b->get_max_y();
00084 return x >= xmin && x <= xmax
00085 && y >= ymin && y <= ymax;
00086 }
00087
00088
00089 bool bsol_algs::meet(vsol_box_2d_sptr const & a, vsol_box_2d_sptr const & b)
00090 {
00091 double min_x_a = a->get_min_x(), max_x_a = a->get_max_x();
00092 double min_y_a = a->get_min_y(), max_y_a = a->get_max_y();
00093 double min_x_b = b->get_min_x(), max_x_b = b->get_max_x();
00094 double min_y_b = b->get_min_y(), max_y_b = b->get_max_y();
00095 return min_x_b <= max_x_a && min_x_a <= max_x_b
00096 && min_y_b <= max_y_a && min_y_a <= max_y_b;
00097 }
00098
00099
00100 bool bsol_algs::intersection(vsol_box_2d_sptr const & a,
00101 vsol_box_2d_sptr const & b,
00102 vsol_box_2d_sptr& a_int_b)
00103 {
00104 vgl_point_2d<double> a_min(a->get_min_x(), a->get_min_y());
00105 vgl_point_2d<double> a_max(a->get_max_x(), a->get_max_y());
00106 vgl_box_2d<double> vga(a_min, a_max);
00107
00108 vgl_point_2d<double> b_min(b->get_min_x(), b->get_min_y());
00109 vgl_point_2d<double> b_max(b->get_max_x(), b->get_max_y());
00110 vgl_box_2d<double> vgb(b_min, b_max);
00111 vgl_box_2d<double> temp = vgl_intersection(vga, vgb);
00112 if (temp.is_empty())
00113 return false;
00114 a_int_b = new vsol_box_2d();
00115 a_int_b->add_point(temp.min_x(), temp.min_y());
00116 a_int_b->add_point(temp.max_x(), temp.max_y());
00117 return true;
00118 }
00119
00120
00121 bool bsol_algs::box_union(vsol_box_2d_sptr const & a,
00122 vsol_box_2d_sptr const & b,
00123 vsol_box_2d_sptr& a_union_b)
00124 {
00125 if (!a||!b)
00126 return false;
00127 double x_min_a = a->get_min_x(), y_min_a = a->get_min_y();
00128 double x_max_a = a->get_max_x(), y_max_a = a->get_max_y();
00129 double x_min_b = b->get_min_x(), y_min_b = b->get_min_y();
00130 double x_max_b = b->get_max_x(), y_max_b = b->get_max_y();
00131 double x_min=x_min_a, y_min = y_min_a;
00132 double x_max=x_max_a, y_max = y_max_a;
00133 if (x_min_b<x_min)
00134 x_min = x_min_b;
00135 if (y_min_b<y_min)
00136 y_min = y_min_b;
00137 if (x_max_b>x_max)
00138 x_max = x_max_b;
00139 if (y_max_b>y_max)
00140 y_max = y_max_b;
00141 a_union_b = new vsol_box_2d();
00142 a_union_b->add_point(x_min, y_min);
00143 a_union_b->add_point(x_max, y_max);
00144 return true;
00145 }
00146
00147
00148
00149
00150 bool bsol_algs::box_with_margin(vsol_box_2d_sptr const & b,
00151 const double margin,
00152 vsol_box_2d_sptr& bmod)
00153 {
00154 if (!b)
00155 return false;
00156 double x_min = b->get_min_x(), y_min = b->get_min_y();
00157 double x_max = b->get_max_x(), y_max = b->get_max_y();
00158 double width = x_max-x_min, height = y_max-y_min;
00159
00160 if ((width+2*margin)<0)
00161 return false;
00162 if ((height+2*margin)<0)
00163 return false;
00164 bmod = new vsol_box_2d();
00165 bmod->add_point(x_min-margin, y_min-margin);
00166 bmod->add_point(x_max+margin, y_max+margin);
00167 return true;
00168 }
00169
00170
00171
00172
00173 bool bsol_algs::hull_of_poly_set(vcl_vector<vsol_polygon_2d_sptr> const& polys,
00174 vsol_polygon_2d_sptr& hull)
00175 {
00176 if (!polys.size())
00177 return false;
00178 vcl_vector<vgl_point_2d<double> > points;
00179 for (vcl_vector<vsol_polygon_2d_sptr>::const_iterator pit = polys.begin();
00180 pit != polys.end(); pit++)
00181 {
00182 if (!(*pit))
00183 return false;
00184 for (unsigned int i=0; i<(*pit)->size(); ++i)
00185 points.push_back(vgl_point_2d<double>((*pit)->vertex(i)->x(),
00186 (*pit)->vertex(i)->y()));
00187 }
00188 vgl_convex_hull_2d<double> ch(points);
00189 vgl_polygon<double> h = ch.hull();
00190 hull = bsol_algs::poly_from_vgl(h);
00191 return true;
00192 }
00193
00194
00195
00196
00197 bool bsol_algs::in(vsol_box_3d_sptr const & b,
00198 double x, double y, double z)
00199 {
00200 if (!b)
00201 return false;
00202 double xmin = b->get_min_x(), ymin = b->get_min_y(), zmin = b->get_min_z();
00203 double xmax = b->get_max_x(), ymax = b->get_max_y(), zmax = b->get_max_z();
00204 return x >= xmin && x <= xmax
00205 && y >= ymin && y <= ymax
00206 && z >= zmin && z <= zmax;
00207 }
00208
00209 vsol_polygon_2d_sptr bsol_algs::poly_from_box(vsol_box_2d_sptr const& box)
00210 {
00211 vcl_vector<vsol_point_2d_sptr> pts;
00212 vsol_point_2d_sptr pa = new vsol_point_2d(box->get_min_x(), box->get_min_y());
00213 vsol_point_2d_sptr pb = new vsol_point_2d(box->get_max_x(), box->get_min_y());
00214 vsol_point_2d_sptr pc = new vsol_point_2d(box->get_max_x(), box->get_max_y());
00215 vsol_point_2d_sptr pd = new vsol_point_2d(box->get_min_x(), box->get_max_y());
00216 pts.push_back(pa); pts.push_back(pb);
00217 pts.push_back(pc); pts.push_back(pd);
00218 return new vsol_polygon_2d(pts);
00219 }
00220
00221
00222 vsol_polygon_2d_sptr bsol_algs::poly_from_vgl(vgl_polygon<double> const& poly)
00223 {
00224 vsol_polygon_2d_sptr out;
00225 vcl_vector<vsol_point_2d_sptr> pts;
00226 if (poly.num_sheets() != 1)
00227 return out;
00228 vcl_vector<vgl_point_2d<double> > sheet = poly[0];
00229 for (vcl_vector<vgl_point_2d<double> >::iterator pit = sheet.begin();
00230 pit != sheet.end(); pit++)
00231 {
00232 vsol_point_2d_sptr p = new vsol_point_2d((*pit).x(), (*pit).y());
00233 pts.push_back(p);
00234 }
00235 out = new vsol_polygon_2d(pts);
00236 return out;
00237 }
00238
00239 vgl_polygon<double>
00240 bsol_algs::vgl_from_poly(vsol_polygon_2d_sptr const& poly)
00241 {
00242 vgl_polygon<double> vp(1);
00243 if (!poly)
00244 return vp;
00245 unsigned nverts = poly->size();
00246 for (unsigned i = 0; i<nverts; ++i)
00247 {
00248 double x = poly->vertex(i)->x(), y = poly->vertex(i)->y();
00249 vp.push_back(x, y);
00250 }
00251 return vp;
00252 }
00253
00254
00255 vsol_point_2d_sptr
00256 bsol_algs::closest_point(vsol_point_2d_sptr const& p,
00257 vcl_vector<vsol_point_2d_sptr> const& point_set,
00258 double& d)
00259 {
00260 vsol_point_2d_sptr cp;
00261 int n = point_set.size();
00262 if (!p||!n)
00263 return cp;
00264 double dmin_sq = vnl_numeric_traits<double>::maxval;
00265 double x = p->x(), y = p->y();
00266 for (vcl_vector<vsol_point_2d_sptr>::const_iterator pit = point_set.begin();
00267 pit!=point_set.end(); pit++)
00268 {
00269 double xs = (*pit)->x(), ys = (*pit)->y();
00270 double dsq = (x-xs)*(x-xs)+(y-ys)*(y-ys);
00271 if (dsq<dmin_sq)
00272 {
00273 dmin_sq = dsq;
00274 cp = *pit;
00275 }
00276 }
00277 d = vcl_sqrt(dmin_sq);
00278 return cp;
00279 }
00280
00281 vsol_point_3d_sptr
00282 bsol_algs::closest_point(vsol_point_3d_sptr const& p,
00283 vcl_vector<vsol_point_3d_sptr> const& point_set,
00284 double& d)
00285 {
00286 d = 0;
00287 vsol_point_3d_sptr cp;
00288 int n = point_set.size();
00289 if (!p||!n)
00290 return cp;
00291 double dmin_sq = vnl_numeric_traits<double>::maxval;
00292 double x = p->x(), y = p->y(), z = p->z();
00293 for (vcl_vector<vsol_point_3d_sptr>::const_iterator pit = point_set.begin();
00294 pit!=point_set.end(); pit++)
00295 {
00296 double xs = (*pit)->x(), ys = (*pit)->y(), zs = (*pit)->z();
00297 double dsq = (x-xs)*(x-xs) + (y-ys)*(y-ys) + (z-zs)*(z-zs);
00298 if (dsq<dmin_sq)
00299 {
00300 dmin_sq = dsq;
00301 cp = *pit;
00302 }
00303 }
00304 d = vcl_sqrt(dmin_sq);
00305 return cp;
00306 }
00307
00308
00309
00310
00311 bool bsol_algs::homography(vsol_polygon_2d_sptr const& p,
00312 vgl_h_matrix_2d<double> const& H,
00313 vsol_polygon_2d_sptr& Hp)
00314 {
00315 const int n = p->size();
00316 vcl_vector<vsol_point_2d_sptr> pts;
00317 const double tol = 1e-06;
00318 for (int i = 0; i<n; i++)
00319 {
00320 vsol_point_2d_sptr v = p->vertex(i);
00321 vgl_homg_point_2d<double> hp(v->x(), v->y());
00322 vgl_homg_point_2d<double> Hhp = H(hp);
00323 if (Hhp.ideal(tol))
00324 return false;
00325 vgl_point_2d<double> q(Hhp);
00326 vsol_point_2d_sptr qs = new vsol_point_2d(q.x(), q.y());
00327 pts.push_back(qs);
00328 }
00329 Hp = new vsol_polygon_2d(pts);
00330 return true;
00331 }
00332
00333
00334
00335
00336 vsol_polygon_2d_sptr bsol_algs::
00337 transform_about_point(vsol_polygon_2d_sptr const& p,
00338 vsol_point_2d_sptr const& c,
00339 vgl_h_matrix_2d<double> const& H)
00340 {
00341 const int n = p->size();
00342 vcl_vector<vsol_point_2d_sptr> pts;
00343 for (int i = 0; i<n; i++)
00344 {
00345 vsol_point_2d_sptr v = p->vertex(i);
00346
00347 vgl_homg_point_2d<double> hp(v->x() - c->x(), v->y() - c->y());
00348 vgl_homg_point_2d<double> Hhp = H(hp);
00349 vgl_point_2d<double> q(Hhp);
00350
00351 vsol_point_2d_sptr qs = new vsol_point_2d(q.x() + c->x(), q.y() + c->y());
00352 pts.push_back(qs);
00353 }
00354 return new vsol_polygon_2d(pts);
00355 }
00356
00357
00358
00359
00360 vsol_polygon_2d_sptr bsol_algs::
00361 transform_about_centroid(vsol_polygon_2d_sptr const& p,
00362 vgl_h_matrix_2d<double> const& H)
00363 {
00364 vsol_point_2d_sptr c = p->centroid();
00365 return bsol_algs::transform_about_point(p, c, H);
00366 }
00367
00368 bool bsol_algs::homography(vsol_box_2d_sptr const& b,
00369 vgl_h_matrix_2d<double> const& H,
00370 vsol_box_2d_sptr& Hb)
00371 {
00372 vsol_polygon_2d_sptr p = bsol_algs::poly_from_box(b);
00373 vsol_polygon_2d_sptr Hp;
00374 if (!homography(p, H, Hp))
00375 return false;
00376 Hb = Hp->get_bounding_box();
00377 return true;
00378 }
00379
00380 void bsol_algs::tangent(vsol_digital_curve_2d_sptr const& dc, unsigned index,
00381 double& dx, double& dy)
00382 {
00383 dx = 0; dy = 0;
00384 if (!dc)
00385 return;
00386 unsigned n = dc->size();
00387
00388 if (index>=n)
00389 return;
00390 if (index == 0)
00391 {
00392 vsol_point_2d_sptr p_n0 = dc->point(0);
00393 vsol_point_2d_sptr p_n1 = dc->point(1);
00394 dx = p_n1->x()-p_n0->x();
00395 dy = p_n1->y()-p_n0->y();
00396 return;
00397 }
00398
00399 if (index == n-1)
00400 {
00401 vsol_point_2d_sptr p_n1 = dc->point(n-1);
00402 vsol_point_2d_sptr p_n2 = dc->point(n-2);
00403 dx = p_n1->x()-p_n2->x();
00404 dy = p_n1->y()-p_n2->y();
00405 return;
00406 }
00407
00408 vsol_point_2d_sptr p_m1 = dc->point(index-1);
00409 vsol_point_2d_sptr p_p1 = dc->point(index+1);
00410 dx = p_p1->x()-p_m1->x();
00411 dy = p_p1->y()-p_m1->y();
00412 }
00413
00414 void bsol_algs::print(vsol_box_2d_sptr const& b)
00415 {
00416 if (!b)
00417 return;
00418 vcl_cout << *b << '\n';
00419 }
00420
00421 void bsol_algs::print(vsol_box_3d_sptr const& b)
00422 {
00423 if (!b)
00424 return;
00425 double xmin = b->get_min_x(), ymin = b->get_min_y(), zmin = b->get_min_z();
00426 double xmax = b->get_max_x(), ymax = b->get_max_y(), zmax = b->get_max_z();
00427
00428 vcl_cout << "vsol_box_2d[(" << xmin << ' ' << ymin << ' ' << zmin << ")<("
00429 << xmax << ' ' << ymax << ' ' << zmax << ")]\n";
00430 }
00431
00432 void bsol_algs::print(vsol_point_2d_sptr const& p)
00433 {
00434 if (!p)
00435 return;
00436 vcl_cout << *p << '\n';
00437 }
00438
00439 void bsol_algs::print(vsol_point_3d_sptr const& p)
00440 {
00441 if (!p)
00442 return;
00443 vcl_cout << "vsol_point_3d[ " << p->x() << ' ' << p->y() << ' '
00444 << p->z() << " ]\n";
00445 }