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_vector_3d.h>
00019 #include <vgl/vgl_box_2d.h>
00020 #include <vgl/vgl_box_3d.h>
00021 #include <vgl/vgl_polygon.h>
00022 #include <vgl/vgl_plane_3d.h>
00023 #include <vgl/vgl_distance.h>
00024 #include <vgl/vgl_tolerance.h>
00025 #include <vgl/vgl_lineseg_test.h>
00026 #include <vcl_vector.h>
00027
00028 static double eps = 1.0e-8;
00029 inline bool vgl_near_zero(double x) { return x < eps && x > -eps; }
00030 inline bool vgl_near_eq(double x, double y) { return vgl_near_zero(x-y); }
00031
00032
00033
00034 template <class T>
00035 vgl_box_2d<T> vgl_intersection(vgl_box_2d<T> const& b1,vgl_box_2d<T> const& b2)
00036 {
00037 T xmin = b1.min_x() > b2.min_x() ? b1.min_x() : b2.min_x();
00038 T ymin = b1.min_y() > b2.min_y() ? b1.min_y() : b2.min_y();
00039 T xmax = b1.max_x() < b2.max_x() ? b1.max_x() : b2.max_x();
00040 T ymax = b1.max_y() < b2.max_y() ? b1.max_y() : b2.max_y();
00041 return vgl_box_2d<T>(xmin,xmax,ymin,ymax);
00042 }
00043
00044
00045
00046
00047 template <class T>
00048 bool vgl_intersection(vgl_box_3d<T> const& box,
00049 vgl_infinite_line_3d<T> const& line_3d,
00050 vgl_point_3d<T>& p0,
00051 vgl_point_3d<T>& p1)
00052 {
00053 vgl_point_3d<T> lpt = line_3d.point();
00054 vgl_vector_3d<T> di = line_3d.direction();
00055 vgl_point_3d<double> dpt(static_cast<double>(lpt.x()),
00056 static_cast<double>(lpt.y()),
00057 static_cast<double>(lpt.z()));
00058 vgl_vector_3d<double> dir(static_cast<double>(di.x()),
00059 static_cast<double>(di.y()),
00060 static_cast<double>(di.z()));
00061 vgl_infinite_line_3d<double> dline_3d(dpt, dir);
00062
00063 double xmin = box.min_x()-eps, xmax = box.max_x()+eps,
00064 ymin = box.min_y()-eps, ymax = box.max_y()+eps,
00065 zmin = box.min_z()-eps, zmax = box.max_z()+eps;
00066 vgl_point_3d<double> minp(xmin, ymin, zmin), maxp(xmax, ymax, zmax);
00067
00068 vgl_vector_3d<double> vxmin(-1.0, 0.0, 0.0), vxmax(1.0, 0.0, 0.0),
00069 vymin(0.0, -1.0, 0.0), vymax(0.0, 1.0, 0.0),
00070 vzmin(0.0, 0.0, -1.0), vzmax(0.0, 0.0, 1.0);
00071 vgl_plane_3d<double> pl_xmin(vxmin, minp),
00072 pl_xmax(vxmax, maxp),
00073 pl_ymin(vymin, minp),
00074 pl_ymax(vymax, maxp),
00075 pl_zmin(vzmin, minp),
00076 pl_zmax(vzmax, maxp);
00077 vgl_point_3d<double> pt_xmin(.0,.0,.0), pt_xmax(.0,.0,.0),
00078 pt_ymin(.0,.0,.0), pt_ymax(.0,.0,.0),
00079 pt_zmin(.0,.0,.0), pt_zmax(.0,.0,.0);
00080 bool xmin_good = vgl_intersection(dline_3d, pl_xmin, pt_xmin);
00081 bool xmax_good = vgl_intersection(dline_3d, pl_xmax, pt_xmax);
00082 bool ymin_good = vgl_intersection(dline_3d, pl_ymin, pt_ymin);
00083 bool ymax_good = vgl_intersection(dline_3d, pl_ymax, pt_ymax);
00084 bool zmin_good = vgl_intersection(dline_3d, pl_zmin, pt_zmin);
00085 bool zmax_good = vgl_intersection(dline_3d, pl_zmax, pt_zmax);
00086
00087
00088
00089
00090 unsigned npts = 0;
00091 vgl_point_3d<double> dp0=pt_xmin, dp1=pt_xmax;
00092
00093
00094 if (xmin_good &&
00095 pt_xmin.y()>=ymin && pt_xmin.y()<=ymax &&
00096 pt_xmin.z()>=zmin && pt_xmin.z()<=zmax)
00097 {
00098
00099 ++npts;
00100 }
00101
00102 if (xmax_good &&
00103 pt_xmax.y()>=ymin && pt_xmax.y()<=ymax &&
00104 pt_xmax.z()>=zmin && pt_xmax.z()<=zmax)
00105 {
00106 if (npts == 0) dp0 = pt_xmax;
00107
00108 ++npts;
00109 }
00110
00111 if (ymin_good &&
00112 pt_ymin.x()>=xmin && pt_ymin.x()<=xmax &&
00113 pt_ymin.z()>=zmin && pt_ymin.z()<=zmax)
00114 {
00115 if (npts == 0) { dp0 = pt_ymin; ++npts; }
00116 else if (npts == 1) { dp1 = pt_ymin; ++npts; }
00117 else if (sqr_length(pt_ymin-dp0)>sqr_length(dp1-dp0)) dp1 = pt_ymin;
00118 }
00119
00120 if (ymax_good &&
00121 pt_ymax.x()>=xmin && pt_ymax.x()<=xmax &&
00122 pt_ymax.z()>=zmin && pt_ymax.z()<=zmax)
00123 {
00124 if (npts == 0) { dp0 = pt_ymax; ++npts; }
00125 else if (npts == 1) { dp1 = pt_ymax; ++npts; }
00126 else if (sqr_length(pt_ymax-dp0)>sqr_length(dp1-dp0)) dp1 = pt_ymax;
00127 }
00128
00129 if (zmin_good &&
00130 pt_zmin.x()>=xmin && pt_zmin.x()<=xmax &&
00131 pt_zmin.y()>=ymin && pt_zmin.y()<=ymax)
00132 {
00133 if (npts == 0) { dp0 = pt_zmin; ++npts; }
00134 else if (npts == 1) { dp1 = pt_zmin; ++npts; }
00135 else if (sqr_length(pt_zmin-dp0)>sqr_length(dp1-dp0)) dp1 = pt_zmin;
00136 }
00137
00138
00139 if (zmax_good &&
00140 pt_zmax.x()>=xmin && pt_zmax.x()<=xmax &&
00141 pt_zmax.y()>=ymin && pt_zmax.y()<=ymax)
00142 {
00143 if (npts == 0) { dp0 = pt_zmax; ++npts; }
00144 else if (npts == 1) { dp1 = pt_zmax; ++npts; }
00145 else if (sqr_length(pt_zmax-dp0)>sqr_length(dp1-dp0)) dp1 = pt_zmax;
00146 }
00147
00148 if (npts==2) {
00149 p0.set(static_cast<T>(dp0.x()),
00150 static_cast<T>(dp0.y()),
00151 static_cast<T>(dp0.z()));
00152 p1.set(static_cast<T>(dp1.x()),
00153 static_cast<T>(dp1.y()),
00154 static_cast<T>(dp1.z()));
00155 return true;
00156 }
00157 else
00158 return false;
00159 }
00160
00161
00162
00163
00164 template <class T>
00165 bool vgl_intersection(vgl_box_3d<T> const& b, vgl_plane_3d<T> const& plane)
00166 {
00167
00168 vcl_vector<vgl_point_3d<T> > corners;
00169 corners.push_back(b.min_point());
00170 corners.push_back(vgl_point_3d<T> (b.min_x()+b.width(), b.min_y(), b.min_z()));
00171 corners.push_back(vgl_point_3d<T> (b.min_x()+b.width(), b.min_y()+b.height(), b.min_z()));
00172 corners.push_back(vgl_point_3d<T> (b.min_x(), b.min_y()+b.height(), b.min_z()));
00173 corners.push_back(vgl_point_3d<T> (b.min_x(), b.min_y(), b.max_z()));
00174 corners.push_back(vgl_point_3d<T> (b.min_x()+b.width(), b.min_y(), b.max_z()));
00175 corners.push_back(b.max_point());
00176 corners.push_back(vgl_point_3d<T> (b.min_x(), b.min_y()+b.height(), b.max_z()));
00177
00178
00179 int pos=0, neg=0;
00180 for (unsigned c=0; c<corners.size(); c++) {
00181 vgl_point_3d<T> corner=corners[c];
00182 double d=(plane.a()*corner.x());
00183 d+=(plane.b()*corner.y());
00184 d+=(plane.c()*corner.z());
00185 d+=plane.d();
00186 if (d > 0)
00187 pos++;
00188 else if (d<0)
00189 neg++;
00190 }
00191 return neg!=8 && pos!=8;
00192 }
00193
00194
00195
00196 template <class T>
00197 vgl_box_3d<T> vgl_intersection(vgl_box_3d<T> const& b1,vgl_box_3d<T> const& b2)
00198 {
00199 T xmin = b1.min_x() > b2.min_x() ? b1.min_x() : b2.min_x();
00200 T ymin = b1.min_y() > b2.min_y() ? b1.min_y() : b2.min_y();
00201 T zmin = b1.min_z() > b2.min_z() ? b1.min_z() : b2.min_z();
00202 T xmax = b1.max_x() < b2.max_x() ? b1.max_x() : b2.max_x();
00203 T ymax = b1.max_y() < b2.max_y() ? b1.max_y() : b2.max_y();
00204 T zmax = b1.max_z() < b2.max_z() ? b1.max_z() : b2.max_z();
00205 return vgl_box_3d<T>(xmin,ymin,zmin,xmax,ymax,zmax);
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 template <class Type>
00236 bool vgl_intersection(const vgl_box_2d<Type>& box,
00237 const vgl_line_2d<Type>& line,
00238 vgl_point_2d<Type>& p0,
00239 vgl_point_2d<Type>& p1)
00240 {
00241 double a = line.a(), b = line.b(), c = line.c();
00242 double xmin=box.min_x(), xmax=box.max_x();
00243 double ymin=box.min_y(), ymax=box.max_y();
00244
00245
00246
00247 if (vgl_near_zero(a))
00248 {
00249 float y0 = static_cast<float>(-c/b);
00250
00251 if (vgl_near_eq(ymin,y0))
00252 {
00253 p0.set(static_cast<Type>(xmin), static_cast<Type>(ymin));
00254 p1.set(static_cast<Type>(xmax), static_cast<Type>(ymin));
00255 return true;
00256 }
00257 if (vgl_near_eq(ymax,y0))
00258 {
00259 p0.set(static_cast<Type>(xmin), static_cast<Type>(ymax));
00260 p1.set(static_cast<Type>(xmax), static_cast<Type>(ymax));
00261 return true;
00262 }
00263
00264 if ((ymin > y0) || (y0 > ymax))
00265 return false;
00266 else
00267 {
00268 p0.set(static_cast<Type>(xmin), static_cast<Type>(y0));
00269 p1.set(static_cast<Type>(xmax), static_cast<Type>(y0));
00270 return true;
00271 }
00272 }
00273
00274 if (vgl_near_zero(b))
00275 {
00276 float x0 = static_cast<float>(-c/a);
00277
00278 if (vgl_near_eq(xmin,x0))
00279 {
00280 p0.set(static_cast<Type>(xmin), static_cast<Type>(ymin));
00281 p1.set(static_cast<Type>(xmin), static_cast<Type>(ymax));
00282 return true;
00283 }
00284 if (vgl_near_eq(xmax,x0))
00285 {
00286 p0.set(static_cast<Type>(xmax), static_cast<Type>(ymin));
00287 p1.set(static_cast<Type>(xmax), static_cast<Type>(ymax));
00288 return true;
00289 }
00290
00291 if (xmin <= x0 && x0 <= xmax)
00292 {
00293 p0.set(static_cast<Type>(x0), static_cast<Type>(ymin));
00294 p1.set(static_cast<Type>(x0), static_cast<Type>(ymax));
00295 return true;
00296 }
00297 else
00298 return false;
00299 }
00300
00301
00302
00303
00304 float y_xmin_int = static_cast<float>(-(c + a*xmin)/b);
00305 bool inside_xmin = (y_xmin_int >= ymin) && (y_xmin_int <= ymax);
00306
00307
00308 float y_xmax_int = static_cast<float>(-(c + a*xmax)/b);
00309 bool inside_xmax = (y_xmax_int >= ymin) && (y_xmax_int <= ymax);
00310
00311
00312 float x_ymin_int = static_cast<float>(-(c + b*ymin)/a);
00313 bool inside_ymin = (x_ymin_int >= xmin) && (x_ymin_int <= xmax);
00314
00315
00316 float x_ymax_int = static_cast<float>(-(c + b*ymax)/a);
00317 bool inside_ymax = (x_ymax_int >= xmin) && (x_ymax_int <= xmax);
00318
00319
00320 if (inside_xmin && inside_xmax &&
00321 !(vgl_near_eq(y_xmin_int,ymin) && vgl_near_eq(y_xmax_int,ymax)))
00322 {
00323 p0.set(static_cast<Type>(xmin), static_cast<Type>(y_xmin_int));
00324 p1.set(static_cast<Type>(xmax), static_cast<Type>(y_xmax_int));
00325 return true;
00326 }
00327
00328
00329 if (inside_ymin && inside_ymax &&
00330 !(vgl_near_eq(x_ymin_int,xmin) && vgl_near_eq(x_ymax_int,xmax)))
00331 {
00332 p0.set(static_cast<Type>(x_ymin_int), static_cast<Type>(ymin));
00333 p1.set(static_cast<Type>(x_ymax_int), static_cast<Type>(ymax));
00334 return true;
00335 }
00336
00337
00338 if (inside_xmin && inside_ymin &&
00339 !(inside_xmax && inside_ymax))
00340 {
00341 p0.set(static_cast<Type>(xmin), static_cast<Type>(y_xmin_int));
00342 p1.set(static_cast<Type>(x_ymin_int), static_cast<Type>(ymin));
00343 return true;
00344 }
00345
00346
00347 if (inside_xmin && inside_ymax &&
00348 !(inside_xmax && inside_ymin))
00349 {
00350 p0.set(static_cast<Type>(xmin), static_cast<Type>(y_xmin_int));
00351 p1.set(static_cast<Type>(x_ymax_int), static_cast<Type>(ymax));
00352 return true;
00353 }
00354
00355
00356 if (inside_ymin && inside_xmax &&
00357 !(inside_xmin && inside_ymax))
00358 {
00359 p0.set(static_cast<Type>(x_ymin_int), static_cast<Type>(ymin));
00360 p1.set(static_cast<Type>(xmax), static_cast<Type>(y_xmax_int));
00361 return true;
00362 }
00363
00364
00365 if (inside_ymax && inside_xmax &&
00366 !(inside_xmin && inside_ymin))
00367 {
00368 p0.set(static_cast<Type>(x_ymax_int), static_cast<Type>(ymax));
00369 p1.set(static_cast<Type>(xmax), static_cast<Type>(y_xmax_int));
00370 return true;
00371 }
00372
00373 if (inside_xmin && inside_xmax && inside_ymin && inside_ymax)
00374 {
00375 if (a>0)
00376 {
00377 p0.set(static_cast<Type>(xmin), static_cast<Type>(ymin));
00378 p1.set(static_cast<Type>(xmax), static_cast<Type>(ymax));
00379 return true;
00380 }
00381 else
00382 {
00383 p0.set(static_cast<Type>(xmin), static_cast<Type>(ymax));
00384 p1.set(static_cast<Type>(xmax), static_cast<Type>(ymin));
00385 return true;
00386 }
00387 }
00388 return false;
00389 }
00390
00391
00392 template <class Type>
00393 unsigned vgl_intersection(const vgl_box_2d<Type>& box,
00394 const vgl_line_segment_2d<Type>& line_seg,
00395 vgl_point_2d<Type>& p0,
00396 vgl_point_2d<Type>& p1)
00397 {
00398 vgl_line_2d<Type> line(line_seg.a(), line_seg.b(), line_seg.c());
00399 vgl_point_2d<Type> pi0, pi1;
00400
00401 if (!vgl_intersection<Type>(box, line, pi0, pi1))
00402 return 0;
00403 unsigned nint = 0;
00404
00405 if (vgl_lineseg_test_point<Type>(pi0, line_seg)) {
00406 p0 = pi0;
00407 nint++;
00408 }
00409 if (vgl_lineseg_test_point<Type>(pi1, line_seg)) {
00410 p1 = pi1;
00411 nint++;
00412 }
00413 return nint;
00414 }
00415
00416
00417 template <class T>
00418 vgl_point_3d<T> vgl_intersection(vgl_line_3d_2_points<T> const& l1,
00419 vgl_line_3d_2_points<T> const& l2)
00420 {
00421 assert(concurrent(l1,l2));
00422 T a0=l1.point1().x(),a1=l1.point2().x(),a2=l2.point1().x(),a3=l2.point2().x(),
00423 b0=l1.point1().y(),b1=l1.point2().y(),b2=l2.point1().y(),b3=l2.point2().y(),
00424 c0=l1.point1().z(),c1=l1.point2().z(),c2=l2.point1().z(),c3=l2.point2().z();
00425 T t1 = (b3-b2)*(a1-a0)-(a3-a2)*(b1-b0), t2 = (b0-b2)*(a1-a0)-(a0-a2)*(b1-b0);
00426 if (vcl_abs(t1) < 0.000001)
00427 {
00428 t1 = (c3-c2)*(a1-a0)-(a3-a2)*(c1-c0), t2 = (c0-c2)*(a1-a0)-(a0-a2)*(c1-c0);
00429 if (vcl_abs(t1) < 0.000001)
00430 t1 = (c3-c2)*(b1-b0)-(b3-b2)*(c1-c0), t2 = (c0-c2)*(b1-b0)-(b0-b2)*(c1-c0);
00431 }
00432
00433 return vgl_point_3d<T>(((t1-t2)*a2+t2*a3)/t1,
00434 ((t1-t2)*b2+t2*b3)/t1,
00435 ((t1-t2)*c2+t2*c3)/t1);
00436 }
00437
00438
00439
00440 template <class T>
00441 bool vgl_intersection(vgl_line_segment_3d<T> const& l1,
00442 vgl_line_segment_3d<T> const& l2,
00443 vgl_point_3d<T>& i_pnt)
00444 {
00445 vgl_line_3d_2_points<T> l21(l1.point1(),l1.point2());
00446 vgl_line_3d_2_points<T> l22(l2.point1(),l2.point2());
00447 if (!concurrent(l21, l22))
00448 return false;
00449 i_pnt = vgl_intersection(l21, l22);
00450
00451 double l1_len = length(l1.point1() - l1.point2());
00452 double l1_idist = length(l1.point1() - i_pnt) + length(l1.point2() - i_pnt);
00453 double l2_len = length(l2.point1() - l2.point2());
00454 double l2_idist = length(l2.point1() - i_pnt) + length(l2.point2() - i_pnt);
00455 return vgl_near_zero(l1_len - l1_idist) && vgl_near_zero(l2_len - l2_idist);
00456 }
00457
00458
00459
00460
00461 template <class T>
00462 bool vgl_intersection(vgl_line_3d_2_points<T> const& l1,
00463 vgl_line_segment_3d<T> const& l2,
00464 vgl_point_3d<T>& i_pnt)
00465 {
00466 vgl_line_3d_2_points<T> l22(l2.point1(),l2.point2());
00467 if (!concurrent(l1, l22))
00468 return false;
00469 i_pnt = vgl_intersection(l1, l22);
00470
00471 double l1_len = length(l1.point1() - l1.point2());
00472 double l1_idist = length(l1.point1() - i_pnt) + length(l1.point2() - i_pnt);
00473 double l2_len = length(l2.point1() - l2.point2());
00474 double l2_idist = length(l2.point1() - i_pnt) + length(l2.point2() - i_pnt);
00475
00476 return vgl_near_zero(l1_len - l1_idist) && vgl_near_zero(l2_len - l2_idist);
00477 }
00478
00479
00480
00481 template <class T>
00482 bool vgl_intersection(vgl_infinite_line_3d<T> const& l1,
00483 vgl_infinite_line_3d<T> const& l2,
00484 vgl_point_3d<T>& i_pnt)
00485 {
00486 vgl_line_3d_2_points<T> l21(l1.point(),l1.point_t(T(1)));
00487 vgl_line_3d_2_points<T> l22(l2.point(),l2.point_t(T(1)));
00488 if (!concurrent(l21, l22))
00489 return false;
00490 i_pnt = vgl_intersection(l21, l22);
00491 return l1.contains(i_pnt) && l2.contains(i_pnt);
00492 }
00493
00494
00495
00496
00497 template <class T>
00498 vgl_point_3d<T> vgl_intersection(vgl_line_3d_2_points<T> const& line,
00499 vgl_plane_3d<T> const& plane)
00500 {
00501 vgl_vector_3d<T> dir = line.direction();
00502
00503 vgl_point_3d<T> pt;
00504
00505 double denom = plane.a()*dir.x() +
00506 plane.b()*dir.y() +
00507 plane.c()*dir.z();
00508
00509 if (denom == 0)
00510 {
00511 const T inf = vcl_numeric_limits<T>::infinity();
00512
00513
00514 if (vgl_distance(line.point1(), plane)==0.0)
00515 pt.set(inf,inf,inf);
00516 else
00517 pt.set(inf,0,0);
00518 }
00519 else
00520 {
00521
00522 double numer = - plane.a()*line.point1().x()
00523 - plane.b()*line.point1().y()
00524 - plane.c()*line.point1().z()
00525 - plane.d();
00526
00527 dir *= numer/denom;
00528 pt = line.point1() + dir;
00529 }
00530
00531 return pt;
00532 }
00533
00534
00535
00536
00537 template <class T>
00538 bool vgl_intersection(vgl_line_segment_3d<T> const& line,
00539 vgl_plane_3d<T> const& plane,
00540 vgl_point_3d<T> & i_pt)
00541 {
00542 vgl_vector_3d<T> dir = line.direction();
00543
00544
00545
00546
00547 const double tol = vcl_numeric_limits<T>::epsilon() * 10e3;
00548
00549 double denom = plane.a()*dir.x() +
00550 plane.b()*dir.y() +
00551 plane.c()*dir.z();
00552
00553 if (vcl_abs(denom) < tol)
00554 {
00555
00556
00557 if (vgl_distance(line.point1(), plane)!=0.0)
00558 return false;
00559
00560 const T inf = vcl_numeric_limits<T>::infinity();
00561 i_pt.set(inf,inf,inf);
00562 return true;
00563 }
00564
00565 double numer = - plane.a()*line.point1().x()
00566 - plane.b()*line.point1().y()
00567 - plane.c()*line.point1().z()
00568 - plane.d();
00569
00570 double t = numer/denom;
00571 if (t < 0 || t > 1.0) return false;
00572
00573 i_pt = line.point1() + t * dir;
00574 return true;
00575 }
00576
00577 template <class T>
00578 bool vgl_intersection(vgl_infinite_line_3d<T> const& line,
00579 vgl_plane_3d<T> const& plane,
00580 vgl_point_3d<T> & i_pt)
00581 {
00582 vgl_vector_3d<T> dir = line.direction();
00583 vgl_point_3d<T> pt = line.point();
00584
00585
00586
00587 const double tol = vcl_numeric_limits<T>::epsilon() * 10e3;
00588
00589 double denom = plane.a()*dir.x() +
00590 plane.b()*dir.y() +
00591 plane.c()*dir.z();
00592
00593 if (vcl_abs(denom) < tol)
00594 {
00595
00596
00597 if (vgl_distance(pt, plane)!=0.0)
00598 return false;
00599
00600 const T inf = vcl_numeric_limits<T>::infinity();
00601 i_pt.set(inf,inf,inf);
00602 return true;
00603 }
00604
00605 double numer = - plane.a()*pt.x()
00606 - plane.b()*pt.y()
00607 - plane.c()*pt.z()
00608 - plane.d();
00609
00610 double t = numer/denom;
00611 i_pt = pt + t * dir;
00612 return true;
00613 }
00614
00615 template <class T>
00616 bool vgl_intersection( const vgl_line_2d<T> &line0,
00617 const vgl_line_2d<T> &line1,
00618 vgl_point_2d<T> &intersection_point )
00619 {
00620 T a0, b0, c0, a1, b1, c1;
00621 a0 = line0.a(); b0 = line0.b(); c0 = line0.c();
00622 a1 = line1.a(); b1 = line1.b(); c1 = line1.c();
00623
00624 T delta, delta_x, delta_y, x, y;
00625 delta = a0*b1 - a1*b0;
00626 if ( vcl_abs(delta) <= vgl_tolerance<T>::position )
00627 return false;
00628 delta_x = -c0*b1 + b0*c1; delta_y = -a0*c1 + a1*c0;
00629 x = delta_x / delta; y = delta_y / delta;
00630
00631
00632 intersection_point.set( x, y );
00633 return true;
00634 }
00635
00636
00637
00638
00639
00640 template <class T>
00641 bool vgl_intersection(vgl_plane_3d<T> const& plane0,
00642 vgl_plane_3d<T> const& plane1,
00643 vgl_infinite_line_3d<T>& line)
00644 {
00645 double n0x = static_cast<double>(plane0.a());
00646 double n0y = static_cast<double>(plane0.b());
00647 double n0z = static_cast<double>(plane0.c());
00648 double n1x = static_cast<double>(plane1.a());
00649 double n1y = static_cast<double>(plane1.b());
00650 double n1z = static_cast<double>(plane1.c());
00651 vgl_vector_3d<double> n0(n0x, n0y, n0z);
00652 vgl_vector_3d<double> n1(n1x, n1y, n1z);
00653
00654 vgl_vector_3d<double> t = cross_product(n0, n1);
00655 double mag = t.length();
00656 if (vgl_near_zero(mag))
00657 return false;
00658 t/=mag;
00659 double tx = vcl_fabs(static_cast<double>(t.x_));
00660 double ty = vcl_fabs(static_cast<double>(t.y_));
00661 double tz = vcl_fabs(static_cast<double>(t.z_));
00662
00663 char component = 'x';
00664 if (ty>tx&&ty>tz)
00665 component = 'y';
00666 if (tz>tx&&tz>ty)
00667 component = 'z';
00668 double d0 = static_cast<double>(plane0.d());
00669 double d1 = static_cast<double>(plane1.d());
00670 vgl_point_3d<double> p0d;
00671 switch (component)
00672 {
00673
00674 case 'x':
00675 {
00676 double det = n0y*n1z-n1y*n0z;
00677 if (vgl_near_zero(det))
00678 return false;
00679 double neuy = d1*n0z - d0*n1z;
00680 double neuz = d0*n1y - d1*n0y;
00681 p0d.set(0.0, neuy/det, neuz/det);
00682 break;
00683 }
00684 case 'y':
00685 {
00686 double det = n0x*n1z-n1x*n0z;
00687 if (vgl_near_zero(det))
00688 return false;
00689 double neux = d1*n0z - d0*n1z;
00690 double neuz = d0*n1x - d1*n0x;
00691 p0d.set(neux/det, 0.0, neuz/det);
00692 break;
00693 }
00694 case 'z':
00695 {
00696 double det = n0x*n1y-n1x*n0y;
00697 if (vgl_near_zero(det))
00698 return false;
00699 double neux = d1*n0y - d0*n1y;
00700 double neuy = d0*n1x - d1*n0x;
00701 p0d.set(neux/det, neuy/det, 0.0);
00702 break;
00703 }
00704 default:
00705 break;
00706 }
00707 vgl_point_3d<T> p0(static_cast<T>(p0d.x()),
00708 static_cast<T>(p0d.y()),
00709 static_cast<T>(p0d.z()));
00710 vgl_vector_3d<T> tt(static_cast<T>(t.x()),
00711 static_cast<T>(t.y()),
00712 static_cast<T>(t.z()));
00713 line = vgl_infinite_line_3d<T>(p0, tt);
00714 return true;
00715 }
00716
00717
00718
00719 template <class T>
00720 vgl_point_3d<T> vgl_intersection(const vgl_plane_3d<T>& p1,
00721 const vgl_plane_3d<T>& p2,
00722 const vgl_plane_3d<T>& p3)
00723 {
00724 vgl_point_3d<T> p(p1, p2, p3);
00725 return p;
00726 }
00727
00728
00729
00730
00731
00732 template <class T>
00733 bool vgl_intersection(vgl_point_2d<T> const& p1,
00734 vgl_point_2d<T> const& p2,
00735 vgl_point_2d<T> const& q1,
00736 vgl_point_2d<T> const& q2,
00737 double tol)
00738 {
00739 vgl_vector_2d<T> u = p2 - p1;
00740 vgl_vector_2d<T> v(-u.y(),u.x());
00741 double uq1 = dot_product(q1 - p1,u);
00742 double vq1 = dot_product(q1 - p1,v);
00743 double tol2 = tol*tol;
00744 double L2 = sqr_length(u);
00745
00746
00747 if (uq1 > 0 && uq1 < L2)
00748 {
00749
00750 if (vq1*vq1 <=tol2*L2) return true;
00751 }
00752 else
00753 {
00754
00755 if ( (q1-p1).sqr_length() <= tol2 || (q1-p2).sqr_length() <= tol2 )
00756 return true;
00757 }
00758
00759
00760 double uq2 = dot_product(q2 - p1,u);
00761 double vq2 = dot_product(q2 - p1,v);
00762
00763
00764 if (uq2 > 0 && uq2 < L2)
00765 {
00766
00767 if (vq2*vq2 <=tol2*L2)
00768 return true;
00769 }
00770 else
00771 {
00772
00773 if ( (q2-p1).sqr_length() <= tol2 || (q2-p2).sqr_length() <= tol2 )
00774 return true;
00775 }
00776
00777
00778
00779
00780
00781
00782
00783 u = q2 - q1;
00784 v.set(-u.y(),u.x());
00785 L2 = sqr_length(u);
00786
00787 double up1 = dot_product(p1 - q1,u);
00788 double vp1 = dot_product(p1 - q1,v);
00789
00790
00791 if (up1 > 0 && up1 < L2)
00792 {
00793
00794 if (vp1*vp1 <=tol2*L2)
00795 return true;
00796 }
00797 else
00798 {
00799
00800 if ( (p1-q1).sqr_length() <= tol2 || (p1-q2).sqr_length() <= tol2 )
00801 return true;
00802 }
00803
00804 double up2 = dot_product(p2 - q1,u);
00805 double vp2 = dot_product(p2 - q1,v);
00806
00807
00808 if (up2 > 0 && up2 < L2)
00809 {
00810
00811 if (vp2*vp2 <=tol2*L2)
00812 return true;
00813 }
00814 else
00815 {
00816
00817 if ( (p2-q1).sqr_length() <= tol2 || (p2-q2).sqr_length() <= tol2)
00818 return true;
00819 }
00820
00821
00822 return vq1*vq2 < 0 && vp1*vp2 < 0;
00823 }
00824
00825 template <class T>
00826 bool vgl_intersection(const vgl_box_2d<T>& b,
00827 const vgl_polygon<T>& poly)
00828 {
00829
00830
00831 unsigned ns = poly.num_sheets();
00832 bool hit = false;
00833 for ( unsigned s = 0; s<ns&&!hit; ++s) {
00834 unsigned n = poly[s].size();
00835 for (unsigned i = 0; i<n&&!hit; ++i) {
00836 vgl_point_2d<T> p = poly[s][i];
00837 hit = b.contains(p.x(), p.y());
00838 }
00839 }
00840 if (hit) return true;
00841
00842 T minx = b.min_x(), maxx = b.max_x();
00843 T miny = b.min_y(), maxy = b.max_y();
00844 hit = poly.contains(minx, miny) || poly.contains(maxx, maxy) ||
00845 poly.contains(minx, maxy) || poly.contains(maxx, miny);
00846 if (hit) return true;
00847
00848 for (unsigned s = 0; s<ns&&!hit; ++s)
00849 {
00850 unsigned n = poly[s].size();
00851 vgl_point_2d<T> ia, ib;
00852 vgl_point_2d<T> last = poly[s][0];
00853 for (unsigned i = 1; i<n&&!hit; ++i)
00854 {
00855 vgl_point_2d<T> p = poly[s][i];
00856 vgl_line_segment_2d<T> l(last, p);
00857 hit = vgl_intersection<T>(b, l, ia, ib)>0;
00858 last = p;
00859 }
00860 if (!hit) {
00861 vgl_point_2d<T> start = poly[s][0];
00862 vgl_line_segment_2d<T> ll(last, start);
00863 hit = vgl_intersection<T>(b,ll, ia, ib)>0;
00864 }
00865 }
00866 return hit;
00867 }
00868
00869
00870
00871
00872 template <class T>
00873 vcl_vector<vgl_point_2d<T> > vgl_intersection(vgl_box_2d<T> const& b, vcl_vector<vgl_point_2d<T> > const& p)
00874 {
00875 vcl_vector<vgl_point_2d<T> > r;
00876 typename vcl_vector<vgl_point_2d<T> >::const_iterator i;
00877 for (i = p.begin(); i != p.end(); ++i)
00878 if (vgl_intersection(b, *i))
00879 r.push_back(*i);
00880 return r;
00881 }
00882
00883
00884
00885
00886 template <class T>
00887 vcl_vector<vgl_point_2d<T> > vgl_intersection(vcl_vector<vgl_point_2d<T> > const& p, vgl_box_2d<T> const& b)
00888 {
00889 vcl_vector<vgl_point_2d<T> > r;
00890 typename vcl_vector<vgl_point_2d<T> >::const_iterator i;
00891 for (i = p.begin(); i != p.end(); ++i)
00892 if (vgl_intersection(b, *i))
00893 r.push_back(*i);
00894 return r;
00895 }
00896
00897
00898
00899
00900 template <class T>
00901 vcl_vector<vgl_point_3d<T> > vgl_intersection(vgl_box_3d<T> const& b, vcl_vector<vgl_point_3d<T> > const& p)
00902 {
00903 vcl_vector<vgl_point_3d<T> > r;
00904 typename vcl_vector<vgl_point_3d<T> >::const_iterator i;
00905 for (i = p.begin(); i != p.end(); ++i)
00906 if (vgl_intersection(b, *i))
00907 r.push_back(*i);
00908 return r;
00909 }
00910
00911
00912
00913
00914 template <class T>
00915 vcl_vector<vgl_point_3d<T> > vgl_intersection(vcl_vector<vgl_point_3d<T> > const& p, vgl_box_3d<T> const& b)
00916 {
00917 vcl_vector<vgl_point_3d<T> > r;
00918 typename vcl_vector<vgl_point_3d<T> >::const_iterator i;
00919 for (i = p.begin(); i != p.end(); ++i)
00920 if (vgl_intersection(b, *i))
00921 r.push_back(*i);
00922 return r;
00923 }
00924
00925
00926 #undef VGL_INTERSECTION_BOX_INSTANTIATE
00927 #define VGL_INTERSECTION_BOX_INSTANTIATE(T) \
00928 template vgl_box_2d<T > vgl_intersection(vgl_box_2d<T > const&,vgl_box_2d<T > const&); \
00929 template vgl_box_3d<T > vgl_intersection(vgl_box_3d<T > const&,vgl_box_3d<T > const&); \
00930 template vcl_vector<vgl_point_2d<T > > vgl_intersection(vgl_box_2d<T > const&,vcl_vector<vgl_point_2d<T > > const&); \
00931 template vcl_vector<vgl_point_2d<T > > vgl_intersection(vcl_vector<vgl_point_2d<T > > const&,vgl_box_2d<T > const&); \
00932 template vcl_vector<vgl_point_3d<T > > vgl_intersection(vgl_box_3d<T > const&,vcl_vector<vgl_point_3d<T > > const&); \
00933 template vcl_vector<vgl_point_3d<T > > vgl_intersection(vcl_vector<vgl_point_3d<T > > const&,vgl_box_3d<T > const&); \
00934 template bool vgl_intersection(vgl_box_2d<T > const&,vgl_line_2d<T > const&,vgl_point_2d<T >&,vgl_point_2d<T >&); \
00935 template bool vgl_intersection(vgl_box_3d<T > const&,vgl_plane_3d<T > const&); \
00936 template bool vgl_intersection(vgl_box_3d<T > const&,vgl_infinite_line_3d<T > const&,vgl_point_3d<T >&,vgl_point_3d<T >&)
00937
00938 #undef VGL_INTERSECTION_INSTANTIATE
00939 #define VGL_INTERSECTION_INSTANTIATE(T) \
00940 template vgl_point_3d<T > vgl_intersection(vgl_line_3d_2_points<T > const&,vgl_line_3d_2_points<T > const&); \
00941 template bool vgl_intersection(vgl_line_segment_3d<T > const&,vgl_line_segment_3d<T > const&,vgl_point_3d<T >&); \
00942 template bool vgl_intersection(vgl_line_3d_2_points<T > const&,vgl_line_segment_3d<T > const&,vgl_point_3d<T >&); \
00943 template vgl_point_3d<T > vgl_intersection(vgl_line_3d_2_points<T > const&,vgl_plane_3d<T > const&); \
00944 template bool vgl_intersection(vgl_line_segment_3d<T > const&,vgl_plane_3d<T > const&,vgl_point_3d<T >&); \
00945 template bool vgl_intersection(vgl_infinite_line_3d<T > const&,vgl_plane_3d<T > const&,vgl_point_3d<T >&); \
00946 template bool vgl_intersection(vgl_infinite_line_3d<T > const&,vgl_infinite_line_3d<T > const&,vgl_point_3d<T >&); \
00947 template vgl_point_3d<T > vgl_intersection(vgl_plane_3d<T > const&,vgl_plane_3d<T > const&,vgl_plane_3d<T > const&); \
00948 template unsigned vgl_intersection(vgl_box_2d<T > const&,vgl_line_segment_2d<T > const&,vgl_point_2d<T >&,vgl_point_2d<T >&); \
00949 template bool vgl_intersection(vgl_line_2d<T > const&,vgl_line_2d<T > const&,vgl_point_2d<T >&); \
00950 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); \
00951 template bool vgl_intersection(vgl_box_2d<T > const&,vgl_polygon<T > const&); \
00952 template bool vgl_intersection(vgl_plane_3d<T > const&,vgl_plane_3d<T > const&,vgl_line_segment_3d<T > &); \
00953 template bool vgl_intersection(vgl_plane_3d<T > const&,vgl_plane_3d<T > const&,vgl_infinite_line_3d<T >&); \
00954 VGL_INTERSECTION_BOX_INSTANTIATE(T)
00955
00956 #endif // vgl_intersection_txx_