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