core/vgl/vgl_intersection.txx
Go to the documentation of this file.
00001 // This is core/vgl/vgl_intersection.txx
00002 #ifndef vgl_intersection_txx_
00003 #define vgl_intersection_txx_
00004 //:
00005 // \file
00006 // \author Gamze Tunali
00007 
00008 #include "vgl_intersection.h"
00009 
00010 #include <vcl_limits.h>
00011 #include <vcl_cassert.h>
00012 #include <vcl_cmath.h>
00013 #include <vgl/vgl_point_2d.h>
00014 #include <vgl/vgl_line_2d.h>
00015 #include <vgl/vgl_line_3d_2_points.h>
00016 #include <vgl/vgl_line_segment_2d.h>
00017 #include <vgl/vgl_line_segment_3d.h>
00018 #include <vgl/vgl_ray_3d.h>
00019 #include <vgl/vgl_vector_3d.h>
00020 #include <vgl/vgl_box_2d.h>
00021 #include <vgl/vgl_box_3d.h>
00022 #include <vgl/vgl_polygon.h>
00023 #include <vgl/vgl_plane_3d.h>
00024 #include <vgl/vgl_distance.h>
00025 #include <vgl/vgl_tolerance.h>
00026 #include <vgl/vgl_lineseg_test.txx>
00027 #include <vcl_vector.h>
00028 
00029 static double eps = 1.0e-8; // tolerance for intersections
00030 inline bool vgl_near_zero(double x) { return x < eps && x > -eps; }
00031 inline bool vgl_near_eq(double x, double y) { return vgl_near_zero(x-y); }
00032 
00033 //: Return the intersection of two boxes (which is itself is a box, possibly the empty box)
00034 // \relatesalso vgl_box_2d
00035 template <class T>
00036 vgl_box_2d<T> vgl_intersection(vgl_box_2d<T> const& b1,vgl_box_2d<T> const& b2)
00037 {
00038   T xmin = b1.min_x() > b2.min_x() ? b1.min_x() : b2.min_x();
00039   T ymin = b1.min_y() > b2.min_y() ? b1.min_y() : b2.min_y();
00040   T xmax = b1.max_x() < b2.max_x() ? b1.max_x() : b2.max_x();
00041   T ymax = b1.max_y() < b2.max_y() ? b1.max_y() : b2.max_y();
00042   return vgl_box_2d<T>(xmin,xmax,ymin,ymax);
00043 }
00044 
00045 //: Return true if line intersects box. If so, compute intersection points.
00046 // \relatesalso vgl_box_3d
00047 // \relatesalso vgl_infinite_line_3d
00048 template <class T>
00049 bool vgl_intersection(vgl_box_3d<T> const& box,
00050                       vgl_infinite_line_3d<T> const& line_3d,
00051                       vgl_point_3d<T>& p0,
00052                       vgl_point_3d<T>& p1)
00053 {
00054   vgl_point_3d<T> lpt = line_3d.point();
00055   vgl_vector_3d<T> di = line_3d.direction();
00056   vgl_point_3d<double> dpt(static_cast<double>(lpt.x()),
00057                            static_cast<double>(lpt.y()),
00058                            static_cast<double>(lpt.z()));
00059   vgl_vector_3d<double> dir(static_cast<double>(di.x()),
00060                             static_cast<double>(di.y()),
00061                             static_cast<double>(di.z()));
00062   vgl_infinite_line_3d<double> dline_3d(dpt, dir);
00063   // expand box by epsilon tolerance
00064   double xmin = box.min_x(), xmax = box.max_x(),
00065          ymin = box.min_y(), ymax = box.max_y(),
00066          zmin = box.min_z(), zmax = box.max_z();
00067   vgl_point_3d<double> minp(xmin, ymin, zmin), maxp(xmax, ymax, zmax);
00068   // find intersection point of the line with each of the six box planes
00069   vgl_vector_3d<double> vxmin(-1.0, 0.0, 0.0), vxmax(1.0, 0.0, 0.0),
00070                         vymin(0.0, -1.0, 0.0), vymax(0.0, 1.0, 0.0),
00071                         vzmin(0.0, 0.0, -1.0), vzmax(0.0, 0.0, 1.0);
00072   vgl_plane_3d<double> pl_xmin(vxmin, minp),
00073                        pl_xmax(vxmax, maxp),
00074                        pl_ymin(vymin, minp),
00075                        pl_ymax(vymax, maxp),
00076                        pl_zmin(vzmin, minp),
00077                        pl_zmax(vzmax, maxp);
00078   vgl_point_3d<double> pt_xmin(.0,.0,.0), pt_xmax(.0,.0,.0), // dummy initializ.
00079                        pt_ymin(.0,.0,.0), pt_ymax(.0,.0,.0), // to avoid
00080                        pt_zmin(.0,.0,.0), pt_zmax(.0,.0,.0); // compiler warning
00081   bool xmin_good = vgl_intersection(dline_3d, pl_xmin, pt_xmin);
00082   bool xmax_good = vgl_intersection(dline_3d, pl_xmax, pt_xmax);
00083   bool ymin_good = vgl_intersection(dline_3d, pl_ymin, pt_ymin);
00084   bool ymax_good = vgl_intersection(dline_3d, pl_ymax, pt_ymax);
00085   bool zmin_good = vgl_intersection(dline_3d, pl_zmin, pt_zmin);
00086   bool zmax_good = vgl_intersection(dline_3d, pl_zmax, pt_zmax);
00087   // Go through the six cases and return the two intersection points
00088   // that lie on box faces. Find the pair that are farthest apart.
00089   // There could be multiple intersections if the line passes through the
00090   // corners of the box.
00091   unsigned int npts = 0;
00092   vgl_point_3d<double> dp0=pt_xmin, dp1=pt_xmax; // keep this initialisation!
00093 
00094   // y-z face at xmin
00095   if (xmin_good &&
00096       pt_xmin.y()>=ymin && pt_xmin.y()<=ymax &&
00097       pt_xmin.z()>=zmin && pt_xmin.z()<=zmax)
00098   {
00099     // dp0 = pt_xmin; // not needed: already set when dp0 was initialised
00100     ++npts;
00101   }
00102   // y-z face at xmax
00103   if (xmax_good &&
00104       pt_xmax.y()>=ymin && pt_xmax.y()<=ymax &&
00105       pt_xmax.z()>=zmin && pt_xmax.z()<=zmax)
00106   {
00107     if  (npts == 0) dp0 = pt_xmax;
00108     // else         dp1 = pt_xmax; // not needed: already set when dp1 was initialised
00109     ++npts;
00110   }
00111   // x-z face at ymin
00112   if (ymin_good &&
00113       pt_ymin.x()>=xmin && pt_ymin.x()<=xmax &&
00114       pt_ymin.z()>=zmin && pt_ymin.z()<=zmax)
00115   {
00116     if      (npts == 0) { dp0 = pt_ymin; ++npts; }
00117     else if (npts == 1) { dp1 = pt_ymin; ++npts; }
00118     else /* npts == 2*/ if (sqr_length(pt_ymin-dp0)>sqr_length(dp1-dp0)) dp1 = pt_ymin;
00119   }
00120   // x-z face at ymax
00121   if (ymax_good &&
00122       pt_ymax.x()>=xmin && pt_ymax.x()<=xmax &&
00123       pt_ymax.z()>=zmin && pt_ymax.z()<=zmax)
00124   {
00125     if      (npts == 0) { dp0 = pt_ymax; ++npts; }
00126     else if (npts == 1) { dp1 = pt_ymax; ++npts; }
00127     else /* npts == 2*/ if (sqr_length(pt_ymax-dp0)>sqr_length(dp1-dp0)) dp1 = pt_ymax;
00128   }
00129   // x-y face at zmin
00130   if (zmin_good &&
00131       pt_zmin.x()>=xmin && pt_zmin.x()<=xmax &&
00132       pt_zmin.y()>=ymin && pt_zmin.y()<=ymax)
00133   {
00134     if      (npts == 0) { dp0 = pt_zmin; ++npts; }
00135     else if (npts == 1) { dp1 = pt_zmin; ++npts; }
00136     else /* npts == 2*/ if (sqr_length(pt_zmin-dp0)>sqr_length(dp1-dp0)) dp1 = pt_zmin;
00137   }
00138 
00139   // x-y face at zmax
00140   if (zmax_good &&
00141       pt_zmax.x()>=xmin && pt_zmax.x()<=xmax &&
00142       pt_zmax.y()>=ymin && pt_zmax.y()<=ymax)
00143   {
00144     if      (npts == 0) { dp0 = pt_zmax; ++npts; }
00145     else if (npts == 1) { dp1 = pt_zmax; ++npts; }
00146     else /* npts == 2*/ if (sqr_length(pt_zmax-dp0)>sqr_length(dp1-dp0)) dp1 = pt_zmax;
00147   }
00148 
00149   if (npts==2) {
00150     p0.set(static_cast<T>(dp0.x()),
00151            static_cast<T>(dp0.y()),
00152            static_cast<T>(dp0.z()));
00153     p1.set(static_cast<T>(dp1.x()),
00154            static_cast<T>(dp1.y()),
00155            static_cast<T>(dp1.z()));
00156     return true;
00157   }
00158   else
00159     return false;
00160 }
00161 
00162 //: Return true if ray intersects box. If so, compute intersection points.
00163 // If ray origin is inside box then p0==p1
00164 // \relatesalso vgl_box_3d
00165 // \relatesalso vgl_ray_3d
00166 template <class T>
00167 bool vgl_intersection(vgl_box_3d<T> const& box,
00168                       vgl_ray_3d<T> const& ray,
00169                       vgl_point_3d<T>& p0,
00170                       vgl_point_3d<T>& p1)
00171 {
00172   // convert ray to infinite line
00173   vgl_infinite_line_3d<T> linf(ray.origin(), ray.direction());
00174   bool good_inter = vgl_intersection(box, linf, p0, p1);
00175   if (!good_inter) return false;
00176   // check if ray origin is inside the box
00177   vgl_point_3d<T> org = ray.origin();
00178   vgl_vector_3d<T> dir = ray.direction();
00179   if (!box.contains(org))
00180     //check if the intersection points are in the ray domain
00181     return ray.contains(p0)&&ray.contains(p1);
00182 
00183   //ray origin is inside the box so find the intersection point in the
00184   //positive ray domain
00185   if (ray.contains(p0)) {
00186     p1 = p0; return true;
00187   }
00188   if (ray.contains(p1)) {
00189     p0 = p1; return true;
00190   }
00191   return false;
00192 }
00193 
00194 //: Return true if a box and plane intersect in 3D
00195 // \relatesalso vgl_plane_3d
00196 // \relatesalso vgl_box_3d
00197 template <class T>
00198 bool vgl_intersection(vgl_box_3d<T> const& b, vgl_plane_3d<T> const& plane)
00199 {
00200   // find the box corners
00201   vcl_vector<vgl_point_3d<T> > corners;
00202   corners.push_back(b.min_point());
00203   corners.push_back(vgl_point_3d<T> (b.min_x()+b.width(), b.min_y(), b.min_z()));
00204   corners.push_back(vgl_point_3d<T> (b.min_x()+b.width(), b.min_y()+b.height(), b.min_z()));
00205   corners.push_back(vgl_point_3d<T> (b.min_x(), b.min_y()+b.height(), b.min_z()));
00206   corners.push_back(vgl_point_3d<T> (b.min_x(), b.min_y(), b.max_z()));
00207   corners.push_back(vgl_point_3d<T> (b.min_x()+b.width(), b.min_y(), b.max_z()));
00208   corners.push_back(b.max_point());
00209   corners.push_back(vgl_point_3d<T> (b.min_x(), b.min_y()+b.height(), b.max_z()));
00210 
00211   // find the signed distance from the box corners to the plane
00212   int pos=0, neg=0;
00213   for (unsigned int c=0; c<corners.size(); c++) {
00214     vgl_point_3d<T> corner=corners[c];
00215     double d=(plane.a()*corner.x());
00216     d+=(plane.b()*corner.y());
00217     d+=(plane.c()*corner.z());
00218     d+=plane.d();
00219     if (d > 0)
00220       pos++;
00221     else if (d<0)
00222       neg++;
00223   }
00224   return neg!=8 && pos!=8; // completely inside polygon plane
00225 }
00226 
00227 //: Return the intersection of two boxes (which is itself either a box, or empty)
00228 // \relatesalso vgl_box_3d
00229 template <class T>
00230 vgl_box_3d<T> vgl_intersection(vgl_box_3d<T> const& b1,vgl_box_3d<T> const& b2)
00231 {
00232   T xmin = b1.min_x() > b2.min_x() ? b1.min_x() : b2.min_x();
00233   T ymin = b1.min_y() > b2.min_y() ? b1.min_y() : b2.min_y();
00234   T zmin = b1.min_z() > b2.min_z() ? b1.min_z() : b2.min_z();
00235   T xmax = b1.max_x() < b2.max_x() ? b1.max_x() : b2.max_x();
00236   T ymax = b1.max_y() < b2.max_y() ? b1.max_y() : b2.max_y();
00237   T zmax = b1.max_z() < b2.max_z() ? b1.max_z() : b2.max_z();
00238   return vgl_box_3d<T>(xmin,ymin,zmin,xmax,ymax,zmax);
00239 }
00240 
00241 //: compute the intersection of an infinite line with *this box.
00242 //  p0 and p1 are the intersection points
00243 // In the normal case (no degeneracies) there are six possible intersection combinations:
00244 // \verbatim
00245 //
00246 //                C01 /    CY     \ C11
00247 //                   /     |       \           .
00248 //       ymax  -----/------|--------\-----
00249 //            |    /       |         \    |
00250 //            |   /        |          \   |
00251 //            |  /         |           \  | \  .
00252 //            | /          |            \ |  \_ Bounding Box
00253 //            |/           |             \|
00254 //            /            |              \    .
00255 //           /|            |              |\   .
00256 //           ---------------------------------- CX
00257 //          \ |            |              /
00258 //           \|            |             /|
00259 //            \            |            / |
00260 //            |\           |           /  |
00261 //            | \          |          /   |
00262 //            |  \         |         /    |
00263 //       xmin  ---\--------|--------/-----   xmax
00264 //       ymin      \       |       /
00265 //              C00 \             / C10
00266 // \endverbatim
00267 
00268 template <class Type>
00269 bool vgl_intersection(const vgl_box_2d<Type>& box,
00270                       const vgl_line_2d<Type>& line,
00271                       vgl_point_2d<Type>& p0,
00272                       vgl_point_2d<Type>& p1)
00273 {
00274   double a = line.a(), b = line.b(), c = line.c();
00275   double xmin=box.min_x(), xmax=box.max_x();
00276   double ymin=box.min_y(), ymax=box.max_y();
00277 
00278   // Run through the cases
00279   //
00280   if (vgl_near_zero(a))// The line is y = -c/b
00281   {
00282     float y0 = static_cast<float>(-c/b);
00283     // The box edge is collinear with line?
00284     if (vgl_near_eq(ymin,y0))
00285     {
00286       p0.set(static_cast<Type>(xmin), static_cast<Type>(ymin));
00287       p1.set(static_cast<Type>(xmax), static_cast<Type>(ymin));
00288       return true;
00289     }
00290     if (vgl_near_eq(ymax,y0))
00291     {
00292       p0.set(static_cast<Type>(xmin), static_cast<Type>(ymax));
00293       p1.set(static_cast<Type>(xmax), static_cast<Type>(ymax));
00294       return true;
00295     }
00296 
00297     if ((ymin > y0) || (y0 > ymax)) // The line does not intersect the box
00298       return false;
00299     else // The line does intersect
00300     {
00301       p0.set(static_cast<Type>(xmin), static_cast<Type>(y0));
00302       p1.set(static_cast<Type>(xmax), static_cast<Type>(y0));
00303       return true;
00304     }
00305   }
00306 
00307   if (vgl_near_zero(b))// The line is x = -c/a
00308   {
00309     float x0 = static_cast<float>(-c/a);
00310     // The box edge is collinear with l?
00311     if (vgl_near_eq(xmin,x0))
00312     {
00313       p0.set(static_cast<Type>(xmin), static_cast<Type>(ymin));
00314       p1.set(static_cast<Type>(xmin), static_cast<Type>(ymax));
00315       return true;
00316     }
00317     if (vgl_near_eq(xmax,x0))
00318     {
00319       p0.set(static_cast<Type>(xmax), static_cast<Type>(ymin));
00320       p1.set(static_cast<Type>(xmax), static_cast<Type>(ymax));
00321       return true;
00322     }
00323 
00324     if (xmin <= x0 && x0 <= xmax) // The line intersects the box
00325     {
00326       p0.set(static_cast<Type>(x0), static_cast<Type>(ymin));
00327       p1.set(static_cast<Type>(x0), static_cast<Type>(ymax));
00328       return true;
00329     }
00330     else
00331       return false;
00332   }
00333 
00334   // The normal case with no degeneracies
00335   //
00336   // Intersection with x = xmin
00337   float y_xmin_int = static_cast<float>(-(c + a*xmin)/b);
00338   bool inside_xmin = (y_xmin_int >= ymin) && (y_xmin_int <= ymax);
00339 
00340   // Intersection with x = xmax
00341   float y_xmax_int = static_cast<float>(-(c + a*xmax)/b);
00342   bool inside_xmax = (y_xmax_int >= ymin) && (y_xmax_int <= ymax);
00343 
00344   // Intersection with y = ymin
00345   float x_ymin_int = static_cast<float>(-(c + b*ymin)/a);
00346   bool inside_ymin = (x_ymin_int >= xmin) && (x_ymin_int <= xmax);
00347 
00348   // Intersection with y = ymax
00349   float x_ymax_int = static_cast<float>(-(c + b*ymax)/a);
00350   bool inside_ymax = (x_ymax_int >= xmin) && (x_ymax_int <= xmax);
00351 
00352   // Case CX
00353   if (inside_xmin && inside_xmax &&
00354       !(vgl_near_eq(y_xmin_int,ymin) && vgl_near_eq(y_xmax_int,ymax)))
00355   {
00356     p0.set(static_cast<Type>(xmin), static_cast<Type>(y_xmin_int));
00357     p1.set(static_cast<Type>(xmax), static_cast<Type>(y_xmax_int));
00358     return true;
00359   }
00360 
00361   // Case CY
00362   if (inside_ymin && inside_ymax &&
00363       !(vgl_near_eq(x_ymin_int,xmin) && vgl_near_eq(x_ymax_int,xmax)))
00364   {
00365     p0.set(static_cast<Type>(x_ymin_int), static_cast<Type>(ymin));
00366     p1.set(static_cast<Type>(x_ymax_int), static_cast<Type>(ymax));
00367     return true;
00368   }
00369 
00370   // Case C00
00371   if (inside_xmin && inside_ymin &&
00372       !(inside_xmax && inside_ymax))
00373   {
00374     p0.set(static_cast<Type>(xmin), static_cast<Type>(y_xmin_int));
00375     p1.set(static_cast<Type>(x_ymin_int), static_cast<Type>(ymin));
00376     return true;
00377   }
00378 
00379   // Case C01
00380   if (inside_xmin && inside_ymax &&
00381       !(inside_xmax && inside_ymin))
00382   {
00383     p0.set(static_cast<Type>(xmin), static_cast<Type>(y_xmin_int));
00384     p1.set(static_cast<Type>(x_ymax_int), static_cast<Type>(ymax));
00385     return true;
00386   }
00387 
00388   // Case C10
00389   if (inside_ymin && inside_xmax &&
00390       !(inside_xmin && inside_ymax))
00391   {
00392     p0.set(static_cast<Type>(x_ymin_int), static_cast<Type>(ymin));
00393     p1.set(static_cast<Type>(xmax), static_cast<Type>(y_xmax_int));
00394     return true;
00395   }
00396 
00397   // Case C11
00398   if (inside_ymax && inside_xmax &&
00399       !(inside_xmin && inside_ymin))
00400   {
00401     p0.set(static_cast<Type>(x_ymax_int), static_cast<Type>(ymax));
00402     p1.set(static_cast<Type>(xmax), static_cast<Type>(y_xmax_int));
00403     return true;
00404   }
00405   // Exactly passing through diagonal of BB
00406   if (inside_xmin && inside_xmax && inside_ymin && inside_ymax)
00407   {
00408     if (a>0) // 45 degrees
00409     {
00410       p0.set(static_cast<Type>(xmin), static_cast<Type>(ymin));
00411       p1.set(static_cast<Type>(xmax), static_cast<Type>(ymax));
00412       return true;
00413     }
00414     else // 135 degrees
00415     {
00416       p0.set(static_cast<Type>(xmin), static_cast<Type>(ymax));
00417       p1.set(static_cast<Type>(xmax), static_cast<Type>(ymin));
00418       return true;
00419     }
00420   }
00421   return false;
00422 }
00423 
00424 //: Returns the number of intersections of a line segment with a box, up to two are returned in p0 and p1.
00425 template <class Type>
00426 unsigned int vgl_intersection(const vgl_box_2d<Type>& box,
00427                               const vgl_line_segment_2d<Type>& line_seg,
00428                               vgl_point_2d<Type>& p0,
00429                               vgl_point_2d<Type>& p1)
00430 {
00431   vgl_line_2d<Type> line(line_seg.a(), line_seg.b(), line_seg.c());
00432   vgl_point_2d<Type> pi0, pi1;
00433   // if no intersection just return
00434   if (!vgl_intersection<Type>(box, line, pi0, pi1))
00435     return 0;
00436   unsigned int nint = 0;
00437   // check if intersection points are interior to the line segment
00438   if (vgl_lineseg_test_point<Type>(pi0, line_seg)) {
00439     p0 = pi0;
00440     nint++;
00441   }
00442   if (vgl_lineseg_test_point<Type>(pi1, line_seg)) {
00443     p1 = pi1;
00444     nint++;
00445   }
00446   return nint;
00447 }
00448 
00449 //: Return the intersection point of two concurrent lines
00450 template <class T>
00451 vgl_point_3d<T> vgl_intersection(vgl_line_3d_2_points<T> const& l1,
00452                                  vgl_line_3d_2_points<T> const& l2)
00453 {
00454   assert(concurrent(l1,l2));
00455   T a0=l1.point1().x(),a1=l1.point2().x(),a2=l2.point1().x(),a3=l2.point2().x(),
00456     b0=l1.point1().y(),b1=l1.point2().y(),b2=l2.point1().y(),b3=l2.point2().y(),
00457     c0=l1.point1().z(),c1=l1.point2().z(),c2=l2.point1().z(),c3=l2.point2().z();
00458   T t1 = (b3-b2)*(a1-a0)-(a3-a2)*(b1-b0), t2 = (b0-b2)*(a1-a0)-(a0-a2)*(b1-b0);
00459   if (vcl_abs(t1) < 0.000001)
00460   {
00461     t1 = (c3-c2)*(a1-a0)-(a3-a2)*(c1-c0), t2 = (c0-c2)*(a1-a0)-(a0-a2)*(c1-c0);
00462     if (vcl_abs(t1) < 0.000001)
00463       t1 = (c3-c2)*(b1-b0)-(b3-b2)*(c1-c0), t2 = (c0-c2)*(b1-b0)-(b0-b2)*(c1-c0);
00464   }
00465 
00466   return vgl_point_3d<T>(((t1-t2)*a2+t2*a3)/t1,
00467                          ((t1-t2)*b2+t2*b3)/t1,
00468                          ((t1-t2)*c2+t2*c3)/t1);
00469 }
00470 
00471 //: Return the intersection point of segments of two concurrent lines
00472 // \relatesalso vgl_line_segment_3d
00473 template <class T>
00474 bool vgl_intersection(vgl_line_segment_3d<T> const& l1,
00475                       vgl_line_segment_3d<T> const& l2,
00476                       vgl_point_3d<T>& i_pnt)
00477 {
00478   vgl_line_3d_2_points<T> l21(l1.point1(),l1.point2());
00479   vgl_line_3d_2_points<T> l22(l2.point1(),l2.point2());
00480   if (!concurrent(l21, l22))
00481     return false;
00482   i_pnt = vgl_intersection(l21, l22);
00483 
00484   double l1_len =   length(l1.point1() - l1.point2());
00485   double l1_idist = length(l1.point1() - i_pnt) + length(l1.point2() - i_pnt);
00486   double l2_len =   length(l2.point1() - l2.point2());
00487   double l2_idist = length(l2.point1() - i_pnt) + length(l2.point2() - i_pnt);
00488   return vgl_near_zero(l1_len - l1_idist) && vgl_near_zero(l2_len - l2_idist);
00489 }
00490 
00491 //: Return the intersection point of segments of two concurrent lines
00492 // \relatesalso vgl_line_segment_3d
00493 // \relatesalso vgl_line_3d_2_points
00494 template <class T>
00495 bool vgl_intersection(vgl_line_3d_2_points<T> const& l1,
00496                       vgl_line_segment_3d<T> const& l2,
00497                       vgl_point_3d<T>& i_pnt)
00498 {
00499   vgl_line_3d_2_points<T> l22(l2.point1(),l2.point2());
00500   if (!concurrent(l1, l22))
00501     return false;
00502   i_pnt = vgl_intersection(l1, l22);
00503 
00504   double l1_len =   length(l1.point1() - l1.point2());
00505   double l1_idist = length(l1.point1() - i_pnt) + length(l1.point2() - i_pnt);
00506   double l2_len =   length(l2.point1() - l2.point2());
00507   double l2_idist = length(l2.point1() - i_pnt) + length(l2.point2() - i_pnt);
00508 
00509   return vgl_near_zero(l1_len - l1_idist) && vgl_near_zero(l2_len - l2_idist);
00510 }
00511 
00512 //: Return the intersection point of two lines, if concurrent.
00513 // \relatesalso vgl_infinite_line_3d
00514 template <class T>
00515 bool vgl_intersection(vgl_infinite_line_3d<T> const& l1,
00516                       vgl_infinite_line_3d<T> const& l2,
00517                       vgl_point_3d<T>& i_pnt)
00518 {
00519   vgl_line_3d_2_points<T> l21(l1.point(),l1.point_t(T(1)));
00520   vgl_line_3d_2_points<T> l22(l2.point(),l2.point_t(T(1)));
00521   if (!concurrent(l21, l22))
00522     return false;
00523   i_pnt = vgl_intersection(l21, l22);
00524   return l1.contains(i_pnt) && l2.contains(i_pnt);
00525 }
00526 
00527 template <class T>
00528 bool vgl_intersection(vgl_ray_3d<T> const& r1,
00529                       vgl_ray_3d<T> const& r2,
00530                       vgl_point_3d<T>& i_pnt)
00531 {
00532   vgl_line_3d_2_points<T> l21(r1.origin(),r1.origin()+r1.direction());
00533   vgl_line_3d_2_points<T> l22(r2.origin(),r2.origin()+r2.direction());
00534   if (!concurrent(l21, l22))
00535     return false;
00536   i_pnt = vgl_intersection(l21, l22);
00537   return r1.contains(i_pnt)&&r2.contains(i_pnt);
00538 }
00539 
00540 //: Return the intersection point of a line and a plane.
00541 // \relatesalso vgl_line_3d_2_points
00542 // \relatesalso vgl_plane_3d
00543 template <class T>
00544 vgl_point_3d<T> vgl_intersection(vgl_line_3d_2_points<T> const& line,
00545                                  vgl_plane_3d<T> const& plane)
00546 {
00547   vgl_vector_3d<T> dir = line.direction();
00548 
00549   vgl_point_3d<T> pt;
00550 
00551   double denom = plane.a()*dir.x() +
00552                  plane.b()*dir.y() +
00553                  plane.c()*dir.z();
00554 
00555   if (denom == 0)
00556   {
00557     const T inf = vcl_numeric_limits<T>::infinity();
00558     // Line is either parallel or coplanar
00559     // If the distance from a line endpoint to the plane is zero, coplanar
00560     if (vgl_distance(line.point1(), plane)==0.0)
00561       pt.set(inf,inf,inf);
00562     else
00563       pt.set(inf,0,0);
00564   }
00565   else
00566   {
00567     // Infinite line intersects plane
00568     double numer = - plane.a()*line.point1().x()
00569                    - plane.b()*line.point1().y()
00570                    - plane.c()*line.point1().z()
00571                    - plane.d();
00572 
00573     dir *= numer/denom;
00574     pt = line.point1() + dir;
00575   }
00576 
00577   return pt;
00578 }
00579 
00580 //: Return the intersection point of a line and a plane.
00581 // \relatesalso vgl_line_segment_3d
00582 // \relatesalso vgl_plane_3d
00583 template <class T>
00584 bool vgl_intersection(vgl_line_segment_3d<T> const& line,
00585                       vgl_plane_3d<T> const& plane,
00586                       vgl_point_3d<T> & i_pt)
00587 {
00588   vgl_vector_3d<T> dir = line.direction();
00589 
00590   // The calculation of both denom and numerator are both very dodgy numerically, especially if
00591   // denom or numerator is small compared to the summands. It would be good to find a more
00592   // numerically stable solution. IMS.
00593   const double tol = vcl_numeric_limits<T>::epsilon() * 10e3;
00594 
00595   double denom = plane.a()*dir.x() +
00596                  plane.b()*dir.y() +
00597                  plane.c()*dir.z();
00598 
00599   if (vcl_abs(denom) < tol)
00600   {
00601     // Line is either parallel or coplanar
00602     // If the distance from a line endpoint to the plane is zero, coplanar
00603     if (vgl_distance(line.point1(), plane)!=0.0)
00604       return false;
00605 
00606     const T inf = vcl_numeric_limits<T>::infinity();
00607     i_pt.set(inf,inf,inf);
00608     return true;
00609   }
00610 
00611   double numer = - plane.a()*line.point1().x()
00612                  - plane.b()*line.point1().y()
00613                  - plane.c()*line.point1().z()
00614                  - plane.d();
00615 
00616   double t = numer/denom; // 0<t<1 between two points
00617   if (t < 0 || t > 1.0) return false;
00618 
00619   i_pt = line.point1() + t * dir;
00620   return true;
00621 }
00622 
00623 template <class T>
00624 bool vgl_intersection(vgl_infinite_line_3d<T> const& line,
00625                       vgl_plane_3d<T> const& plane,
00626                       vgl_point_3d<T> & i_pt)
00627 {
00628   vgl_vector_3d<T> dir = line.direction();
00629   vgl_point_3d<T> pt = line.point();
00630   // The calculation of both denom and numerator are both very dodgy numerically, especially if
00631   // denom or numerator is small compared to the summands. It would be good to find a more
00632   // numerically stable solution. IMS.
00633   const double tol = vcl_numeric_limits<T>::epsilon() * 10e3;
00634 
00635   double denom = plane.a()*dir.x() +
00636                  plane.b()*dir.y() +
00637                  plane.c()*dir.z();
00638 
00639   if (vcl_abs(denom) < tol)
00640   {
00641     // Line is either parallel or coplanar
00642     // If the distance from a line endpoint to the plane is zero, coplanar
00643     if (vgl_distance(pt, plane)!=0.0)
00644       return false;
00645 
00646     const T inf = vcl_numeric_limits<T>::infinity();
00647     i_pt.set(inf,inf,inf);
00648     return true;
00649   }
00650 
00651   double numer = - plane.a()*pt.x()
00652                  - plane.b()*pt.y()
00653                  - plane.c()*pt.z()
00654                  - plane.d();
00655 
00656   double t = numer/denom;
00657   i_pt = pt + t * dir;
00658   return true;
00659 }
00660 
00661 template <class T>
00662 bool vgl_intersection(vgl_ray_3d<T> const& ray,
00663                       vgl_plane_3d<T> const& plane,
00664                       vgl_point_3d<T> & i_pt)
00665 {
00666   vgl_vector_3d<T> dir = ray.direction();
00667   vgl_point_3d<T> pt = ray.origin();
00668   // The calculation of both denom and numerator are both very dodgy numerically, especially if
00669   // denom or numerator is small compared to the summands. It would be good to find a more
00670   // numerically stable solution. IMS.
00671   const double tol = vcl_numeric_limits<T>::epsilon() * 10e3;
00672 
00673   double denom = plane.a()*dir.x() +
00674                  plane.b()*dir.y() +
00675                  plane.c()*dir.z();
00676 
00677   if (vcl_abs(denom) < tol)
00678   {
00679     // Line is either parallel or coplanar
00680     // If the distance from a line endpoint to the plane is zero, coplanar
00681     if (vgl_distance(pt, plane)!=0.0)
00682       return false;
00683 
00684     const T inf = vcl_numeric_limits<T>::infinity();
00685     i_pt.set(inf,inf,inf);
00686     return true;
00687   }
00688 
00689   double numer = - plane.a()*pt.x()
00690                  - plane.b()*pt.y()
00691                  - plane.c()*pt.z()
00692                  - plane.d();
00693 
00694   double t = numer/denom;
00695   if (t<0) return false;
00696   i_pt = pt + t * dir;
00697   return true;
00698 }
00699 
00700 template <class T>
00701 bool vgl_intersection( const vgl_line_2d<T> &line0,
00702                        const vgl_line_2d<T> &line1,
00703                        vgl_point_2d<T>      &intersection_point )
00704 {
00705   T a0, b0, c0,  a1, b1, c1;
00706   a0 = line0.a(); b0 = line0.b(); c0 = line0.c();
00707   a1 = line1.a(); b1 = line1.b(); c1 = line1.c();
00708 
00709   T delta, delta_x, delta_y, x, y;
00710   delta = a0*b1 - a1*b0;
00711   if ( vcl_abs(delta) <= vgl_tolerance<T>::position ) // Lines are parallel
00712     return false;
00713   delta_x = -c0*b1 + b0*c1; delta_y = -a0*c1 + a1*c0;
00714   x = delta_x / delta; y = delta_y / delta;
00715 
00716   //   intersection_point.set( (Type)x, (Type)y );
00717   intersection_point.set( x, y );
00718   return true;
00719 }
00720 
00721 //: Return the intersection line of two planes. Returns false if planes
00722 // are effectively parallel
00723 // \relatesalso vgl_infinite_line_3d
00724 // \relatesalso vgl_plane_3d
00725 template <class T>
00726 bool vgl_intersection(vgl_plane_3d<T> const& plane0,
00727                       vgl_plane_3d<T> const& plane1,
00728                       vgl_infinite_line_3d<T>& line)
00729 {
00730   double n0x = static_cast<double>(plane0.a());
00731   double n0y = static_cast<double>(plane0.b());
00732   double n0z = static_cast<double>(plane0.c());
00733   double n1x = static_cast<double>(plane1.a());
00734   double n1y = static_cast<double>(plane1.b());
00735   double n1z = static_cast<double>(plane1.c());
00736   vgl_vector_3d<double> n0(n0x, n0y, n0z);
00737   vgl_vector_3d<double> n1(n1x, n1y, n1z);
00738   // t is the direction vector of the line
00739   vgl_vector_3d<double> t = cross_product(n0, n1);
00740   double mag = t.length();
00741   if (vgl_near_zero(mag)) // planes are parallel (or coincident)
00742     return false;
00743   t/=mag; // create unit vector
00744   double tx = vcl_fabs(static_cast<double>(t.x_));
00745   double ty = vcl_fabs(static_cast<double>(t.y_));
00746   double tz = vcl_fabs(static_cast<double>(t.z_));
00747   // determine maximum component of t
00748   char component = 'x';
00749   if (ty>=tx&&ty>=tz)
00750     component = 'y';
00751   if (tz>=tx&&tz>=ty)
00752     component = 'z';
00753   double d0 = static_cast<double>(plane0.d());
00754   double d1 = static_cast<double>(plane1.d());
00755   vgl_point_3d<double> p0d;
00756   switch (component)
00757   {
00758     // x is the largest component of t
00759     case 'x':
00760     {
00761       double det = n0y*n1z-n1y*n0z;
00762       if (vgl_near_zero(det))
00763         return false;
00764       double neuy = d1*n0z - d0*n1z;
00765       double neuz = d0*n1y - d1*n0y;
00766       p0d.set(0.0, neuy/det, neuz/det);
00767       break;
00768     }
00769     case 'y':
00770     {
00771       double det = n0x*n1z-n1x*n0z;
00772       if (vgl_near_zero(det))
00773         return false;
00774       double neux = d1*n0z - d0*n1z;
00775       double neuz = d0*n1x - d1*n0x;
00776       p0d.set(neux/det, 0.0, neuz/det);
00777       break;
00778     }
00779     case 'z':
00780     default:
00781     {
00782       double det = n0x*n1y-n1x*n0y;
00783       if (vgl_near_zero(det))
00784         return false;
00785       double neux = d1*n0y - d0*n1y;
00786       double neuy = d0*n1x - d1*n0x;
00787       p0d.set(neux/det, neuy/det, 0.0);
00788       break;
00789     }
00790   }
00791   vgl_point_3d<T> p0(static_cast<T>(p0d.x()),
00792                      static_cast<T>(p0d.y()),
00793                      static_cast<T>(p0d.z()));
00794   vgl_vector_3d<T> tt(static_cast<T>(t.x()),
00795                       static_cast<T>(t.y()),
00796                       static_cast<T>(t.z()));
00797   line = vgl_infinite_line_3d<T>(p0, tt);
00798   return true;
00799 }
00800 
00801 //: Return the intersection point of three planes.
00802 // \relatesalso vgl_plane_3d
00803 template <class T>
00804 vgl_point_3d<T> vgl_intersection(const vgl_plane_3d<T>& p1,
00805                                  const vgl_plane_3d<T>& p2,
00806                                  const vgl_plane_3d<T>& p3)
00807 {
00808   vgl_point_3d<T> p(p1, p2, p3);
00809   return p;
00810 }
00811 
00812 //: Return true if any point on [p1,p2] is within tol of [q1,q2]
00813 //  Tests two line segments for intersection or near intersection
00814 //  (within given tolerance).
00815 // \author Dan jackson
00816 template <class T>
00817 bool vgl_intersection(vgl_point_2d<T> const& p1,
00818                       vgl_point_2d<T> const& p2,
00819                       vgl_point_2d<T> const& q1,
00820                       vgl_point_2d<T> const& q2,
00821                       double tol)
00822 {
00823   vgl_vector_2d<T> u = p2 - p1;
00824   vgl_vector_2d<T> v(-u.y(),u.x());
00825   double uq1 = dot_product(q1 - p1,u);
00826   double vq1 = dot_product(q1 - p1,v);
00827   double tol2 = tol*tol;
00828   double L2 = sqr_length(u);
00829 
00830   // Check if q1 is in central band (either side of line p1-p2
00831   if (uq1 > 0 && uq1 < L2)
00832   {
00833     // Check if q1 is within tol of the line, ie |vq1/L| < tol
00834     if (vq1*vq1 <=tol2*L2) return true;
00835   }
00836   else
00837   {
00838     // Check if q1 is within tol of either end of line
00839     if ( (q1-p1).sqr_length() <= tol2 || (q1-p2).sqr_length() <= tol2 )
00840       return true;
00841   }
00842 
00843   // Repeat test for q2
00844   double uq2 = dot_product(q2 - p1,u);
00845   double vq2 = dot_product(q2 - p1,v);
00846 
00847   // Check if q2 is in central band (either side of line p1-p2
00848   if (uq2 > 0 && uq2 < L2)
00849   {
00850     // Check if q1 is within tol of the line, ie |vq1/L| < tol
00851     if (vq2*vq2 <=tol2*L2)
00852       return true;
00853   }
00854   else
00855   {
00856     // Check if q1 is within tol of either end of line
00857     if ( (q2-p1).sqr_length() <= tol2 || (q2-p2).sqr_length() <= tol2 )
00858       return true;
00859   }
00860 
00861   // The points q1 and q2 do not lie within the tolerance region
00862   // around line segment (p1,p2)
00863   // Now repeat the test the other way around,
00864   // testing whether points p1 and p2 lie in tolerance region
00865   // of line (q1,q2)
00866 
00867   u = q2 - q1;
00868   v.set(-u.y(),u.x());
00869   L2 = sqr_length(u);
00870 
00871   double up1 = dot_product(p1 - q1,u);
00872   double vp1 = dot_product(p1 - q1,v);
00873 
00874   // Check if p1 is in central band either side of line q1-q2
00875   if (up1 > 0 && up1 < L2)
00876   {
00877     // Check if p1 is within tol of the line, ie |vp1/L| < tol
00878     if (vp1*vp1 <=tol2*L2)
00879       return true;
00880   }
00881   else
00882   {
00883     // Check if p1 is within tol of either end of line
00884     if ( (p1-q1).sqr_length() <= tol2 || (p1-q2).sqr_length() <= tol2 )
00885       return true;
00886   }
00887 
00888   double up2 = dot_product(p2 - q1,u);
00889   double vp2 = dot_product(p2 - q1,v);
00890 
00891   // Check if p2 is in central band either side of line q1-q2
00892   if (up2 > 0 && up2 < L2)
00893   {
00894     // Check if p1 is within tol of the line, ie |vp1/L| < tol
00895     if (vp2*vp2 <=tol2*L2)
00896       return true;
00897   }
00898   else
00899   {
00900     // Check if p2 is within tol of either end of line
00901     if ( (p2-q1).sqr_length() <= tol2 || (p2-q2).sqr_length() <= tol2)
00902       return true;
00903   }
00904 
00905   // Now check for actual intersection
00906   return vq1*vq2 < 0 && vp1*vp2 < 0;
00907 }
00908 
00909 template <class T>
00910 bool vgl_intersection(const vgl_box_2d<T>& b,
00911                       const vgl_polygon<T>& poly)
00912 {
00913   // easy checks first
00914   // check if any poly vertices are inside the box
00915   unsigned int ns = poly.num_sheets();
00916   bool hit = false;
00917   for (unsigned int s = 0; s<ns&&!hit; ++s) {
00918     unsigned int n = (unsigned int)(poly[s].size());
00919     for (unsigned int i = 0; i<n&&!hit; ++i) {
00920       vgl_point_2d<T> p = poly[s][i];
00921       hit = b.contains(p.x(), p.y());
00922     }
00923   }
00924   if (hit) return true;
00925   // check if any box vertices are inside the polygon
00926   T minx = b.min_x(), maxx = b.max_x();
00927   T miny = b.min_y(), maxy = b.max_y();
00928   hit = poly.contains(minx, miny) || poly.contains(maxx, maxy) ||
00929     poly.contains(minx, maxy) || poly.contains(maxx, miny);
00930   if (hit) return true;
00931   // check if any polygon edges intersect the box
00932   for (unsigned int s = 0; s<ns&&!hit; ++s)
00933   {
00934     unsigned int n = (unsigned int)(poly[s].size());
00935     vgl_point_2d<T> ia, ib;
00936     vgl_point_2d<T> last = poly[s][0];
00937     for (unsigned int i = 1; i<n&&!hit; ++i)
00938     {
00939       vgl_point_2d<T> p = poly[s][i];
00940       vgl_line_segment_2d<T> l(last, p);
00941       hit = vgl_intersection<T>(b, l, ia, ib)>0;
00942       last = p;
00943     }
00944     if (!hit) {
00945       vgl_point_2d<T> start = poly[s][0];
00946       vgl_line_segment_2d<T> ll(last, start);
00947       hit = vgl_intersection<T>(b,ll, ia, ib)>0;
00948     }
00949   }
00950   return hit;
00951 }
00952 
00953 //: Return the points from the list that lie inside the box
00954 // \relatesalso vgl_point_2d
00955 // \relatesalso vgl_box_2d
00956 template <class T>
00957 vcl_vector<vgl_point_2d<T> > vgl_intersection(vgl_box_2d<T> const& b, vcl_vector<vgl_point_2d<T> > const& p)
00958 {
00959   vcl_vector<vgl_point_2d<T> > r;
00960   typename vcl_vector<vgl_point_2d<T> >::const_iterator i;
00961   for (i = p.begin(); i != p.end(); ++i)
00962     if (vgl_intersection(b, *i))
00963       r.push_back(*i);
00964   return r;
00965 }
00966 
00967 //: Return the points from the list that lie inside the box
00968 // \relatesalso vgl_point_2d
00969 // \relatesalso vgl_box_2d
00970 template <class T>
00971 vcl_vector<vgl_point_2d<T> > vgl_intersection(vcl_vector<vgl_point_2d<T> > const& p, vgl_box_2d<T> const& b)
00972 {
00973   vcl_vector<vgl_point_2d<T> > r;
00974   typename vcl_vector<vgl_point_2d<T> >::const_iterator i;
00975   for (i = p.begin(); i != p.end(); ++i)
00976     if (vgl_intersection(b, *i))
00977       r.push_back(*i);
00978   return r;
00979 }
00980 
00981 //: Return the points from the list that lie inside the box
00982 // \relatesalso vgl_point_3d
00983 // \relatesalso vgl_box_3d
00984 template <class T>
00985 vcl_vector<vgl_point_3d<T> > vgl_intersection(vgl_box_3d<T> const& b, vcl_vector<vgl_point_3d<T> > const& p)
00986 {
00987   vcl_vector<vgl_point_3d<T> > r;
00988   typename vcl_vector<vgl_point_3d<T> >::const_iterator i;
00989   for (i = p.begin(); i != p.end(); ++i)
00990     if (vgl_intersection(b, *i))
00991       r.push_back(*i);
00992   return r;
00993 }
00994 
00995 //: Return the points from the list that lie inside the box
00996 // \relatesalso vgl_point_3d
00997 // \relatesalso vgl_box_3d
00998 template <class T>
00999 vcl_vector<vgl_point_3d<T> > vgl_intersection(vcl_vector<vgl_point_3d<T> > const& p, vgl_box_3d<T> const& b)
01000 {
01001   vcl_vector<vgl_point_3d<T> > r;
01002   typename vcl_vector<vgl_point_3d<T> >::const_iterator i;
01003   for (i = p.begin(); i != p.end(); ++i)
01004     if (vgl_intersection(b, *i))
01005       r.push_back(*i);
01006   return r;
01007 }
01008 
01009 template <class T>
01010 vcl_vector<vgl_point_2d<T> > vgl_intersection(vgl_polygon<T> const& poly,
01011                                               vgl_line_2d<T> const& line){
01012   vcl_vector<vgl_point_2d<T> > ret;
01013   T tol = vcl_sqrt(vgl_tolerance<T>::position);
01014   T a = line.a(), b = line.b(), c = line.c();
01015   T norm = vcl_sqrt(a*a + b*b);
01016   a/=norm; b/=norm; c/=norm;
01017   unsigned ns = poly.num_sheets();
01018   for (unsigned s = 0; s<ns; ++s) {
01019     vcl_vector<vgl_point_2d<T> > sh = poly[s];
01020     unsigned nv = sh.size();
01021     for (unsigned i = 0; i<nv; ++i) {
01022       unsigned next = (i+1)%nv;
01023       vgl_point_2d<T> pa = sh[i];
01024       vgl_point_2d<T> pb = sh[next];
01025       //algebraic distances
01026       T ad_a = a*pa.x() +b*pa.y() +c;
01027       T ad_b = a*pb.x() +b*pb.y() +c;
01028       bool sign_a = ad_a>T(0);
01029       bool sign_b = ad_b>T(0);
01030       bool zero = vcl_abs(ad_a)<tol;
01031       //cases
01032       // 1) no intersections
01033       // 2) current vertex intersects
01034       // 3) intersection interior to poly edge
01035       // case 1
01036       if (!zero&&(sign_a == sign_b))
01037         continue;
01038       // case 2
01039       if (zero) {
01040         ret.push_back(pa);
01041         continue;
01042       }
01043       //case 3
01044       // find the intersection
01045       vgl_line_2d<T> edge(pa, pb);
01046       vgl_point_2d<T> p_int;
01047       if (!vgl_intersection(line, edge, p_int))
01048         continue;
01049       ret.push_back(p_int);
01050     }
01051   }
01052   return ret;
01053 }
01054 
01055 // Instantiate those functions which are suitable for integer instantiation.
01056 #undef VGL_INTERSECTION_BOX_INSTANTIATE
01057 #define VGL_INTERSECTION_BOX_INSTANTIATE(T) \
01058 template vgl_box_2d<T > vgl_intersection(vgl_box_2d<T > const&,vgl_box_2d<T > const&); \
01059 template vgl_box_3d<T > vgl_intersection(vgl_box_3d<T > const&,vgl_box_3d<T > const&); \
01060 template vcl_vector<vgl_point_2d<T > > vgl_intersection(vgl_box_2d<T > const&,vcl_vector<vgl_point_2d<T > > const&); \
01061 template vcl_vector<vgl_point_2d<T > > vgl_intersection(vcl_vector<vgl_point_2d<T > > const&,vgl_box_2d<T > const&); \
01062 template vcl_vector<vgl_point_3d<T > > vgl_intersection(vgl_box_3d<T > const&,vcl_vector<vgl_point_3d<T > > const&); \
01063 template vcl_vector<vgl_point_3d<T > > vgl_intersection(vcl_vector<vgl_point_3d<T > > const&,vgl_box_3d<T > const&); \
01064 template bool vgl_intersection(vgl_box_2d<T > const&,vgl_line_2d<T > const&,vgl_point_2d<T >&,vgl_point_2d<T >&); \
01065 template bool vgl_intersection(vgl_box_3d<T > const&,vgl_plane_3d<T > const&); \
01066 template bool vgl_intersection(vgl_box_3d<T > const&,vgl_infinite_line_3d<T > const&,vgl_point_3d<T >&,vgl_point_3d<T >&);\
01067 template bool vgl_intersection(vgl_box_3d<T > const&,vgl_ray_3d<T > const&,vgl_point_3d<T >&,vgl_point_3d<T >&)
01068 #undef VGL_INTERSECTION_INSTANTIATE
01069 #define VGL_INTERSECTION_INSTANTIATE(T) \
01070 template vgl_point_3d<T > vgl_intersection(vgl_line_3d_2_points<T > const&,vgl_line_3d_2_points<T > const&); \
01071 template bool vgl_intersection(vgl_line_segment_3d<T > const&,vgl_line_segment_3d<T > const&,vgl_point_3d<T >&); \
01072 template bool vgl_intersection(vgl_line_3d_2_points<T > const&,vgl_line_segment_3d<T > const&,vgl_point_3d<T >&); \
01073 template bool vgl_intersection(vgl_ray_3d<T > const&,vgl_ray_3d<T > const&,vgl_point_3d<T >&); \
01074 template vgl_point_3d<T > vgl_intersection(vgl_line_3d_2_points<T > const&,vgl_plane_3d<T > const&); \
01075 template bool vgl_intersection(vgl_line_segment_3d<T > const&,vgl_plane_3d<T > const&,vgl_point_3d<T >&); \
01076 template bool vgl_intersection(vgl_infinite_line_3d<T > const&,vgl_plane_3d<T > const&,vgl_point_3d<T >&); \
01077 template bool vgl_intersection(vgl_ray_3d<T > const& ray, vgl_plane_3d<T > const& plane, vgl_point_3d<T > & i_pt); \
01078 template bool vgl_intersection(vgl_infinite_line_3d<T > const&,vgl_infinite_line_3d<T > const&,vgl_point_3d<T >&); \
01079 template vgl_point_3d<T > vgl_intersection(vgl_plane_3d<T > const&,vgl_plane_3d<T > const&,vgl_plane_3d<T > const&); \
01080 template unsigned vgl_intersection(vgl_box_2d<T > const&,vgl_line_segment_2d<T > const&,vgl_point_2d<T >&,vgl_point_2d<T >&); \
01081 template bool vgl_intersection(vgl_line_2d<T > const&,vgl_line_2d<T > const&,vgl_point_2d<T >&); \
01082 template bool vgl_intersection(vgl_point_2d<T > const&,vgl_point_2d<T > const&,vgl_point_2d<T > const&,vgl_point_2d<T > const&,double); \
01083 template bool vgl_intersection(vgl_box_2d<T > const&,vgl_polygon<T > const&); \
01084 template bool vgl_intersection(vgl_plane_3d<T > const&,vgl_plane_3d<T > const&,vgl_line_segment_3d<T > &); \
01085 template bool vgl_intersection(vgl_plane_3d<T > const&,vgl_plane_3d<T > const&,vgl_infinite_line_3d<T >&); \
01086 template vcl_vector<vgl_point_2d<T > > vgl_intersection(vgl_polygon<T > const&, vgl_line_2d<T > const&); \
01087 VGL_INTERSECTION_BOX_INSTANTIATE(T)
01088 
01089 #endif // vgl_intersection_txx_