00001
00002 #ifndef vgl_closest_point_txx_
00003 #define vgl_closest_point_txx_
00004
00005
00006
00007
00008 #include "vgl_closest_point.h"
00009 #include <vgl/vgl_distance.h>
00010 #include <vgl/vgl_line_2d.h>
00011 #include <vgl/vgl_homg_line_2d.h>
00012 #include <vgl/vgl_point_2d.h>
00013 #include <vgl/vgl_point_3d.h>
00014 #include <vgl/vgl_homg_point_2d.h>
00015 #include <vgl/vgl_homg_point_3d.h>
00016 #include <vgl/vgl_plane_3d.h>
00017 #include <vgl/vgl_homg_plane_3d.h>
00018 #include <vgl/vgl_homg_line_3d_2_points.h>
00019 #include <vgl/vgl_line_3d_2_points.h>
00020 #include <vgl/vgl_line_segment_3d.h>
00021 #include <vgl/vgl_polygon.h>
00022 #include <vcl_cassert.h>
00023 #include <vcl_cmath.h>
00024
00025 template <class T>
00026 static inline T square(T x) { return x*x; }
00027
00028
00029
00030 const double SMALL_DOUBLE = 1e-12;
00031
00032
00033
00034
00035
00036
00037
00038 #ifdef VCL_BORLAND_55
00039 # define DIST_SQR_TO_LINE_SEG_2D( T, x1, y1, x2, y2, x, y ) \
00040 vgl_distance2_to_linesegment(T(x1), T(y1), T(x2), T(y2), T(x), T(y) );
00041 # define DIST_SQR_TO_LINE_SEG_3D( T, x1, y1, z1, x2, y2, z2, x, y, z ) \
00042 vgl_distance2_to_linesegment(T(x1), T(y1), T(z1), T(x2), T(y2), T(z2), T(x), T(y), T(z) );
00043 #else
00044 # define DIST_SQR_TO_LINE_SEG_2D( T, x1, y1, x2, y2, x, y ) \
00045 vgl_distance2_to_linesegment(x1, y1, x2, y2, x, y );
00046 # define DIST_SQR_TO_LINE_SEG_3D( T, x1, y1, z1, x2, y2, z2, x, y, z ) \
00047 vgl_distance2_to_linesegment(x1, y1, z1, x2, y2, z2, x, y, z );
00048 #endif
00049
00050
00051 template <class T>
00052 void vgl_closest_point_to_linesegment(T& ret_x, T& ret_y,
00053 T x1, T y1,
00054 T x2, T y2,
00055 T x0, T y0)
00056 {
00057
00058 T ddh = square(x2-x1) + square(y2-y1);
00059
00060
00061 T dd1 = square(x0-x1) + square(y0-y1);
00062 T dd2 = square(x0-x2) + square(y0-y2);
00063
00064
00065 if (dd2 > ddh + dd1) { ret_x=x1; ret_y=y1; return; }
00066
00067
00068 if (dd1 > ddh + dd2) { ret_x=x2; ret_y=y2; return; }
00069
00070
00071
00072
00073 T dx = x2-x1;
00074 T dy = y2-y1;
00075 double c = dx*dx+dy*dy;
00076 ret_x = T((dx*dx*x0+dy*dy*x1-dx*dy*(y1-y0))/c);
00077 ret_y = T((dx*dx*y1+dy*dy*y0-dx*dy*(x1-x0))/c);
00078 }
00079
00080 template <class T>
00081 void vgl_closest_point_to_linesegment(T& ret_x, T& ret_y, T& ret_z,
00082 T x1, T y1, T z1,
00083 T x2, T y2, T z2,
00084 T x, T y, T z)
00085 {
00086
00087 T ddh = square(x2-x1) + square(y2-y1) + square(z2-z1);
00088
00089
00090 T dd1 = square(x-x1) + square(y-y1) + square(z-z1);
00091 T dd2 = square(x-x2) + square(y-y2) + square(z-z2);
00092
00093
00094 if (dd2 > ddh + dd1) { ret_x=x1; ret_y=y1; ret_z=z1; return; }
00095
00096
00097 if (dd1 > ddh + dd2) { ret_x=x2; ret_y=y2; ret_z=z2; return; }
00098
00099
00100
00101 T a = x2-x1, b = y2-y1, c = z2-z1;
00102
00103
00104 double lambda = (a*(x-x1)+b*(y-y1)+c*(z-z1))/double(a*a+b*b+c*c);
00105 ret_x = x1+T(lambda*a); ret_y = y1+T(lambda*b); ret_z = z1+T(lambda*c);
00106 }
00107
00108 template <class T>
00109 int vgl_closest_point_to_non_closed_polygon(T& ret_x, T& ret_y,
00110 T const px[], T const py[], unsigned int n,
00111 T x, T y)
00112 {
00113 assert(n>1);
00114 double dd = DIST_SQR_TO_LINE_SEG_2D(T,px[0],py[0], px[1],py[1], x,y);
00115 int di = 0;
00116 for (unsigned i=1; i+1<n; ++i)
00117 {
00118 double nd = DIST_SQR_TO_LINE_SEG_2D(T,px[i],py[i], px[i+1],py[i+1], x,y);
00119 if (nd<dd) { dd=nd; di=i; }
00120 }
00121 vgl_closest_point_to_linesegment(ret_x,ret_y, px[di],py[di], px[di+1],py[di+1], x,y);
00122 return di;
00123 }
00124
00125 template <class T>
00126 int vgl_closest_point_to_non_closed_polygon(T& ret_x, T& ret_y, T& ret_z,
00127 T const px[], T const py[], T const pz[], unsigned int n,
00128 T x, T y, T z)
00129 {
00130 assert(n>1);
00131 double dd = DIST_SQR_TO_LINE_SEG_3D(T,px[0],py[0],pz[0], px[1],py[1],pz[1], x,y,z);
00132 int di = 0;
00133 for (unsigned i=1; i+1<n; ++i)
00134 {
00135 double nd = DIST_SQR_TO_LINE_SEG_3D(T,px[i],py[i],pz[i], px[i+1],py[i+1],pz[i+1], x,y,z);
00136 if (nd<dd) { dd=nd; di=i; }
00137 }
00138 vgl_closest_point_to_linesegment(ret_x,ret_y,ret_z, px[di],py[di],pz[di],
00139 px[di+1],py[di+1],pz[di+1], x,y,z);
00140 return di;
00141 }
00142
00143 template <class T>
00144 int vgl_closest_point_to_closed_polygon(T& ret_x, T& ret_y,
00145 T const px[], T const py[], unsigned int n,
00146 T x, T y)
00147 {
00148 assert(n>1);
00149 double dd = DIST_SQR_TO_LINE_SEG_2D(T,px[0],py[0], px[n-1],py[n-1], x,y);
00150 int di = -1;
00151 for (unsigned i=0; i+1<n; ++i)
00152 {
00153 double nd = DIST_SQR_TO_LINE_SEG_2D(T,px[i],py[i], px[i+1],py[i+1], x,y);
00154 if (nd<dd) { dd=nd; di=i; }
00155 }
00156 if (di == -1) di+=n,
00157 vgl_closest_point_to_linesegment(ret_x,ret_y, px[0],py[0], px[n-1],py[n-1], x,y);
00158 else
00159 vgl_closest_point_to_linesegment(ret_x,ret_y, px[di],py[di], px[di+1],py[di+1], x,y);
00160 return di;
00161 }
00162
00163 template <class T>
00164 int vgl_closest_point_to_closed_polygon(T& ret_x, T& ret_y, T& ret_z,
00165 T const px[], T const py[], T const pz[], unsigned int n,
00166 T x, T y, T z)
00167 {
00168 assert(n>1);
00169 double dd = DIST_SQR_TO_LINE_SEG_3D(T,px[0],py[0],pz[0], px[n-1],py[n-1],pz[n-1], x,y,z);
00170 int di = -1;
00171 for (unsigned i=0; i+1<n; ++i)
00172 {
00173 double nd = DIST_SQR_TO_LINE_SEG_3D(T,px[i],py[i],pz[i], px[i+1],py[i+1],pz[i+1], x,y,z);
00174 if (nd<dd) { dd=nd; di=i; }
00175 }
00176 if (di == -1) di+=n,
00177 vgl_closest_point_to_linesegment(ret_x,ret_y,ret_z, px[0],py[0],pz[0],
00178 px[n-1],py[n-1],pz[n-1], x,y,z);
00179 else
00180 vgl_closest_point_to_linesegment(ret_x,ret_y,ret_z, px[di],py[di],pz[di],
00181 px[di+1],py[di+1],pz[di+1], x,y,z);
00182 return di;
00183 }
00184
00185 template <class T>
00186 vgl_point_2d<T> vgl_closest_point_origin(vgl_line_2d<T> const& l)
00187 {
00188 T d = l.a()*l.a()+l.b()*l.b();
00189 return vgl_point_2d<T>(-l.a()*l.c()/d, -l.b()*l.c()/d);
00190 }
00191
00192 template <class T>
00193 vgl_homg_point_2d<T> vgl_closest_point_origin(vgl_homg_line_2d<T> const& l)
00194 {
00195 return vgl_homg_point_2d<T>(l.a()*l.c(), l.b()*l.c(),
00196 -l.a()*l.a()-l.b()*l.b());
00197 }
00198
00199 template <class T>
00200 vgl_point_3d<T> vgl_closest_point_origin(vgl_plane_3d<T> const& pl)
00201 {
00202 T d = pl.a()*pl.a()+pl.b()*pl.b()+pl.c()*pl.c();
00203 return vgl_point_3d<T>(-pl.a()*pl.d()/d, -pl.b()*pl.d()/d, -pl.c()*pl.d()/d);
00204 }
00205
00206 template <class T>
00207 vgl_homg_point_3d<T> vgl_closest_point_origin(vgl_homg_plane_3d<T> const& pl)
00208 {
00209 return vgl_homg_point_3d<T>(pl.a()*pl.d(), pl.b()*pl.d(), pl.c()*pl.d(),
00210 -pl.a()*pl.a()-pl.b()*pl.b()-pl.c()*pl.c());
00211 }
00212
00213 template <class T>
00214 vgl_homg_point_3d<T> vgl_closest_point_origin(vgl_homg_line_3d_2_points<T> const& l)
00215 {
00216 vgl_homg_point_3d<T> const& q = l.point_finite();
00217
00218
00219 T a = l.point_infinite().x(), b = l.point_infinite().y(), c = l.point_infinite().z(),
00220 d = a*a+b*b+c*c;
00221
00222
00223 T lambda = a*q.x()+b*q.y()+c*q.z();
00224 return vgl_homg_point_3d<T>(d*q.x()-lambda*a*q.w(), d*q.y()-lambda*b*q.w(), d*q.z()-lambda*c*q.w(), d*q.w());
00225 }
00226
00227 template <class T>
00228 vgl_point_3d<T> vgl_closest_point_origin(vgl_line_3d_2_points<T> const& l)
00229 {
00230 vgl_point_3d<T> const& q = l.point1();
00231
00232
00233 T a = l.point2().x()-q.x(), b = l.point2().y()-q.y(), c = l.point2().z()-q.z(),
00234 d = a*a+b*b+c*c;
00235
00236
00237 T lambda = (a*q.x()+b*q.y()+c*q.z())/d;
00238 return vgl_point_3d<T>(q.x()-lambda*a, q.y()-lambda*b, q.z()-lambda*c);
00239 }
00240
00241 template <class T>
00242 vgl_point_2d<T> vgl_closest_point(vgl_line_2d<T> const& l,
00243 vgl_point_2d<T> const& p)
00244 {
00245 T d = l.a()*l.a()+l.b()*l.b();
00246 assert(d!=0);
00247 return vgl_point_2d<T>((l.b()*l.b()*p.x()-l.a()*l.b()*p.y()-l.a()*l.c())/d,
00248 (l.a()*l.a()*p.y()-l.a()*l.b()*p.x()-l.b()*l.c())/d);
00249 }
00250
00251 template <class T>
00252 vgl_homg_point_2d<T> vgl_closest_point(vgl_homg_line_2d<T> const& l,
00253 vgl_homg_point_2d<T> const& p)
00254 {
00255 T d = l.a()*l.a()+l.b()*l.b();
00256 assert(d!=0);
00257 return vgl_homg_point_2d<T>(l.b()*l.b()*p.x()-l.a()*l.b()*p.y()-l.a()*l.c(),
00258 l.a()*l.a()*p.y()-l.a()*l.b()*p.x()-l.b()*l.c(),
00259 d);
00260 }
00261
00262 template <class T>
00263 vgl_point_3d<T> vgl_closest_point(vgl_plane_3d<T> const& l,
00264 vgl_point_3d<T> const& p)
00265 {
00266
00267
00268
00269 T d = l.a()*l.a()+l.b()*l.b()+l.c()*l.c();
00270 return vgl_point_3d<T>(((l.b()*l.b()+l.c()*l.c())*p.x()-l.a()*l.b()*p.y()-l.a()*l.c()*p.z()-l.a()*l.d())/d,
00271 ((l.a()*l.a()+l.c()*l.c())*p.y()-l.a()*l.b()*p.x()-l.b()*l.c()*p.z()-l.b()*l.d())/d,
00272 ((l.a()*l.a()+l.b()*l.b())*p.z()-l.a()*l.c()*p.x()-l.b()*l.c()*p.y()-l.c()*l.d())/d);
00273 }
00274
00275 template <class T>
00276 vgl_homg_point_3d<T> vgl_closest_point(vgl_homg_plane_3d<T> const& l,
00277 vgl_homg_point_3d<T> const& p)
00278 {
00279 return vgl_homg_point_3d<T>((l.b()*l.b()+l.c()*l.c())*p.x()-l.a()*l.b()*p.y()-l.a()*l.c()*p.z()-l.a()*l.d(),
00280 (l.a()*l.a()+l.c()*l.c())*p.y()-l.a()*l.b()*p.x()-l.b()*l.c()*p.z()-l.b()*l.d(),
00281 (l.a()*l.a()+l.b()*l.b())*p.z()-l.a()*l.c()*p.x()-l.b()*l.c()*p.y()-l.c()*l.d(),
00282 l.a()*l.a()+l.b()*l.b()+l.c()*l.c());
00283 }
00284
00285 template <class T>
00286 vgl_point_2d<T> vgl_closest_point(vgl_polygon<T> const& poly,
00287 vgl_point_2d<T> const& point,
00288 bool closed)
00289 {
00290 T x=point.x(), y=point.y();
00291 double dd = DIST_SQR_TO_LINE_SEG_2D(T,poly[0][0].x(),poly[0][0].y(), poly[0][1].x(),poly[0][1].y(), x,y);
00292 int si = 0, di = 0;
00293 for ( unsigned int s=0; s < poly.num_sheets(); ++s )
00294 {
00295 unsigned int n = poly[s].size();
00296 assert( n > 1 );
00297 for (unsigned i=0; i+1<n; ++i)
00298 {
00299 double nd = DIST_SQR_TO_LINE_SEG_2D(T,poly[s][i].x(),poly[s][i].y(), poly[s][i+1].x(),poly[s][i+1].y(), x,y);
00300 if (nd<dd) { dd=nd; di=i; si=s; }
00301 }
00302 if (closed)
00303 {
00304 double nd = DIST_SQR_TO_LINE_SEG_2D(T,poly[s][0].x(),poly[s][0].y(), poly[s][n-1].x(),poly[s][n-1].y(), x,y);
00305 if (nd<dd) { dd=nd; di=-1; si=s; }
00306 }
00307 }
00308 T ret_x, ret_y;
00309 unsigned int n = poly[si].size();
00310 if (di == -1)
00311 vgl_closest_point_to_linesegment(ret_x,ret_y, poly[si][0].x(),poly[si][0].y(), poly[si][n-1].x(),poly[si][n-1].y(), x,y);
00312 else
00313 vgl_closest_point_to_linesegment(ret_x,ret_y, poly[si][di].x(),poly[si][di].y(), poly[si][di+1].x(),poly[si][di+1].y(), x,y);
00314 return vgl_point_2d<T>(T(ret_x), T(ret_y));
00315 }
00316
00317 template <class T>
00318 vcl_pair<vgl_homg_point_3d<T>, vgl_homg_point_3d<T> >
00319 vgl_closest_points(vgl_homg_line_3d_2_points<T> const& line1,
00320 vgl_homg_line_3d_2_points<T> const& line2)
00321 {
00322 vcl_pair<vgl_homg_point_3d<T>, vgl_homg_point_3d<T> > ret;
00323
00324 if ((line1==line2)||(line1.point_infinite()==line2.point_infinite()))
00325 {
00326 ret.first = ret.second = line1.point_infinite();
00327 }
00328
00329 else if (concurrent(line1, line2))
00330 {
00331 ret.first = ret.second = intersection(line1, line2);
00332 }
00333
00334
00335 else
00336 {
00337
00338 vgl_homg_point_3d<T> p21 = line1.point_infinite();
00339 vgl_homg_point_3d<T> p43 = line2.point_infinite();
00340 vgl_vector_3d<T> p13 = line1.point_finite()-line2.point_finite();
00341
00342 T d1343 = p13.x() * p43.x() + p13.y() * p43.y() + p13.z() * p43.z();
00343 T d4321 = p43.x() * p21.x() + p43.y() * p21.y() + p43.z() * p21.z();
00344 T d1321 = p13.x() * p21.x() + p13.y() * p21.y() + p13.z() * p21.z();
00345 T d4343 = p43.x() * p43.x() + p43.y() * p43.y() + p43.z() * p43.z();
00346 T d2121 = p21.x() * p21.x() + p21.y() * p21.y() + p21.z() * p21.z();
00347
00348 T denom = d2121 * d4343 - d4321 * d4321;
00349 T numer = d1343 * d4321 - d1321 * d4343;
00350
00351
00352
00353
00354 T mu_n = d1343 * denom + d4321 * numer;
00355 T mu_d = d4343 * denom;
00356
00357 ret.first.set(denom*line1.point_finite().x()+numer*p21.x(),
00358 denom*line1.point_finite().y()+numer*p21.y(),
00359 denom*line1.point_finite().z()+numer*p21.z(),
00360 denom);
00361 ret.second.set(mu_d*line2.point_finite().x()+mu_n*p43.x(),
00362 mu_d*line2.point_finite().y()+mu_n*p43.y(),
00363 mu_d*line2.point_finite().z()+mu_n*p43.z(),
00364 mu_d);
00365 }
00366 return ret;
00367 }
00368
00369 template <class T>
00370 vgl_homg_point_3d<T> vgl_closest_point(vgl_homg_line_3d_2_points<T> const& l,
00371 vgl_homg_point_3d<T> const& p)
00372 {
00373
00374 if (p.w() == 0) return l.point_infinite();
00375 vgl_homg_point_3d<T> const& q = l.point_finite();
00376 vgl_vector_3d<T> v = p-q;
00377
00378
00379 T a = l.point_infinite().x(), b = l.point_infinite().y(), c = l.point_infinite().z(),
00380 d = a*a+b*b+c*c;
00381
00382
00383 T lambda = a*v.x()+b*v.y()+c*v.z();
00384 return vgl_homg_point_3d<T>(d*q.x()+lambda*a*q.w(), d*q.y()+lambda*b*q.w(), d*q.z()+lambda*c*q.w(), d*q.w());
00385 }
00386
00387 template <class T>
00388 double vgl_closest_point_t(vgl_line_3d_2_points<T> const& l,
00389 vgl_point_3d<T> const& p)
00390 {
00391 vgl_point_3d<T> const& q = l.point1();
00392 vgl_vector_3d<T> v = p-q;
00393
00394
00395 double a = l.point2().x()-q.x(), b = l.point2().y()-q.y(),
00396 c = l.point2().z()-q.z(), d = a*a+b*b+c*c;
00397
00398
00399 double lambda = (a*v.x()+b*v.y()+c*v.z())/d;
00400 return lambda;
00401 }
00402
00403
00404 template <class T>
00405 vgl_point_3d<T> vgl_closest_point(vgl_line_3d_2_points<T> const& l,
00406 vgl_point_3d<T> const& p)
00407 {
00408 vgl_point_3d<T> const& q = l.point1();
00409 vgl_vector_3d<T> v = p-q;
00410
00411
00412 T a = l.point2().x()-q.x(), b = l.point2().y()-q.y(), c = l.point2().z()-q.z(),
00413 d = a*a+b*b+c*c;
00414
00415
00416 T lambda = (a*v.x()+b*v.y()+c*v.z())/d;
00417 return vgl_point_3d<T>(q.x()+lambda*a, q.y()+lambda*b, q.z()+lambda*c);
00418 }
00419
00420
00421 template <class T>
00422 vcl_pair<vgl_point_3d<T>, vgl_point_3d<T> >
00423 vgl_closest_points(const vgl_line_3d_2_points<T>& l1,
00424 const vgl_line_3d_2_points<T>& l2,
00425 bool* unique)
00426 {
00427 vcl_pair<vgl_point_3d<T>, vgl_point_3d<T> > ret;
00428
00429
00430
00431
00432 vgl_vector_3d<T> u = l1.direction();
00433 vgl_vector_3d<T> v = l2.direction();
00434
00435
00436 vgl_vector_3d<T> w = l1.point1() - l2.point1();
00437
00438 double a = dot_product(u,u);
00439 double b = dot_product(u,v);
00440 double c = dot_product(v,v);
00441 double d = dot_product(u,w);
00442 double e = dot_product(v,w);
00443
00444
00445 double denom = a*c - b*b;
00446 if (denom<0.0) denom = 0.0;
00447 if (denom>SMALL_DOUBLE)
00448 {
00449 double s = (b*e - c*d) / denom;
00450 double t = (a*e - b*d) / denom;
00451
00452 ret.first = l1.point_t(s);
00453 ret.second = l2.point_t(t);
00454 if (unique) *unique = true;
00455 }
00456 else
00457 {
00458
00459
00460 double s = 0.0;
00461 double t = (b>c ? d/b : e/c);
00462 ret.first = l1.point_t(s);
00463 ret.second = l2.point_t(t);
00464 if (unique) *unique = false;
00465 }
00466
00467 return ret;
00468 }
00469
00470
00471
00472 template <class T>
00473 vcl_pair<vgl_point_3d<T>, vgl_point_3d<T> >
00474 vgl_closest_points(vgl_line_segment_3d<T> const& l1,
00475 vgl_line_segment_3d<T> const& l2,
00476 bool* unique)
00477 {
00478 vcl_pair<vgl_point_3d<T>, vgl_point_3d<T> > ret;
00479
00480
00481
00482
00483 vgl_vector_3d<T> u = l1.direction();
00484 vgl_vector_3d<T> v = l2.direction();
00485
00486
00487 vgl_vector_3d<T> w = l1.point1() - l2.point1();
00488
00489 double a = dot_product(u,u); assert(a>0.0);
00490 double b = dot_product(u,v);
00491 double c = dot_product(v,v); assert(c>0.0);
00492 double d = dot_product(u,w);
00493 double e = dot_product(v,w);
00494
00495
00496 double denom = a*c - b*b;
00497 assert(denom>=0.0);
00498
00499
00500
00501
00502
00503
00504
00505 double s_numer;
00506 double s_denom = denom;
00507 double t_numer;
00508 double t_denom = denom;
00509
00510 if (denom < SMALL_DOUBLE)
00511 {
00512
00513 s_numer = 0.0;
00514 s_denom = 1.0;
00515 t_numer = e;
00516 t_denom = c;
00517 if (unique) *unique = false;
00518 }
00519 else
00520 {
00521
00522 s_numer = (b*e - c*d);
00523 t_numer = (a*e - b*d);
00524 if (s_numer < 0.0)
00525 {
00526
00527 s_numer = 0.0;
00528 t_numer = e;
00529 t_denom = c;
00530 }
00531 else if (s_numer > s_denom)
00532 {
00533
00534 s_numer = s_denom;
00535 t_numer = e + b;
00536 t_denom = c;
00537 }
00538 if (unique) *unique = true;
00539 }
00540
00541 if (t_numer < 0.0)
00542 {
00543
00544 t_numer = 0.0;
00545
00546
00547 if (-d < 0.0)
00548 s_numer = 0.0;
00549 else if (-d > a)
00550 s_numer = s_denom;
00551 else
00552 {
00553 s_numer = -d;
00554 s_denom = a;
00555 }
00556 }
00557 else if (t_numer > t_denom)
00558 {
00559
00560 t_numer = t_denom;
00561
00562
00563 if ((-d + b) < 0.0)
00564 s_numer = 0.0;
00565 else if ((-d + b) > a)
00566 s_numer = s_denom;
00567 else
00568 {
00569 s_numer = (-d + b);
00570 s_denom = a;
00571 }
00572 }
00573
00574
00575 double s = (vcl_abs(s_numer) < SMALL_DOUBLE ? 0.0 : s_numer / s_denom);
00576 double t = (vcl_abs(t_numer) < SMALL_DOUBLE ? 0.0 : t_numer / t_denom);
00577
00578
00579
00580 if (unique && ! *unique)
00581 {
00582 if ((s==0.0 || s==1.0) && (t==0.0 || t==1.0))
00583 *unique = true;
00584 }
00585
00586 ret.first = l1.point_t(s);
00587 ret.second = l2.point_t(t);
00588
00589 return ret;
00590 }
00591
00592
00593 #undef DIST_SQR_TO_LINE_SEG_2D
00594 #undef DIST_SQR_TO_LINE_SEG_3D
00595
00596
00597 #undef VGL_CLOSEST_POINT_INSTANTIATE
00598 #define VGL_CLOSEST_POINT_INSTANTIATE(T) \
00599 template void vgl_closest_point_to_linesegment(T&,T&,T,T,T,T,T,T); \
00600 template void vgl_closest_point_to_linesegment(T&,T&,T&,T,T,T,T,T,T,T,T,T); \
00601 template int vgl_closest_point_to_non_closed_polygon(T&,T&,T const[],T const[],unsigned int,T,T); \
00602 template int vgl_closest_point_to_non_closed_polygon(T&,T&,T&,T const[],T const[],T const[],unsigned int,T,T,T); \
00603 template int vgl_closest_point_to_closed_polygon(T&,T&,T const[],T const[],unsigned int,T,T); \
00604 template int vgl_closest_point_to_closed_polygon(T&,T&,T&,T const[],T const[],T const[],unsigned int,T,T,T); \
00605 template vgl_point_2d<T > vgl_closest_point_origin(vgl_line_2d<T >const& l); \
00606 template vgl_point_3d<T > vgl_closest_point_origin(vgl_plane_3d<T > const& pl); \
00607 template vgl_point_3d<T > vgl_closest_point_origin(vgl_line_3d_2_points<T > const& l); \
00608 template vgl_homg_point_2d<T > vgl_closest_point_origin(vgl_homg_line_2d<T >const& l); \
00609 template vgl_homg_point_3d<T > vgl_closest_point_origin(vgl_homg_plane_3d<T > const& pl); \
00610 template vgl_homg_point_3d<T > vgl_closest_point_origin(vgl_homg_line_3d_2_points<T > const& l); \
00611 template vgl_point_2d<T > vgl_closest_point(vgl_line_2d<T >const&,vgl_point_2d<T >const&); \
00612 template vgl_point_2d<T > vgl_closest_point(vgl_point_2d<T >const&,vgl_line_2d<T >const&); \
00613 template double vgl_closest_point_t(vgl_line_3d_2_points<T >const&,vgl_point_3d<T >const&); \
00614 template vgl_point_3d<T > vgl_closest_point(vgl_line_3d_2_points<T >const&,vgl_point_3d<T >const&); \
00615 template vgl_homg_point_2d<T > vgl_closest_point(vgl_homg_line_2d<T >const&,vgl_homg_point_2d<T >const&); \
00616 template vgl_homg_point_2d<T > vgl_closest_point(vgl_homg_point_2d<T >const&,vgl_homg_line_2d<T >const&); \
00617 template vgl_point_3d<T > vgl_closest_point(vgl_plane_3d<T >const&,vgl_point_3d<T >const&); \
00618 template vgl_point_3d<T > vgl_closest_point(vgl_point_3d<T >const&,vgl_plane_3d<T >const&); \
00619 template vgl_homg_point_3d<T > vgl_closest_point(vgl_homg_plane_3d<T >const&,vgl_homg_point_3d<T >const&); \
00620 template vgl_homg_point_3d<T > vgl_closest_point(vgl_homg_point_3d<T >const&,vgl_homg_plane_3d<T >const&); \
00621 template vgl_point_2d<T > vgl_closest_point(vgl_polygon<T >const&,vgl_point_2d<T >const&,bool); \
00622 template vcl_pair<vgl_homg_point_3d<T >,vgl_homg_point_3d<T > > \
00623 vgl_closest_points(vgl_homg_line_3d_2_points<T >const&,vgl_homg_line_3d_2_points<T >const&); \
00624 template vgl_homg_point_3d<T > vgl_closest_point(vgl_homg_line_3d_2_points<T >const&,vgl_homg_point_3d<T >const&); \
00625 template vgl_homg_point_3d<T > vgl_closest_point(vgl_homg_point_3d<T >const&,vgl_homg_line_3d_2_points<T >const&); \
00626 template vcl_pair<vgl_point_3d<T >,vgl_point_3d<T > > \
00627 vgl_closest_points(vgl_line_3d_2_points<T >const&, vgl_line_3d_2_points<T >const&, bool*); \
00628 template vcl_pair<vgl_point_3d<T >,vgl_point_3d<T > > \
00629 vgl_closest_points(vgl_line_segment_3d<T >const&, vgl_line_segment_3d<T >const&, bool*)
00630
00631 #endif // vgl_closest_point_txx_