contrib/brl/bbas/bsol/bsol_algs.cxx

Go to the documentation of this file.
00001 #include "bsol_algs.h"
00002 //:
00003 // \file
00004 
00005 #include <vcl_compiler.h>
00006 #ifdef VCL_VC_6
00007 //Get rid of warning generated by fault deep inside MS supplied library
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 // Destructor
00027 bsol_algs::~bsol_algs()
00028 {
00029 }
00030 
00031 //-----------------------------------------------------------------------------
00032 //: Compute a bounding box for a set of vsol_point_2ds.
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 //: Compute a bounding box for a set of vsol_line_2ds.
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 //: Compute a bounding box for a set of vsol_point_3ds.
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 //: Determine if a point is inside a bounding box
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 //: returns true if the boxes a and b intersect
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 //: find the intersection of two boxes. Return false if no intersection
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 //: find the convex union of two boxes. Always return true
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 //: expand or contract a box with the supplied absolute margin
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   //See if the margin for contraction is too large, i.e. margin is negative
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 //: Compute the convex hull of a set of polygons
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 //: Determine if a point is inside a bounding box
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 //: construct a vsol_polygon from a vgl_polygon
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 //: find the closest point to p in a set of points
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 //: Transform a vsol_polygon_2d with a general homography.
00319 //  Return false if any of the points are turned into ideal points
00320 //  since vsol geometry is assumed finite.
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 //: Transform a vsol_polygon_2d with a point specified as the center of the transformation.
00344 //  i.e. vertices of the polygon are translated so that the specified point is the origin.
00345 /// The transformation is then applied and the point coordinates added back in afterwards.
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     //Remove the centroid
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     //add it back in
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 //: Transform a vsol_polygon_2d with a homography
00368 //  Apply the transform with the centroid of the polygon as the
00369 //  origin and then translate by the centroid location vector
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   //cases
00398   if (index>=n)
00399     return;
00400   if (index == 0)// first point on curve
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)// last point on curve
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   //the normal case
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 }

Generated on Sun Sep 7 05:20:15 2008 for contrib/brl/bbas/bsol by  doxygen 1.5.1