00001
00002 #ifndef vgl_intersection_txx_
00003 #define vgl_intersection_txx_
00004
00005
00006
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;
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
00034
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
00046
00047
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
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
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),
00079 pt_ymin(.0,.0,.0), pt_ymax(.0,.0,.0),
00080 pt_zmin(.0,.0,.0), pt_zmax(.0,.0,.0);
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
00088
00089
00090
00091 unsigned int npts = 0;
00092 vgl_point_3d<double> dp0=pt_xmin, dp1=pt_xmax;
00093
00094
00095 if (xmin_good &&
00096 pt_xmin.y()>=ymin && pt_xmin.y()<=ymax &&
00097 pt_xmin.z()>=zmin && pt_xmin.z()<=zmax)
00098 {
00099
00100 ++npts;
00101 }
00102
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
00109 ++npts;
00110 }
00111
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 if (sqr_length(pt_ymin-dp0)>sqr_length(dp1-dp0)) dp1 = pt_ymin;
00119 }
00120
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 if (sqr_length(pt_ymax-dp0)>sqr_length(dp1-dp0)) dp1 = pt_ymax;
00128 }
00129
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 if (sqr_length(pt_zmin-dp0)>sqr_length(dp1-dp0)) dp1 = pt_zmin;
00137 }
00138
00139
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 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
00163
00164
00165
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
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
00177 vgl_point_3d<T> org = ray.origin();
00178 vgl_vector_3d<T> dir = ray.direction();
00179 if (!box.contains(org))
00180
00181 return ray.contains(p0)&&ray.contains(p1);
00182
00183
00184
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
00195
00196
00197 template <class T>
00198 bool vgl_intersection(vgl_box_3d<T> const& b, vgl_plane_3d<T> const& plane)
00199 {
00200
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
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;
00225 }
00226
00227
00228
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
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
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
00279
00280 if (vgl_near_zero(a))
00281 {
00282 float y0 = static_cast<float>(-c/b);
00283
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))
00298 return false;
00299 else
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))
00308 {
00309 float x0 = static_cast<float>(-c/a);
00310
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)
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
00335
00336
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
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
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
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
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
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
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
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
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
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
00406 if (inside_xmin && inside_xmax && inside_ymin && inside_ymax)
00407 {
00408 if (a>0)
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
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
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
00434 if (!vgl_intersection<Type>(box, line, pi0, pi1))
00435 return 0;
00436 unsigned int nint = 0;
00437
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
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
00472
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
00492
00493
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
00513
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
00541
00542
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
00559
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
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
00581
00582
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
00591
00592
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
00602
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;
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
00631
00632
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
00642
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
00669
00670
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
00680
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 )
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
00717 intersection_point.set( x, y );
00718 return true;
00719 }
00720
00721
00722
00723
00724
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
00739 vgl_vector_3d<double> t = cross_product(n0, n1);
00740 double mag = t.length();
00741 if (vgl_near_zero(mag))
00742 return false;
00743 t/=mag;
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
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
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
00802
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
00813
00814
00815
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
00831 if (uq1 > 0 && uq1 < L2)
00832 {
00833
00834 if (vq1*vq1 <=tol2*L2) return true;
00835 }
00836 else
00837 {
00838
00839 if ( (q1-p1).sqr_length() <= tol2 || (q1-p2).sqr_length() <= tol2 )
00840 return true;
00841 }
00842
00843
00844 double uq2 = dot_product(q2 - p1,u);
00845 double vq2 = dot_product(q2 - p1,v);
00846
00847
00848 if (uq2 > 0 && uq2 < L2)
00849 {
00850
00851 if (vq2*vq2 <=tol2*L2)
00852 return true;
00853 }
00854 else
00855 {
00856
00857 if ( (q2-p1).sqr_length() <= tol2 || (q2-p2).sqr_length() <= tol2 )
00858 return true;
00859 }
00860
00861
00862
00863
00864
00865
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
00875 if (up1 > 0 && up1 < L2)
00876 {
00877
00878 if (vp1*vp1 <=tol2*L2)
00879 return true;
00880 }
00881 else
00882 {
00883
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
00892 if (up2 > 0 && up2 < L2)
00893 {
00894
00895 if (vp2*vp2 <=tol2*L2)
00896 return true;
00897 }
00898 else
00899 {
00900
00901 if ( (p2-q1).sqr_length() <= tol2 || (p2-q2).sqr_length() <= tol2)
00902 return true;
00903 }
00904
00905
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
00914
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
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
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
00954
00955
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
00968
00969
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
00982
00983
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
00996
00997
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
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
01032
01033
01034
01035
01036 if (!zero&&(sign_a == sign_b))
01037 continue;
01038
01039 if (zero) {
01040 ret.push_back(pa);
01041 continue;
01042 }
01043
01044
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
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_