vgl_intersection.hxx
Go to the documentation of this file.
1 // This is core/vgl/vgl_intersection.hxx
2 #ifndef vgl_intersection_hxx_
3 #define vgl_intersection_hxx_
4 //:
5 // \file
6 // \author Gamze Tunali
7 
8 #include <limits>
9 #include <cmath>
10 #include <vector>
11 #include "vgl_intersection.h"
12 
13 #ifdef _MSC_VER
14 # include <vcl_msvc_warnings.h>
15 #endif
16 #include <cassert>
17 #include <vgl/vgl_point_2d.h>
18 #include <vgl/vgl_line_2d.h>
22 #include <vgl/vgl_ray_3d.h>
23 #include <vgl/vgl_vector_3d.h>
24 #include <vgl/vgl_box_2d.h>
25 #include <vgl/vgl_box_3d.h>
26 #include <vgl/vgl_polygon.h>
27 #include <vgl/vgl_plane_3d.h>
28 #include <vgl/vgl_distance.h>
29 #include <vgl/vgl_tolerance.h>
30 #include <vgl/vgl_closest_point.h>
31 #include <vgl/vgl_lineseg_test.hxx>
32 
33 static double eps = 1.0e-8; // tolerance for intersections
34 inline bool vgl_near_zero(double x) { return x < eps && x > -eps; }
35 inline bool vgl_near_eq(double x, double y) { return vgl_near_zero(x-y); }
36 
37 //: Return the intersection of two boxes (which is itself is a box, possibly the empty box)
38 // \relatesalso vgl_box_2d
39 template <class T>
41 {
42  T xmin = b1.min_x() > b2.min_x() ? b1.min_x() : b2.min_x();
43  T ymin = b1.min_y() > b2.min_y() ? b1.min_y() : b2.min_y();
44  T xmax = b1.max_x() < b2.max_x() ? b1.max_x() : b2.max_x();
45  T ymax = b1.max_y() < b2.max_y() ? b1.max_y() : b2.max_y();
46  return vgl_box_2d<T>(xmin,xmax,ymin,ymax);
47 }
48 
49 //: Return true if line intersects box. If so, compute intersection points.
50 // \relatesalso vgl_box_3d
51 // \relatesalso vgl_infinite_line_3d
52 template <class T>
54  vgl_infinite_line_3d<T> const& line_3d,
55  vgl_point_3d<T>& p0,
56  vgl_point_3d<T>& p1)
57 {
58  vgl_point_3d<T> lpt = line_3d.point();
59  vgl_vector_3d<T> di = line_3d.direction();
60  vgl_point_3d<double> dpt(static_cast<double>(lpt.x()),
61  static_cast<double>(lpt.y()),
62  static_cast<double>(lpt.z()));
63  vgl_vector_3d<double> dir(static_cast<double>(di.x()),
64  static_cast<double>(di.y()),
65  static_cast<double>(di.z()));
66  vgl_infinite_line_3d<double> dline_3d(dpt, dir);
67  // expand box by epsilon tolerance
68  double xmin = box.min_x(), xmax = box.max_x(),
69  ymin = box.min_y(), ymax = box.max_y(),
70  zmin = box.min_z(), zmax = box.max_z();
71  vgl_point_3d<double> minp(xmin, ymin, zmin), maxp(xmax, ymax, zmax);
72  // find intersection point of the line with each of the six box planes
73  vgl_vector_3d<double> vxmin(-1.0, 0.0, 0.0), vxmax(1.0, 0.0, 0.0),
74  vymin(0.0, -1.0, 0.0), vymax(0.0, 1.0, 0.0),
75  vzmin(0.0, 0.0, -1.0), vzmax(0.0, 0.0, 1.0);
76  vgl_plane_3d<double> pl_xmin(vxmin, minp),
77  pl_xmax(vxmax, maxp),
78  pl_ymin(vymin, minp),
79  pl_ymax(vymax, maxp),
80  pl_zmin(vzmin, minp),
81  pl_zmax(vzmax, maxp);
82  vgl_point_3d<double> pt_xmin(.0,.0,.0), pt_xmax(.0,.0,.0), // dummy initializ.
83  pt_ymin(.0,.0,.0), pt_ymax(.0,.0,.0), // to avoid
84  pt_zmin(.0,.0,.0), pt_zmax(.0,.0,.0); // compiler warning
85  bool xmin_good = vgl_intersection(dline_3d, pl_xmin, pt_xmin);
86  bool xmax_good = vgl_intersection(dline_3d, pl_xmax, pt_xmax);
87  bool ymin_good = vgl_intersection(dline_3d, pl_ymin, pt_ymin);
88  bool ymax_good = vgl_intersection(dline_3d, pl_ymax, pt_ymax);
89  bool zmin_good = vgl_intersection(dline_3d, pl_zmin, pt_zmin);
90  bool zmax_good = vgl_intersection(dline_3d, pl_zmax, pt_zmax);
91  // Go through the six cases and return the two intersection points
92  // that lie on box faces. Find the pair that are farthest apart.
93  // There could be multiple intersections if the line passes through the
94  // corners of the box.
95  unsigned int npts = 0;
96  vgl_point_3d<double> dp0=pt_xmin, dp1=pt_xmax; // keep this initialisation!
97 
98  // y-z face at xmin
99  if (xmin_good &&
100  pt_xmin.y()>=ymin && pt_xmin.y()<=ymax &&
101  pt_xmin.z()>=zmin && pt_xmin.z()<=zmax)
102  {
103  // dp0 = pt_xmin; // not needed: already set when dp0 was initialised
104  ++npts;
105  }
106  // y-z face at xmax
107  if (xmax_good &&
108  pt_xmax.y()>=ymin && pt_xmax.y()<=ymax &&
109  pt_xmax.z()>=zmin && pt_xmax.z()<=zmax)
110  {
111  if (npts == 0) dp0 = pt_xmax;
112  // else dp1 = pt_xmax; // not needed: already set when dp1 was initialised
113  ++npts;
114  }
115  // x-z face at ymin
116  if (ymin_good &&
117  pt_ymin.x()>=xmin && pt_ymin.x()<=xmax &&
118  pt_ymin.z()>=zmin && pt_ymin.z()<=zmax)
119  {
120  if (npts == 0) { dp0 = pt_ymin; ++npts; }
121  else if (npts == 1) { dp1 = pt_ymin; ++npts; }
122  else /* npts == 2*/ if (sqr_length(pt_ymin-dp0)>sqr_length(dp1-dp0)) dp1 = pt_ymin;
123  }
124  // x-z face at ymax
125  if (ymax_good &&
126  pt_ymax.x()>=xmin && pt_ymax.x()<=xmax &&
127  pt_ymax.z()>=zmin && pt_ymax.z()<=zmax)
128  {
129  if (npts == 0) { dp0 = pt_ymax; ++npts; }
130  else if (npts == 1) { dp1 = pt_ymax; ++npts; }
131  else /* npts == 2*/ if (sqr_length(pt_ymax-dp0)>sqr_length(dp1-dp0)) dp1 = pt_ymax;
132  }
133  // x-y face at zmin
134  if (zmin_good &&
135  pt_zmin.x()>=xmin && pt_zmin.x()<=xmax &&
136  pt_zmin.y()>=ymin && pt_zmin.y()<=ymax)
137  {
138  if (npts == 0) { dp0 = pt_zmin; ++npts; }
139  else if (npts == 1) { dp1 = pt_zmin; ++npts; }
140  else /* npts == 2*/ if (sqr_length(pt_zmin-dp0)>sqr_length(dp1-dp0)) dp1 = pt_zmin;
141  }
142 
143  // x-y face at zmax
144  if (zmax_good &&
145  pt_zmax.x()>=xmin && pt_zmax.x()<=xmax &&
146  pt_zmax.y()>=ymin && pt_zmax.y()<=ymax)
147  {
148  if (npts == 0) { dp0 = pt_zmax; ++npts; }
149  else if (npts == 1) { dp1 = pt_zmax; ++npts; }
150  else /* npts == 2*/ if (sqr_length(pt_zmax-dp0)>sqr_length(dp1-dp0)) dp1 = pt_zmax;
151  }
152 
153  if (npts==2) {
154  p0.set(static_cast<T>(dp0.x()),
155  static_cast<T>(dp0.y()),
156  static_cast<T>(dp0.z()));
157  p1.set(static_cast<T>(dp1.x()),
158  static_cast<T>(dp1.y()),
159  static_cast<T>(dp1.z()));
160  return true;
161  }
162  else
163  return false;
164 }
165 
166 //: Return true if ray intersects box. If so, compute intersection points.
167 // If ray origin is inside box then p0==p1
168 // \relatesalso vgl_box_3d
169 // \relatesalso vgl_ray_3d
170 template <class T>
172  vgl_ray_3d<T> const& ray,
173  vgl_point_3d<T>& p0,
174  vgl_point_3d<T>& p1)
175 {
176  // convert ray to infinite line
177  vgl_infinite_line_3d<T> linf(ray.origin(), ray.direction());
178  bool good_inter = vgl_intersection(box, linf, p0, p1);
179  if (!good_inter) return false;
180  // check if ray origin is inside the box
181  vgl_point_3d<T> org = ray.origin();
182  if (!box.contains(org))
183  //check if the intersection points are in the ray domain
184  return ray.contains(p0)&&ray.contains(p1);
185 
186  //ray origin is inside the box so find the intersection point in the
187  //positive ray domain
188  if (ray.contains(p0)) {
189  p1 = p0; return true;
190  }
191  if (ray.contains(p1)) {
192  p0 = p1; return true;
193  }
194  return false;
195 }
196 
197 //: Return true if a box and plane intersect in 3D
198 // \relatesalso vgl_plane_3d
199 // \relatesalso vgl_box_3d
200 template <class T>
201 bool vgl_intersection(vgl_box_3d<T> const& b, vgl_plane_3d<T> const& plane)
202 {
203  // find the box corners
204  std::vector<vgl_point_3d<T> > corners;
205  corners.push_back(b.min_point());
206  corners.push_back(vgl_point_3d<T> (b.min_x()+b.width(), b.min_y(), b.min_z()));
207  corners.push_back(vgl_point_3d<T> (b.min_x()+b.width(), b.min_y()+b.height(), b.min_z()));
208  corners.push_back(vgl_point_3d<T> (b.min_x(), b.min_y()+b.height(), b.min_z()));
209  corners.push_back(vgl_point_3d<T> (b.min_x(), b.min_y(), b.max_z()));
210  corners.push_back(vgl_point_3d<T> (b.min_x()+b.width(), b.min_y(), b.max_z()));
211  corners.push_back(b.max_point());
212  corners.push_back(vgl_point_3d<T> (b.min_x(), b.min_y()+b.height(), b.max_z()));
213 
214  // find the signed distance from the box corners to the plane
215  int pos=0, neg=0;
216  for (unsigned int c=0; c<corners.size(); c++) {
217  vgl_point_3d<T> corner=corners[c];
218  double d=(plane.a()*corner.x());
219  d+=(plane.b()*corner.y());
220  d+=(plane.c()*corner.z());
221  d+=plane.d();
222  if (d > 0)
223  pos++;
224  else if (d<0)
225  neg++;
226  }
227  return neg!=8 && pos!=8; // completely inside polygon plane
228 }
229 
230 //: Return the intersection of two boxes (which is itself either a box, or empty)
231 // \relatesalso vgl_box_3d
232 template <class T>
234 {
235  T xmin = b1.min_x() > b2.min_x() ? b1.min_x() : b2.min_x();
236  T ymin = b1.min_y() > b2.min_y() ? b1.min_y() : b2.min_y();
237  T zmin = b1.min_z() > b2.min_z() ? b1.min_z() : b2.min_z();
238  T xmax = b1.max_x() < b2.max_x() ? b1.max_x() : b2.max_x();
239  T ymax = b1.max_y() < b2.max_y() ? b1.max_y() : b2.max_y();
240  T zmax = b1.max_z() < b2.max_z() ? b1.max_z() : b2.max_z();
241  return vgl_box_3d<T>(xmin,ymin,zmin,xmax,ymax,zmax);
242 }
243 
244 //: compute the intersection of an infinite line with *this box.
245 // p0 and p1 are the intersection points
246 // In the normal case (no degeneracies) there are six possible intersection combinations:
247 // \verbatim
248 //
249 // C01 / CY \ C11
250 // / | \ .
251 // ymax -----/------|--------\-----
252 // | / | \ |
253 // | / | \ |
254 // | / | \ | \ .
255 // | / | \ | \_ Bounding Box
256 // |/ | \|
257 // / | \ .
258 // /| | |\ .
259 // ---------------------------------- CX
260 // \ | | /
261 // \| | /|
262 // \ | / |
263 // |\ | / |
264 // | \ | / |
265 // | \ | / |
266 // xmin ---\--------|--------/----- xmax
267 // ymin \ | /
268 // C00 \ / C10
269 // \endverbatim
270 
271 template <class Type>
273  const vgl_line_2d<Type>& line,
274  vgl_point_2d<Type>& p0,
275  vgl_point_2d<Type>& p1)
276 {
277  double a = line.a(), b = line.b(), c = line.c();
278  double xmin=box.min_x(), xmax=box.max_x();
279  double ymin=box.min_y(), ymax=box.max_y();
280 
281  // Run through the cases
282  //
283  if (vgl_near_zero(a))// The line is y = -c/b
284  {
285  float y0 = static_cast<float>(-c/b);
286  // The box edge is collinear with line?
287  if (vgl_near_eq(ymin,y0))
288  {
289  p0.set(static_cast<Type>(xmin), static_cast<Type>(ymin));
290  p1.set(static_cast<Type>(xmax), static_cast<Type>(ymin));
291  return true;
292  }
293  if (vgl_near_eq(ymax,y0))
294  {
295  p0.set(static_cast<Type>(xmin), static_cast<Type>(ymax));
296  p1.set(static_cast<Type>(xmax), static_cast<Type>(ymax));
297  return true;
298  }
299 
300  if ((ymin > y0) || (y0 > ymax)) // The line does not intersect the box
301  return false;
302  else // The line does intersect
303  {
304  p0.set(static_cast<Type>(xmin), static_cast<Type>(y0));
305  p1.set(static_cast<Type>(xmax), static_cast<Type>(y0));
306  return true;
307  }
308  }
309 
310  if (vgl_near_zero(b))// The line is x = -c/a
311  {
312  float x0 = static_cast<float>(-c/a);
313  // The box edge is collinear with l?
314  if (vgl_near_eq(xmin,x0))
315  {
316  p0.set(static_cast<Type>(xmin), static_cast<Type>(ymin));
317  p1.set(static_cast<Type>(xmin), static_cast<Type>(ymax));
318  return true;
319  }
320  if (vgl_near_eq(xmax,x0))
321  {
322  p0.set(static_cast<Type>(xmax), static_cast<Type>(ymin));
323  p1.set(static_cast<Type>(xmax), static_cast<Type>(ymax));
324  return true;
325  }
326 
327  if (xmin <= x0 && x0 <= xmax) // The line intersects the box
328  {
329  p0.set(static_cast<Type>(x0), static_cast<Type>(ymin));
330  p1.set(static_cast<Type>(x0), static_cast<Type>(ymax));
331  return true;
332  }
333  else
334  return false;
335  }
336 
337  // The normal case with no degeneracies
338  //
339  // Intersection with x = xmin
340  float y_xmin_int = static_cast<float>(-(c + a*xmin)/b);
341  bool inside_xmin = (y_xmin_int >= ymin) && (y_xmin_int <= ymax);
342 
343  // Intersection with x = xmax
344  float y_xmax_int = static_cast<float>(-(c + a*xmax)/b);
345  bool inside_xmax = (y_xmax_int >= ymin) && (y_xmax_int <= ymax);
346 
347  // Intersection with y = ymin
348  float x_ymin_int = static_cast<float>(-(c + b*ymin)/a);
349  bool inside_ymin = (x_ymin_int >= xmin) && (x_ymin_int <= xmax);
350 
351  // Intersection with y = ymax
352  float x_ymax_int = static_cast<float>(-(c + b*ymax)/a);
353  bool inside_ymax = (x_ymax_int >= xmin) && (x_ymax_int <= xmax);
354 
355  // Case CX
356  if (inside_xmin && inside_xmax &&
357  !(vgl_near_eq(y_xmin_int,ymin) && vgl_near_eq(y_xmax_int,ymax)))
358  {
359  p0.set(static_cast<Type>(xmin), static_cast<Type>(y_xmin_int));
360  p1.set(static_cast<Type>(xmax), static_cast<Type>(y_xmax_int));
361  return true;
362  }
363 
364  // Case CY
365  if (inside_ymin && inside_ymax &&
366  !(vgl_near_eq(x_ymin_int,xmin) && vgl_near_eq(x_ymax_int,xmax)))
367  {
368  p0.set(static_cast<Type>(x_ymin_int), static_cast<Type>(ymin));
369  p1.set(static_cast<Type>(x_ymax_int), static_cast<Type>(ymax));
370  return true;
371  }
372 
373  // Case C00
374  if (inside_xmin && inside_ymin &&
375  !(inside_xmax && inside_ymax))
376  {
377  p0.set(static_cast<Type>(xmin), static_cast<Type>(y_xmin_int));
378  p1.set(static_cast<Type>(x_ymin_int), static_cast<Type>(ymin));
379  return true;
380  }
381 
382  // Case C01
383  if (inside_xmin && inside_ymax &&
384  !(inside_xmax && inside_ymin))
385  {
386  p0.set(static_cast<Type>(xmin), static_cast<Type>(y_xmin_int));
387  p1.set(static_cast<Type>(x_ymax_int), static_cast<Type>(ymax));
388  return true;
389  }
390 
391  // Case C10
392  if (inside_ymin && inside_xmax &&
393  !(inside_xmin && inside_ymax))
394  {
395  p0.set(static_cast<Type>(x_ymin_int), static_cast<Type>(ymin));
396  p1.set(static_cast<Type>(xmax), static_cast<Type>(y_xmax_int));
397  return true;
398  }
399 
400  // Case C11
401  if (inside_ymax && inside_xmax &&
402  !(inside_xmin && inside_ymin))
403  {
404  p0.set(static_cast<Type>(x_ymax_int), static_cast<Type>(ymax));
405  p1.set(static_cast<Type>(xmax), static_cast<Type>(y_xmax_int));
406  return true;
407  }
408  // Exactly passing through diagonal of BB
409  if (inside_xmin && inside_xmax && inside_ymin && inside_ymax)
410  {
411  if (a>0) // 45 degrees
412  {
413  p0.set(static_cast<Type>(xmin), static_cast<Type>(ymin));
414  p1.set(static_cast<Type>(xmax), static_cast<Type>(ymax));
415  return true;
416  }
417  else // 135 degrees
418  {
419  p0.set(static_cast<Type>(xmin), static_cast<Type>(ymax));
420  p1.set(static_cast<Type>(xmax), static_cast<Type>(ymin));
421  return true;
422  }
423  }
424  return false;
425 }
426 
427 //: Returns the number of intersections of a line segment with a box, up to two are returned in p0 and p1.
428 template <class Type>
429 unsigned int vgl_intersection(const vgl_box_2d<Type>& box,
430  const vgl_line_segment_2d<Type>& line_seg,
431  vgl_point_2d<Type>& p0,
432  vgl_point_2d<Type>& p1)
433 {
434  vgl_line_2d<Type> line(line_seg.a(), line_seg.b(), line_seg.c());
435  vgl_point_2d<Type> pi0, pi1;
436  // if no intersection just return
437  if (!vgl_intersection<Type>(box, line, pi0, pi1))
438  return 0;
439  unsigned int nint = 0;
440  // check if intersection points are interior to the line segment
441  if (vgl_lineseg_test_point<Type>(pi0, line_seg)) {
442  p0 = pi0;
443  nint++;
444  }
445  if (vgl_lineseg_test_point<Type>(pi1, line_seg)) {
446  p1 = pi1;
447  nint++;
448  }
449  return nint;
450 }
451 // return the line segment that lies inside the box. If none, return false.
452 template <class T>
454  vgl_line_segment_2d<T> const& line_seg,
455  vgl_line_segment_2d<T>& int_line_seg){
456  // check if both segment endpoints are inside the box
457  const vgl_point_2d<T>& p1 = line_seg.point1();
458  const vgl_point_2d<T>& p2 = line_seg.point2();
459  bool p1_in_box = box.contains(p1);
460  bool p2_in_box = box.contains(p2);
461  if(p1_in_box&&p2_in_box){
462  int_line_seg = line_seg;
463  return true;
464  }
465  // form an infinite line
466  vgl_line_2d<T> line(line_seg.a(), line_seg.b(), line_seg.c());
467  vgl_point_2d<T> pia, pib;
468  // if no intersection just return
469  if (!vgl_intersection<T>(box, line, pia, pib))
470  return false;
471 
472  // check if intersection points are interior to the line segment
473  bool pia_valid = vgl_lineseg_test_point<T>(pia, line_seg);
474  bool pib_valid = vgl_lineseg_test_point<T>(pib, line_seg);
475  // shouldn't happen but to be complete ...
476  if((!pia_valid)&&(!pib_valid))
477  return false;
478  //if both intersection points are interior to the line segment then
479  //return a segment that spans the box interior
480  if(pia_valid&&pib_valid){
481  int_line_seg.set(pia, pib);
482  return true;
483  }
484  //only one intersection point is valid so form the line segment interior
485  //to the box
486  // find the original segment endpoint inside the box
487  if(p1_in_box){// p1 is inside the box
488  if(pia_valid)
489  int_line_seg.set(p1, pia);
490  else
491  int_line_seg.set(p1, pib);
492  return true;
493  }else{// p2 is inside the box
494  if(pia_valid)
495  int_line_seg.set(p2, pia);
496  else
497  int_line_seg.set(p2, pib);
498  return true;
499  }
500  return false;
501 }
502 
503 //: Return the intersection point of two concurrent lines
504 template <class T>
506  vgl_line_3d_2_points<T> const& l2)
507 {
508  assert(concurrent(l1,l2));
509  T a0=l1.point1().x(),a1=l1.point2().x(),a2=l2.point1().x(),a3=l2.point2().x(),
510  b0=l1.point1().y(),b1=l1.point2().y(),b2=l2.point1().y(),b3=l2.point2().y(),
511  c0=l1.point1().z(),c1=l1.point2().z(),c2=l2.point1().z(),c3=l2.point2().z();
512  T t1 = (b3-b2)*(a1-a0)-(a3-a2)*(b1-b0), t2 = (b0-b2)*(a1-a0)-(a0-a2)*(b1-b0);
513  if (std::abs(t1) < 0.000001)
514  {
515  t1 = (c3-c2)*(a1-a0)-(a3-a2)*(c1-c0), t2 = (c0-c2)*(a1-a0)-(a0-a2)*(c1-c0);
516  if (std::abs(t1) < 0.000001)
517  t1 = (c3-c2)*(b1-b0)-(b3-b2)*(c1-c0), t2 = (c0-c2)*(b1-b0)-(b0-b2)*(c1-c0);
518  }
519 
520  return vgl_point_3d<T>(((t1-t2)*a2+t2*a3)/t1,
521  ((t1-t2)*b2+t2*b3)/t1,
522  ((t1-t2)*c2+t2*c3)/t1);
523 }
524 
525 //: Return the intersection point of segments of two concurrent lines
526 // \relatesalso vgl_line_segment_3d
527 template <class T>
529  vgl_line_segment_3d<T> const& l2,
530  vgl_point_3d<T>& i_pnt)
531 {
532  vgl_line_3d_2_points<T> l21(l1.point1(),l1.point2());
533  vgl_line_3d_2_points<T> l22(l2.point1(),l2.point2());
534  if (!concurrent(l21, l22))
535  return false;
536  i_pnt = vgl_intersection(l21, l22);
537 
538  double l1_len = length(l1.point1() - l1.point2());
539  double l1_idist = length(l1.point1() - i_pnt) + length(l1.point2() - i_pnt);
540  double l2_len = length(l2.point1() - l2.point2());
541  double l2_idist = length(l2.point1() - i_pnt) + length(l2.point2() - i_pnt);
542  return vgl_near_zero(l1_len - l1_idist) && vgl_near_zero(l2_len - l2_idist);
543 }
544 
545 //: Return the intersection point of segments of two concurrent lines
546 // \relatesalso vgl_line_segment_3d
547 // \relatesalso vgl_line_3d_2_points
548 template <class T>
550  vgl_line_segment_3d<T> const& l2,
551  vgl_point_3d<T>& i_pnt)
552 {
553  vgl_line_3d_2_points<T> l22(l2.point1(),l2.point2());
554  if (!concurrent(l1, l22))
555  return false;
556  i_pnt = vgl_intersection(l1, l22);
557 
558  double l1_len = length(l1.point1() - l1.point2());
559  double l1_idist = length(l1.point1() - i_pnt) + length(l1.point2() - i_pnt);
560  double l2_len = length(l2.point1() - l2.point2());
561  double l2_idist = length(l2.point1() - i_pnt) + length(l2.point2() - i_pnt);
562 
563  return vgl_near_zero(l1_len - l1_idist) && vgl_near_zero(l2_len - l2_idist);
564 }
565 
566 //: Return the intersection point of two lines, if concurrent.
567 // \relatesalso vgl_infinite_line_3d
568 template <class T>
570  vgl_infinite_line_3d<T> const& l2,
571  vgl_point_3d<T>& i_pnt)
572 {
573  vgl_line_3d_2_points<T> l21(l1.point(),l1.point_t(T(1)));
574  vgl_line_3d_2_points<T> l22(l2.point(),l2.point_t(T(1)));
575  if (!concurrent(l21, l22))
576  return false;
577  i_pnt = vgl_intersection(l21, l22);
578  return l1.contains(i_pnt) && l2.contains(i_pnt);
579 }
580 
581 template <class T>
583  vgl_ray_3d<T> const& r2,
584  vgl_point_3d<T>& i_pnt)
585 {
586  vgl_line_3d_2_points<T> l21(r1.origin(),r1.origin()+r1.direction());
587  vgl_line_3d_2_points<T> l22(r2.origin(),r2.origin()+r2.direction());
588  if (!concurrent(l21, l22))
589  return false;
590  i_pnt = vgl_intersection(l21, l22);
591  return r1.contains(i_pnt)&&r2.contains(i_pnt);
592 }
593 
594 //: Return the intersection point of a line and a plane.
595 // \relatesalso vgl_line_3d_2_points
596 // \relatesalso vgl_plane_3d
597 template <class T>
599  vgl_plane_3d<T> const& plane)
600 {
601  vgl_vector_3d<T> dir = line.direction();
602 
603  vgl_point_3d<T> pt;
604 
605  double denom = plane.a()*dir.x() +
606  plane.b()*dir.y() +
607  plane.c()*dir.z();
608 
609  if (denom == 0)
610  {
611  const T inf = std::numeric_limits<T>::infinity();
612  // Line is either parallel or coplanar
613  // If the distance from a line endpoint to the plane is zero, coplanar
614  if (vgl_distance(line.point1(), plane)==0.0)
615  pt.set(inf,inf,inf);
616  else
617  pt.set(inf,0,0);
618  }
619  else
620  {
621  // Infinite line intersects plane
622  double numer = - plane.a()*line.point1().x()
623  - plane.b()*line.point1().y()
624  - plane.c()*line.point1().z()
625  - plane.d();
626 
627  dir *= numer/denom;
628  pt = line.point1() + dir;
629  }
630 
631  return pt;
632 }
633 
634 //: Return the intersection point of a line and a plane.
635 // \relatesalso vgl_line_segment_3d
636 // \relatesalso vgl_plane_3d
637 template <class T>
639  vgl_plane_3d<T> const& plane,
640  vgl_point_3d<T> & i_pt)
641 {
642  vgl_vector_3d<T> dir = line.direction();
643 
644  // The calculation of both denom and numerator are both very dodgy numerically, especially if
645  // denom or numerator is small compared to the summands. It would be good to find a more
646  // numerically stable solution. IMS.
647  const double tol = std::numeric_limits<T>::epsilon() * 10e3;
648 
649  double denom = plane.a()*dir.x() +
650  plane.b()*dir.y() +
651  plane.c()*dir.z();
652 
653  if (std::abs(denom) < tol)
654  {
655  // Line is either parallel or coplanar
656  // If the distance from a line endpoint to the plane is zero, coplanar
657  if (vgl_distance(line.point1(), plane)!=0.0)
658  return false;
659 
660  const T inf = std::numeric_limits<T>::infinity();
661  i_pt.set(inf,inf,inf);
662  return true;
663  }
664 
665  double numer = - plane.a()*line.point1().x()
666  - plane.b()*line.point1().y()
667  - plane.c()*line.point1().z()
668  - plane.d();
669 
670  double t = numer/denom; // 0<t<1 between two points
671  if (t < 0 || t > 1.0) return false;
672 
673  i_pt = line.point1() + t * dir;
674  return true;
675 }
676 
677 template <class T>
679  vgl_plane_3d<T> const& plane,
680  vgl_point_3d<T> & i_pt)
681 {
682  vgl_vector_3d<T> dir = line.direction();
683  vgl_point_3d<T> pt = line.point();
684  // The calculation of both denom and numerator are both very dodgy numerically, especially if
685  // denom or numerator is small compared to the summands. It would be good to find a more
686  // numerically stable solution. IMS.
687  const double tol = std::numeric_limits<T>::epsilon() * 10e3;
688 
689  double denom = plane.a()*dir.x() +
690  plane.b()*dir.y() +
691  plane.c()*dir.z();
692 
693  if (std::abs(denom) < tol)
694  {
695  // Line is either parallel or coplanar
696  // If the distance from a line endpoint to the plane is zero, coplanar
697  if (vgl_distance(pt, plane)!=0.0)
698  return false;
699 
700  const T inf = std::numeric_limits<T>::infinity();
701  i_pt.set(inf,inf,inf);
702  return true;
703  }
704 
705  double numer = - plane.a()*pt.x()
706  - plane.b()*pt.y()
707  - plane.c()*pt.z()
708  - plane.d();
709 
710  double t = numer/denom;
711  i_pt = pt + t * dir;
712  return true;
713 }
714 
715 template <class T>
717  vgl_plane_3d<T> const& plane,
718  vgl_point_3d<T> & i_pt)
719 {
720  vgl_vector_3d<T> dir = ray.direction();
721  vgl_point_3d<T> pt = ray.origin();
722  // The calculation of both denom and numerator are both very dodgy numerically, especially if
723  // denom or numerator is small compared to the summands. It would be good to find a more
724  // numerically stable solution. IMS.
725  const double tol = std::numeric_limits<T>::epsilon() * 10e3;
726 
727  double denom = plane.a()*dir.x() +
728  plane.b()*dir.y() +
729  plane.c()*dir.z();
730 
731  if (std::abs(denom) < tol)
732  {
733  // Line is either parallel or coplanar
734  // If the distance from a line endpoint to the plane is zero, coplanar
735  if (vgl_distance(pt, plane)!=0.0)
736  return false;
737 
738  const T inf = std::numeric_limits<T>::infinity();
739  i_pt.set(inf,inf,inf);
740  return true;
741  }
742 
743  double numer = - plane.a()*pt.x()
744  - plane.b()*pt.y()
745  - plane.c()*pt.z()
746  - plane.d();
747 
748  double t = numer/denom;
749  if (t<0) return false;
750  i_pt = pt + t * dir;
751  return true;
752 }
753 
754 template <class T>
755 bool vgl_intersection( const vgl_line_2d<T> &line0,
756  const vgl_line_2d<T> &line1,
757  vgl_point_2d<T> &intersection_point )
758 {
759  T a0, b0, c0, a1, b1, c1;
760  a0 = line0.a(); b0 = line0.b(); c0 = line0.c();
761  a1 = line1.a(); b1 = line1.b(); c1 = line1.c();
762 
763  T delta, delta_x, delta_y, x, y;
764  delta = a0*b1 - a1*b0;
765  if ( std::abs(delta) <= vgl_tolerance<T>::position ) // Lines are parallel
766  return false;
767  delta_x = -c0*b1 + b0*c1; delta_y = -a0*c1 + a1*c0;
768  x = delta_x / delta; y = delta_y / delta;
769 
770  // intersection_point.set( (Type)x, (Type)y );
771  intersection_point.set( x, y );
772  return true;
773 }
774 
775 //: Return the intersection line of two planes. Returns false if planes
776 // are effectively parallel
777 // \relatesalso vgl_infinite_line_3d
778 // \relatesalso vgl_plane_3d
779 template <class T>
781  vgl_plane_3d<T> const& plane1,
783 {
784  double n0x = static_cast<double>(plane0.a());
785  double n0y = static_cast<double>(plane0.b());
786  double n0z = static_cast<double>(plane0.c());
787  double n1x = static_cast<double>(plane1.a());
788  double n1y = static_cast<double>(plane1.b());
789  double n1z = static_cast<double>(plane1.c());
790  vgl_vector_3d<double> n0(n0x, n0y, n0z);
791  vgl_vector_3d<double> n1(n1x, n1y, n1z);
792  // t is the direction vector of the line
794  double mag = t.length();
795  if (vgl_near_zero(mag)) // planes are parallel (or coincident)
796  return false;
797  t/=mag; // create unit vector
798  double tx = std::fabs(static_cast<double>(t.x_));
799  double ty = std::fabs(static_cast<double>(t.y_));
800  double tz = std::fabs(static_cast<double>(t.z_));
801  // determine maximum component of t
802  char component = 'x';
803  if (ty>=tx&&ty>=tz)
804  component = 'y';
805  if (tz>=tx&&tz>=ty)
806  component = 'z';
807  double d0 = static_cast<double>(plane0.d());
808  double d1 = static_cast<double>(plane1.d());
810  switch (component)
811  {
812  // x is the largest component of t
813  case 'x':
814  {
815  double det = n0y*n1z-n1y*n0z;
816  if (vgl_near_zero(det))
817  return false;
818  double neuy = d1*n0z - d0*n1z;
819  double neuz = d0*n1y - d1*n0y;
820  p0d.set(0.0, neuy/det, neuz/det);
821  break;
822  }
823  case 'y':
824  {
825  double det = n0x*n1z-n1x*n0z;
826  if (vgl_near_zero(det))
827  return false;
828  double neux = d1*n0z - d0*n1z;
829  double neuz = d0*n1x - d1*n0x;
830  p0d.set(neux/det, 0.0, neuz/det);
831  break;
832  }
833  case 'z':
834  default:
835  {
836  double det = n0x*n1y-n1x*n0y;
837  if (vgl_near_zero(det))
838  return false;
839  double neux = d1*n0y - d0*n1y;
840  double neuy = d0*n1x - d1*n0x;
841  p0d.set(neux/det, neuy/det, 0.0);
842  break;
843  }
844  }
845  vgl_point_3d<T> p0(static_cast<T>(p0d.x()),
846  static_cast<T>(p0d.y()),
847  static_cast<T>(p0d.z()));
848  vgl_vector_3d<T> tt(static_cast<T>(t.x()),
849  static_cast<T>(t.y()),
850  static_cast<T>(t.z()));
851  line = vgl_infinite_line_3d<T>(p0, tt);
852  return true;
853 }
854 
855 //: Return the intersection point of three planes.
856 // \relatesalso vgl_plane_3d
857 template <class T>
859  const vgl_plane_3d<T>& p2,
860  const vgl_plane_3d<T>& p3)
861 {
862  vgl_point_3d<T> p(p1, p2, p3);
863  return p;
864 }
865 
866 //: Return true if any point on [p1,p2] is within tol of [q1,q2]
867 // Tests two line segments for intersection or near intersection
868 // (within given tolerance).
869 // \author Dan jackson
870 template <class T>
872  vgl_point_2d<T> const& p2,
873  vgl_point_2d<T> const& q1,
874  vgl_point_2d<T> const& q2,
875  double tol)
876 {
877  vgl_vector_2d<T> u = p2 - p1;
878  vgl_vector_2d<T> v(-u.y(),u.x());
879  double uq1 = dot_product(q1 - p1,u);
880  double vq1 = dot_product(q1 - p1,v);
881  double tol2 = tol*tol;
882  double L2 = sqr_length(u);
883 
884  // Check if q1 is in central band (either side of line p1-p2
885  if (uq1 > 0 && uq1 < L2)
886  {
887  // Check if q1 is within tol of the line, ie |vq1/L| < tol
888  if (vq1*vq1 <=tol2*L2) return true;
889  }
890  else
891  {
892  // Check if q1 is within tol of either end of line
893  if ( (q1-p1).sqr_length() <= tol2 || (q1-p2).sqr_length() <= tol2 )
894  return true;
895  }
896 
897  // Repeat test for q2
898  double uq2 = dot_product(q2 - p1,u);
899  double vq2 = dot_product(q2 - p1,v);
900 
901  // Check if q2 is in central band (either side of line p1-p2
902  if (uq2 > 0 && uq2 < L2)
903  {
904  // Check if q1 is within tol of the line, ie |vq1/L| < tol
905  if (vq2*vq2 <=tol2*L2)
906  return true;
907  }
908  else
909  {
910  // Check if q1 is within tol of either end of line
911  if ( (q2-p1).sqr_length() <= tol2 || (q2-p2).sqr_length() <= tol2 )
912  return true;
913  }
914 
915  // The points q1 and q2 do not lie within the tolerance region
916  // around line segment (p1,p2)
917  // Now repeat the test the other way around,
918  // testing whether points p1 and p2 lie in tolerance region
919  // of line (q1,q2)
920 
921  u = q2 - q1;
922  v.set(-u.y(),u.x());
923  L2 = sqr_length(u);
924 
925  double up1 = dot_product(p1 - q1,u);
926  double vp1 = dot_product(p1 - q1,v);
927 
928  // Check if p1 is in central band either side of line q1-q2
929  if (up1 > 0 && up1 < L2)
930  {
931  // Check if p1 is within tol of the line, ie |vp1/L| < tol
932  if (vp1*vp1 <=tol2*L2)
933  return true;
934  }
935  else
936  {
937  // Check if p1 is within tol of either end of line
938  if ( (p1-q1).sqr_length() <= tol2 || (p1-q2).sqr_length() <= tol2 )
939  return true;
940  }
941 
942  double up2 = dot_product(p2 - q1,u);
943  double vp2 = dot_product(p2 - q1,v);
944 
945  // Check if p2 is in central band either side of line q1-q2
946  if (up2 > 0 && up2 < L2)
947  {
948  // Check if p1 is within tol of the line, ie |vp1/L| < tol
949  if (vp2*vp2 <=tol2*L2)
950  return true;
951  }
952  else
953  {
954  // Check if p2 is within tol of either end of line
955  if ( (p2-q1).sqr_length() <= tol2 || (p2-q2).sqr_length() <= tol2)
956  return true;
957  }
958 
959  // Now check for actual intersection
960  return vq1*vq2 < 0 && vp1*vp2 < 0;
961 }
962 
963 template <class T>
965  const vgl_polygon<T>& poly)
966 {
967  // easy checks first
968  // check if any poly vertices are inside the box
969  unsigned int ns = poly.num_sheets();
970  bool hit = false;
971  for (unsigned int s = 0; s<ns&&!hit; ++s) {
972  unsigned int n = (unsigned int)(poly[s].size());
973  for (unsigned int i = 0; i<n&&!hit; ++i) {
974  vgl_point_2d<T> p = poly[s][i];
975  hit = b.contains(p.x(), p.y());
976  }
977  }
978  if (hit) return true;
979  // check if any box vertices are inside the polygon
980  T minx = b.min_x(), maxx = b.max_x();
981  T miny = b.min_y(), maxy = b.max_y();
982  hit = poly.contains(minx, miny) || poly.contains(maxx, maxy) ||
983  poly.contains(minx, maxy) || poly.contains(maxx, miny);
984  if (hit) return true;
985  // check if any polygon edges intersect the box
986  for (unsigned int s = 0; s<ns&&!hit; ++s)
987  {
988  unsigned int n = (unsigned int)(poly[s].size());
989  vgl_point_2d<T> ia, ib;
990  vgl_point_2d<T> last = poly[s][0];
991  for (unsigned int i = 1; i<n&&!hit; ++i)
992  {
993  vgl_point_2d<T> p = poly[s][i];
994  vgl_line_segment_2d<T> l(last, p);
995  hit = vgl_intersection<T>(b, l, ia, ib)>0;
996  last = p;
997  }
998  if (!hit) {
999  vgl_point_2d<T> start = poly[s][0];
1000  vgl_line_segment_2d<T> ll(last, start);
1001  hit = vgl_intersection<T>(b,ll, ia, ib)>0;
1002  }
1003  }
1004  return hit;
1005 }
1006 
1007 //: Return the points from the list that lie inside the box
1008 // \relatesalso vgl_point_2d
1009 // \relatesalso vgl_box_2d
1010 template <class T>
1011 std::vector<vgl_point_2d<T> > vgl_intersection(vgl_box_2d<T> const& b, std::vector<vgl_point_2d<T> > const& p)
1012 {
1013  std::vector<vgl_point_2d<T> > r;
1014  typename std::vector<vgl_point_2d<T> >::const_iterator i;
1015  for (i = p.begin(); i != p.end(); ++i)
1016  if (vgl_intersection(b, *i))
1017  r.push_back(*i);
1018  return r;
1019 }
1020 
1021 //: Return the points from the list that lie inside the box
1022 // \relatesalso vgl_point_2d
1023 // \relatesalso vgl_box_2d
1024 template <class T>
1025 std::vector<vgl_point_2d<T> > vgl_intersection(std::vector<vgl_point_2d<T> > const& p, vgl_box_2d<T> const& b)
1026 {
1027  std::vector<vgl_point_2d<T> > r;
1028  typename std::vector<vgl_point_2d<T> >::const_iterator i;
1029  for (i = p.begin(); i != p.end(); ++i)
1030  if (vgl_intersection(b, *i))
1031  r.push_back(*i);
1032  return r;
1033 }
1034 
1035 //: Return the points from the list that lie inside the box
1036 // \relatesalso vgl_point_3d
1037 // \relatesalso vgl_box_3d
1038 template <class T>
1039 std::vector<vgl_point_3d<T> > vgl_intersection(vgl_box_3d<T> const& b, std::vector<vgl_point_3d<T> > const& p)
1040 {
1041  std::vector<vgl_point_3d<T> > r;
1042  typename std::vector<vgl_point_3d<T> >::const_iterator i;
1043  for (i = p.begin(); i != p.end(); ++i)
1044  if (vgl_intersection(b, *i))
1045  r.push_back(*i);
1046  return r;
1047 }
1048 
1049 //: Return the points from the list that lie inside the box
1050 // \relatesalso vgl_point_3d
1051 // \relatesalso vgl_box_3d
1052 template <class T>
1053 std::vector<vgl_point_3d<T> > vgl_intersection(std::vector<vgl_point_3d<T> > const& p, vgl_box_3d<T> const& b)
1054 {
1055  std::vector<vgl_point_3d<T> > r;
1056  typename std::vector<vgl_point_3d<T> >::const_iterator i;
1057  for (i = p.begin(); i != p.end(); ++i)
1058  if (vgl_intersection(b, *i))
1059  r.push_back(*i);
1060  return r;
1061 }
1062 
1063 template <class T>
1064 std::vector<vgl_point_2d<T> > vgl_intersection(vgl_polygon<T> const& poly,
1065  vgl_line_2d<T> const& line) {
1066  std::vector<vgl_point_2d<T> > ret;
1067  T tol = std::sqrt(vgl_tolerance<T>::position);
1068  T a = line.a(), b = line.b(), c = line.c();
1069  T norm = std::sqrt(a*a + b*b);
1070  a/=norm; b/=norm; c/=norm;
1071  unsigned ns = poly.num_sheets();
1072  for (unsigned s = 0; s<ns; ++s) {
1073  std::vector<vgl_point_2d<T> > sh = poly[s];
1074  unsigned nv = static_cast<unsigned>(sh.size());
1075  for (unsigned i = 0; i<nv; ++i) {
1076  unsigned next = (i+1)%nv;
1077  vgl_point_2d<T> pa = sh[i];
1078  vgl_point_2d<T> pb = sh[next];
1079  //algebraic distances
1080  T ad_a = a*pa.x() +b*pa.y() +c;
1081  T ad_b = a*pb.x() +b*pb.y() +c;
1082  bool sign_a = ad_a>T(0);
1083  bool sign_b = ad_b>T(0);
1084  bool zero = std::abs(ad_a)<tol;
1085  //cases
1086  // 1) no intersections
1087  // 2) current vertex intersects
1088  // 3) intersection interior to poly edge
1089  // case 1
1090  if (!zero&&(sign_a == sign_b))
1091  continue;
1092  // case 2
1093  if (zero) {
1094  ret.push_back(pa);
1095  continue;
1096  }
1097  //case 3
1098  // find the intersection
1099  vgl_line_2d<T> edge(pa, pb);
1100  vgl_point_2d<T> p_int;
1101  if (!vgl_intersection(line, edge, p_int))
1102  continue;
1103  ret.push_back(p_int);
1104  }
1105  }
1106  return ret;
1107 }
1108 
1109 //: find points that intersect the plane within the specified tolerance on normal distance to the plane.
1110 template <class T>
1112  vgl_pointset_3d<T> ret;
1113  bool hasn = ptset.has_normals();
1114  unsigned npts = ptset.npts();
1115  for(unsigned i = 0; i<npts; ++i){
1116  vgl_point_3d<T> p = ptset.p(i);
1117  vgl_point_3d<T> cp = vgl_closest_point(plane, p);
1118  T d = static_cast<T>((p-cp).length());
1119  if(d<tol){
1120  if(hasn){
1121  vgl_vector_3d<T> norm = ptset.n(i);
1122  ret.add_point_with_normal(p, norm);
1123  }else{
1124  ret.add_point(p);
1125  }
1126  }
1127  }
1128  return ret;
1129 }
1130 template <class T>
1132  unsigned npts = ptset.npts();
1133  std::vector<vgl_point_3d<T> > pts;
1134  std::vector<vgl_vector_3d<T> > normals;
1135  bool hasn = ptset.has_normals();
1136  for(unsigned i = 0; i<npts; ++i){
1137  vgl_point_3d<T> p = ptset.p(i);
1138  if(box.contains(p)){
1139  pts.push_back(p);
1140  if(hasn)
1141  normals.push_back(ptset.n(i));
1142  }
1143  }
1144  if(hasn)
1145  return vgl_pointset_3d<T>(pts, normals);
1146  return vgl_pointset_3d<T>(pts);
1147 }
1148 
1149 // Instantiate those functions which are suitable for integer instantiation.
1150 #undef VGL_INTERSECTION_BOX_INSTANTIATE
1151 #define VGL_INTERSECTION_BOX_INSTANTIATE(T) \
1152 template vgl_box_2d<T > vgl_intersection(vgl_box_2d<T > const&,vgl_box_2d<T > const&); \
1153 template vgl_box_3d<T > vgl_intersection(vgl_box_3d<T > const&,vgl_box_3d<T > const&); \
1154 template std::vector<vgl_point_2d<T > > vgl_intersection(vgl_box_2d<T > const&,std::vector<vgl_point_2d<T > > const&); \
1155 template std::vector<vgl_point_2d<T > > vgl_intersection(std::vector<vgl_point_2d<T > > const&,vgl_box_2d<T > const&); \
1156 template std::vector<vgl_point_3d<T > > vgl_intersection(vgl_box_3d<T > const&,std::vector<vgl_point_3d<T > > const&); \
1157 template std::vector<vgl_point_3d<T > > vgl_intersection(std::vector<vgl_point_3d<T > > const&,vgl_box_3d<T > const&); \
1158 template bool vgl_intersection(vgl_box_2d<T > const&,vgl_line_2d<T > const&,vgl_point_2d<T >&,vgl_point_2d<T >&); \
1159 template bool vgl_intersection(vgl_box_2d<T> const&,vgl_line_segment_2d<T> const&, vgl_line_segment_2d<T>& ); \
1160 template bool vgl_intersection(vgl_box_3d<T > const&,vgl_plane_3d<T > const&); \
1161 template bool vgl_intersection(vgl_box_3d<T > const&,vgl_infinite_line_3d<T > const&,vgl_point_3d<T >&,vgl_point_3d<T >&);\
1162 template bool vgl_intersection(vgl_box_3d<T > const&,vgl_ray_3d<T > const&,vgl_point_3d<T >&,vgl_point_3d<T >&)
1163 #undef VGL_INTERSECTION_INSTANTIATE
1164 #define VGL_INTERSECTION_INSTANTIATE(T) \
1165 template vgl_pointset_3d<T> vgl_intersection(vgl_plane_3d<T> const&, vgl_pointset_3d<T> const&, T); \
1166 template vgl_pointset_3d<T> vgl_intersection(vgl_box_3d<T> const&, vgl_pointset_3d<T> const&); \
1167 template vgl_point_3d<T > vgl_intersection(vgl_line_3d_2_points<T > const&,vgl_line_3d_2_points<T > const&); \
1168 template bool vgl_intersection(vgl_line_segment_3d<T > const&,vgl_line_segment_3d<T > const&,vgl_point_3d<T >&); \
1169 template bool vgl_intersection(vgl_line_3d_2_points<T > const&,vgl_line_segment_3d<T > const&,vgl_point_3d<T >&); \
1170 template bool vgl_intersection(vgl_ray_3d<T > const&,vgl_ray_3d<T > const&,vgl_point_3d<T >&); \
1171 template vgl_point_3d<T > vgl_intersection(vgl_line_3d_2_points<T > const&,vgl_plane_3d<T > const&); \
1172 template bool vgl_intersection(vgl_line_segment_3d<T > const&,vgl_plane_3d<T > const&,vgl_point_3d<T >&); \
1173 template bool vgl_intersection(vgl_infinite_line_3d<T > const&,vgl_plane_3d<T > const&,vgl_point_3d<T >&); \
1174 template bool vgl_intersection(vgl_ray_3d<T > const& ray, vgl_plane_3d<T > const& plane, vgl_point_3d<T > & i_pt); \
1175 template bool vgl_intersection(vgl_infinite_line_3d<T > const&,vgl_infinite_line_3d<T > const&,vgl_point_3d<T >&); \
1176 template vgl_point_3d<T > vgl_intersection(vgl_plane_3d<T > const&,vgl_plane_3d<T > const&,vgl_plane_3d<T > const&); \
1177 template unsigned vgl_intersection(vgl_box_2d<T > const&,vgl_line_segment_2d<T > const&,vgl_point_2d<T >&,vgl_point_2d<T >&); \
1178 template bool vgl_intersection(vgl_line_2d<T > const&,vgl_line_2d<T > const&,vgl_point_2d<T >&); \
1179 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); \
1180 template bool vgl_intersection(vgl_box_2d<T > const&,vgl_polygon<T > const&); \
1181 template bool vgl_intersection(vgl_plane_3d<T > const&,vgl_plane_3d<T > const&,vgl_line_segment_3d<T > &); \
1182 template bool vgl_intersection(vgl_plane_3d<T > const&,vgl_plane_3d<T > const&,vgl_infinite_line_3d<T >&); \
1183 template std::vector<vgl_point_2d<T > > vgl_intersection(vgl_polygon<T > const&, vgl_line_2d<T > const&); \
1184 VGL_INTERSECTION_BOX_INSTANTIATE(T)
1185 
1186 #endif // vgl_intersection_hxx_
Set of intersection functions.
Represents a 2D line segment using two points.
Definition: vgl_fwd.h:18
T dot_product(v const &a, v const &b)
dot product or inner product of two vectors.
Type b() const
Parameter b of line a*x + b*y + c = 0.
bool vgl_near_eq(double x, double y)
vgl_point_3d< Type > point1() const
a point in 2D nonhomogeneous space
Type a() const
Parameter a of line a*x + b*y + c = 0.
bool contains(point_t const &p) const
Returns true if p(x,y) is inside the polygon, else false.
Definition: vgl_polygon.h:81
Type min_x() const
Get min x.
Definition: vgl_box_2d.h:132
vgl_point_3d< Type > p(unsigned i) const
Direction vector in Euclidean 2D space, templated by type of element.
Definition: vgl_fwd.h:12
void add_point_with_normal(vgl_point_3d< Type > const &p, vgl_vector_3d< Type > const &normal)
incrementally grow points and normals duplicate pairs are allowed.
vgl_vector_3d< Type > direction() const
T a() const
Return x coefficient.
Definition: vgl_plane_3d.h:89
vgl_point_3d< Type > point2() const
Type min_z() const
Get min z.
Definition: vgl_box_3d.h:128
T y() const
Definition: vgl_vector_2d.h:36
direction vector in Euclidean 3D space
Contains class to represent a cartesian 3D bounding box.
Type c() const
Parameter c of line a*x + b*y + c = 0.
bool concurrent(l const &l1, l const &l2, l const &l3)
Are three lines concurrent, i.e., do they pass through a common point?.
bool contains(const vgl_point_3d< Type > &p) const
Check if point p is on the line.
vgl_point_2d< Type > point2() const
The other end-point of the line segment.
vgl_vector_3d< Type > direction() const
Return the direction vector of this line (not normalised - but perhaps it should be,...
A 3-d ray defined by an origin and a direction vector.
Type max_z() const
Get max z.
Definition: vgl_box_3d.h:135
bool contains(vgl_point_2d< Type > const &p) const
Return true iff the point p is inside this box.
Definition: vgl_box_2d.hxx:347
vgl_point_3d< T > vgl_intersection(const std::vector< vgl_plane_3d< T > > &p)
Return the intersection point of vector of planes.
double length(v const &a)
Return the length of a vector.
Definition: vgl_vector_2d.h:94
Type & z()
Definition: vgl_point_3d.h:73
A class to hold a non-homogeneous representation of a 3D line.
Definition: vgl_fwd.h:17
Type max_y() const
Get max y.
Definition: vgl_box_3d.h:133
#define v
Definition: vgl_vector_2d.h:74
Set of closest-point functions.
T b() const
Return y coefficient.
Definition: vgl_plane_3d.h:92
vgl_point_3d< Type > min_point() const
Return lower left corner of box.
Definition: vgl_box_3d.hxx:326
Type min_x() const
Get min x.
Definition: vgl_box_3d.h:124
line segment in 3D nonhomogeneous space
vgl_point_2d< T > vgl_closest_point(vgl_line_2d< T > const &l, vgl_point_2d< T > const &p)
Return the point on the given line closest to the given point.
double length() const
Return the length of this vector.
void set(Type px, Type py)
Set x and y.
Definition: vgl_point_2d.h:79
T cross_product(v const &a, v const &b)
cross product of two vectors (area of enclosed parallellogram).
bool has_normals() const
accessors.
T y() const
Definition: vgl_vector_3d.h:37
Represents a Euclidean 2D line.
Definition: vgl_fwd.h:16
vgl_point_3d< Type > point_t(const double t) const
Return a point on the line defined by a scalar parameter t.
Type & y()
Definition: vgl_point_2d.h:72
vgl_point_3d< Type > point1() const
Return the first point representing this line.
Represents a Euclidean 3D plane.
Definition: vgl_fwd.h:23
Represents a 3D line segment using two points.
Definition: vgl_fwd.h:19
Type a() const
Parameter a of line a*x + b*y + c = 0.
Definition: vgl_line_2d.h:97
Represents a 3-d ray.
Definition: vgl_fwd.h:21
void add_point(vgl_point_3d< Type > const &p)
incrementally grow points, duplicate points are allowed.
T x() const
Definition: vgl_vector_3d.h:36
T d() const
Return constant coefficient.
Definition: vgl_plane_3d.h:98
T z() const
Definition: vgl_vector_3d.h:38
Contains class to represent a cartesian 2D bounding box.
vgl_point_3d< Type > origin() const
Accessors.
Definition: vgl_ray_3d.h:66
Type & x()
Definition: vgl_point_3d.h:71
Represents a 3-d line with position defined in the orthogonal plane passing through the origin.
Definition: vgl_fwd.h:20
Direction vector in Euclidean 3D space, templated by type of element.
Definition: vgl_fwd.h:13
Type height() const
Get height of this box (= y dimension).
Definition: vgl_box_3d.hxx:136
bool contains(vgl_point_3d< Type > const &p) const
Return true iff the point p is inside this box.
Definition: vgl_box_3d.hxx:406
vgl_point_3d< Type > max_point() const
Return upper right corner of box.
Definition: vgl_box_3d.hxx:333
Type b() const
Parameter b of line a*x + b*y + c = 0.
Definition: vgl_line_2d.h:99
T sqr_length(v const &a)
Return the squared length of a vector.
Definition: vgl_vector_2d.h:98
double vgl_distance(vgl_point_2d< T >const &p1, vgl_point_2d< T >const &p2)
return the distance between two points.
Definition: vgl_distance.h:104
Type min_y() const
Get min y.
Definition: vgl_box_2d.h:134
#define l
T x() const
Definition: vgl_vector_2d.h:35
vgl_point_3d< Type > point2() const
Return the second point representing this line.
Represents a cartesian 2D point.
Definition: vgl_area.h:7
void set(Type px, Type py, Type pz)
Set x, y and z.
Definition: vgl_point_3d.h:81
Type min_y() const
Get min y.
Definition: vgl_box_3d.h:126
Type c() const
Parameter c of line a*x + b*y + c = 0.
Definition: vgl_line_2d.h:101
void set(vgl_point_2d< Type > const &p1, vgl_point_2d< Type > const &p2)
Assignment.
bool contains(const vgl_point_3d< Type > &p) const
Check if point p is on the ray and lies in the positive ray direction.
Definition: vgl_ray_3d.hxx:16
a plane in 3D nonhomogeneous space
non-homogeneous 3D line, represented by 2 points.
Type width() const
Get width of this box (= x dimension).
Definition: vgl_box_3d.hxx:130
Represents a cartesian 3D box.
Definition: vgl_box_3d.h:65
Type max_y() const
Get max y.
Definition: vgl_box_2d.h:138
vgl_vector_3d< Type > direction() const
Return the direction vector of this line (not normalised - but perhaps it should be,...
Set of distance functions.
unsigned int num_sheets() const
Definition: vgl_polygon.h:116
Store a polygon.
Definition: vgl_area.h:6
vgl_point_3d< Type > point() const
Return the point on the line closest to the origin.
bool vgl_near_zero(double x)
Type max_x() const
Get max x.
Definition: vgl_box_2d.h:136
vgl_point_2d< Type > point1() const
One end-point of the line segment.
size_t npts() const
vgl_vector_3d< Type > direction() const
Definition: vgl_ray_3d.h:68
T c() const
Return z coefficient.
Definition: vgl_plane_3d.h:95
Type & y()
Definition: vgl_point_3d.h:72
Type & x()
Definition: vgl_point_2d.h:71
vgl_vector_3d< Type > n(unsigned i) const
Type max_x() const
Get max x.
Definition: vgl_box_3d.h:131