2 #ifndef vgl_closest_point_hxx_ 3 #define vgl_closest_point_hxx_ 7 # include <vcl_msvc_warnings.h> 36 static inline T square(T x) {
return x*x; }
48 #define DIST_SQR_TO_LINE_SEG_2D( T, x1, y1, x2, y2, x, y ) \ 49 vgl_distance2_to_linesegment(x1, y1, x2, y2, x, y ); 50 #define DIST_SQR_TO_LINE_SEG_3D( T, x1, y1, z1, x2, y2, z2, x, y, z ) \ 51 vgl_distance2_to_linesegment(x1, y1, z1, x2, y2, z2, x, y, z ); 61 T ddh = square(x2-x1) + square(y2-y1);
64 T dd1 = square(x0-x1) + square(y0-y1);
65 T dd2 = square(x0-x2) + square(y0-y2);
68 if (dd2 > ddh + dd1) { ret_x=x1; ret_y=y1;
return; }
71 if (dd1 > ddh + dd2) { ret_x=x2; ret_y=y2;
return; }
78 double c = dx*dx+dy*dy;
79 ret_x = T((dx*dx*x0+dy*dy*x1-dx*dy*(y1-y0))/c);
80 ret_y = T((dx*dx*y1+dy*dy*y0-dx*dy*(x1-x0))/c);
90 T ddh = square(x2-x1) + square(y2-y1) + square(z2-z1);
93 T dd1 = square(x-x1) + square(y-y1) + square(z-z1);
94 T dd2 = square(x-x2) + square(y-y2) + square(z-z2);
97 if (dd2 > ddh + dd1) { ret_x=x1; ret_y=y1; ret_z=z1;
return; }
100 if (dd1 > ddh + dd2) { ret_x=x2; ret_y=y2; ret_z=z2;
return; }
104 T a = x2-x1, b = y2-y1, c = z2-z1;
107 double lambda = (a*(x-x1)+b*(y-y1)+c*(z-z1))/double(a*a+b*b+c*c);
108 ret_x = x1+T(lambda*a); ret_y = y1+T(lambda*b); ret_z = z1+T(lambda*c);
113 T
const px[], T
const py[],
unsigned int n,
119 for (
unsigned i=1; i+1<n; ++i)
122 if (nd<dd) { dd=nd; di=i; }
130 T
const px[], T
const py[], T
const pz[],
unsigned int n,
136 for (
unsigned i=1; i+1<n; ++i)
139 if (nd<dd) { dd=nd; di=i; }
142 px[di+1],py[di+1],pz[di+1], x,y,z);
148 T
const px[], T
const py[],
unsigned int n,
154 for (
unsigned i=0; i+1<n; ++i)
157 if (nd<dd) { dd=nd; di=i; }
168 T
const px[], T
const py[], T
const pz[],
unsigned int n,
174 for (
unsigned i=0; i+1<n; ++i)
177 if (nd<dd) { dd=nd; di=i; }
181 px[n-1],py[n-1],pz[n-1], x,y,z);
184 px[di+1],py[di+1],pz[di+1], x,y,z);
191 T d =
l.a()*
l.a()+
l.b()*
l.b();
199 -
l.a()*
l.a()-
l.b()*
l.b());
205 T d = pl.
a()*pl.
a()+pl.
b()*pl.
b()+pl.
c()*pl.
c();
213 -pl.
a()*pl.
a()-pl.
b()*pl.
b()-pl.
c()*pl.
c());
222 T a =
l.point_infinite().x(), b =
l.point_infinite().y(), c =
l.point_infinite().z(),
226 T lambda = a*q.
x()+b*q.
y()+c*q.
z();
236 T a =
l.point2().x()-q.
x(), b =
l.point2().y()-q.
y(), c =
l.point2().z()-q.
z(),
240 T lambda = (a*q.
x()+b*q.
y()+c*q.
z())/d;
248 T d =
l.a()*
l.a()+
l.b()*
l.b();
251 (
l.a()*
l.a()*p.
y()-
l.a()*
l.b()*p.
x()-
l.b()*
l.c())/d);
258 T d =
l.a()*
l.a()+
l.b()*
l.b();
261 l.a()*
l.a()*p.
y()-
l.a()*
l.b()*p.
x()-
l.b()*
l.c(),
272 T d =
l.a()*
l.a()+
l.b()*
l.b()+
l.c()*
l.c();
274 ((
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,
275 ((
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);
283 (
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(),
284 (
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(),
285 l.a()*
l.a()+
l.b()*
l.b()+
l.c()*
l.c());
293 T x=point.
x(), y=point.
y();
296 for (
unsigned int s=0; s < poly.
num_sheets(); ++s )
298 unsigned int n = (
unsigned int)(poly[s].size());
300 for (
unsigned i=0; i+1<n; ++i)
303 if (nd<dd) { dd=nd; di=i; si=s; }
308 if (nd<dd) { dd=nd; di=-1; si=s; }
312 unsigned int n = (
unsigned int)(poly[si].size());
345 T d1343 = p13.
x() * p43.
x() + p13.
y() * p43.
y() + p13.
z() * p43.
z();
346 T d4321 = p43.
x() * p21.
x() + p43.
y() * p21.
y() + p43.
z() * p21.
z();
347 T d1321 = p13.
x() * p21.
x() + p13.
y() * p21.
y() + p13.
z() * p21.
z();
348 T d4343 = p43.
x() * p43.
x() + p43.
y() * p43.
y() + p43.
z() * p43.
z();
349 T d2121 = p21.
x() * p21.
x() + p21.
y() * p21.
y() + p21.
z() * p21.
z();
351 T denom = d2121 * d4343 - d4321 * d4321;
352 T numer = d1343 * d4321 - d1321 * d4343;
357 T mu_n = d1343 * denom + d4321 * numer;
358 T mu_d = d4343 * denom;
377 if (p.
w() == 0)
return l.point_infinite();
382 T a =
l.point_infinite().x(), b =
l.point_infinite().y(), c =
l.point_infinite().z(),
386 T lambda = a*
v.x()+b*
v.y()+c*
v.z();
387 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());
398 double a =
l.point2().x()-q.x(), b =
l.point2().y()-q.y(),
399 c =
l.point2().z()-q.z(), d = a*a+b*b+c*c;
402 double lambda = (a*
v.x()+b*
v.y()+c*
v.z())/d;
415 T a =
l.point2().x()-q.x(), b =
l.point2().y()-q.y(), c =
l.point2().z()-q.z(),
419 T lambda = (a*
v.x()+b*
v.y()+c*
v.z())/d;
420 return vgl_point_3d<T>(q.x()+lambda*a, q.y()+lambda*b, q.z()+lambda*c);
448 double denom = a*c - b*b;
449 if (denom<0.0) denom = 0.0;
452 double s = (b*e - c*d) / denom;
453 double t = (a*e - b*d) / denom;
457 if (unique) *unique =
true;
464 double t = (b>c ? d/b : e/c);
467 if (unique) *unique =
false;
506 double denom = a*c - b*b;
516 double s_denom = denom;
518 double t_denom = denom;
527 if (unique) *unique =
false;
532 s_numer = (b*e - c*d);
533 t_numer = (a*e - b*d);
541 else if (s_numer > s_denom)
548 if (unique) *unique =
true;
567 else if (t_numer > t_denom)
575 else if ((-d + b) > a)
585 double s = (std::abs(s_numer) <
SMALL_DOUBLE ? 0.0 : s_numer / s_denom);
586 double t = (std::abs(t_numer) <
SMALL_DOUBLE ? 0.0 : t_numer / t_denom);
590 if (unique && ! *unique)
592 if ((s==0.0 || s==1.0) && (t==0.0 || t==1.0))
608 l.point1().x(),
l.point1().y(),
609 l.point2().x(),
l.point2().y(),
620 l.point1().x(),
l.point1().y(),
l.point1().z(),
621 l.point2().x(),
l.point2().y(),
l.point2().z(),
622 p.
x(), p.
y(), p.
z());
630 double vx = static_cast<double>(p.
x()-c.
x()), vy = static_cast<double>(p.
y()-c.
y()),
631 vz = static_cast<double>(p.
z()-c.
z());
632 double radius = std::sqrt(vx*vx + vy*vy + vz*vz);
633 T azimuth = static_cast<T>(std::atan2(vy, vx));
634 T elevation = static_cast<T>(std::acos(vz/radius));
643 unsigned n = ptset.
npts();
648 for(
unsigned i = 0; i<n; ++i){
650 double d = (pi-p).
length();
661 if(std::numeric_limits<T>::is_integer){
664 vgl_point_3d<double> pcd(static_cast<double>(pc.
x()), static_cast<double>(pc.
y()), static_cast<double>(pc.
z()));
666 vgl_vector_3d<double> normd(static_cast<double>(norm.
x()),static_cast<double>(norm.
y()),static_cast<double>(norm.
z()));
669 T dpd = static_cast<T>((pc_planed-pcd).
length());
672 vgl_point_3d<T> pc_plane_T(static_cast<T>(pc_planed.
x()), static_cast<T>(pc_planed.
y()), static_cast<T>(pc_planed.
z()));
677 T dp = static_cast<T>((pc_plane-p).
length());
686 std::vector<vgl_point_3d<T> >
const& knots = cspl.
const_knots();
688 double min_dist = std::numeric_limits<double>::max();
689 unsigned min_index = 0;
690 for(
unsigned i = 0; i<n; ++i){
697 unsigned start_index = 0, end_index = 0;
715 }
else if(min_index == n-1){
734 start_index = min_index;
735 end_index = min_index+1;
737 start_index = min_index-1;
738 end_index = min_index;
742 T sindx = static_cast<T>(start_index), eindx = static_cast<T>(end_index);
745 double tolerance =
vgl_distance(knots[start_index],knots[end_index])/T(1000);
746 T t = (sindx+ eindx)/T(2);
749 unsigned max_iter = 100;
750 while(first || ((std::fabs(dcm - dcm0)>tolerance)&&iter<max_iter)){
753 T tp = (t+eindx)/T(2), tm = (t+sindx)/T(2);
768 std::cout <<
" Warning: exceeded num interations in closest point cubic_spline_3d\n";
772 #undef DIST_SQR_TO_LINE_SEG_2D 773 #undef DIST_SQR_TO_LINE_SEG_3D 775 #undef VGL_CLOSEST_POINT_INSTANTIATE 776 #define VGL_CLOSEST_POINT_INSTANTIATE(T) \ 777 template void vgl_closest_point_to_linesegment(T&,T&,T,T,T,T,T,T); \ 778 template void vgl_closest_point_to_linesegment(T&,T&,T&,T,T,T,T,T,T,T,T,T); \ 779 template int vgl_closest_point_to_non_closed_polygon(T&,T&,T const[],T const[],unsigned int,T,T); \ 780 template int vgl_closest_point_to_non_closed_polygon(T&,T&,T&,T const[],T const[],T const[],unsigned int,T,T,T); \ 781 template int vgl_closest_point_to_closed_polygon(T&,T&,T const[],T const[],unsigned int,T,T); \ 782 template int vgl_closest_point_to_closed_polygon(T&,T&,T&,T const[],T const[],T const[],unsigned int,T,T,T); \ 783 template vgl_point_2d<T > vgl_closest_point_origin(vgl_line_2d<T >const& l); \ 784 template vgl_point_3d<T > vgl_closest_point_origin(vgl_plane_3d<T > const& pl); \ 785 template vgl_point_3d<T > vgl_closest_point_origin(vgl_line_3d_2_points<T > const& l); \ 786 template vgl_homg_point_2d<T > vgl_closest_point_origin(vgl_homg_line_2d<T >const& l); \ 787 template vgl_homg_point_3d<T > vgl_closest_point_origin(vgl_homg_plane_3d<T > const& pl); \ 788 template vgl_homg_point_3d<T > vgl_closest_point_origin(vgl_homg_line_3d_2_points<T > const& l); \ 789 template vgl_point_2d<T > vgl_closest_point(vgl_line_2d<T >const&,vgl_point_2d<T >const&); \ 790 template vgl_point_2d<T > vgl_closest_point(vgl_point_2d<T >const&,vgl_line_2d<T >const&); \ 791 template double vgl_closest_point_t(vgl_line_3d_2_points<T >const&,vgl_point_3d<T >const&); \ 792 template vgl_point_3d<T > vgl_closest_point(vgl_line_3d_2_points<T >const&,vgl_point_3d<T >const&); \ 793 template vgl_point_3d<T > vgl_closest_point(vgl_point_3d<T > const& p,vgl_ray_3d<T > const& r); \ 794 template vgl_homg_point_2d<T > vgl_closest_point(vgl_homg_line_2d<T >const&,vgl_homg_point_2d<T >const&); \ 795 template vgl_homg_point_2d<T > vgl_closest_point(vgl_homg_point_2d<T >const&,vgl_homg_line_2d<T >const&); \ 796 template vgl_point_3d<T > vgl_closest_point(vgl_plane_3d<T >const&,vgl_point_3d<T >const&); \ 797 template vgl_point_3d<T > vgl_closest_point(vgl_point_3d<T >const&,vgl_plane_3d<T >const&); \ 798 template vgl_homg_point_3d<T > vgl_closest_point(vgl_homg_plane_3d<T >const&,vgl_homg_point_3d<T >const&); \ 799 template vgl_homg_point_3d<T > vgl_closest_point(vgl_homg_point_3d<T >const&,vgl_homg_plane_3d<T >const&); \ 800 template vgl_point_2d<T > vgl_closest_point(vgl_polygon<T >const&,vgl_point_2d<T >const&,bool); \ 801 template std::pair<vgl_homg_point_3d<T >,vgl_homg_point_3d<T > > \ 802 vgl_closest_points(vgl_homg_line_3d_2_points<T >const&,vgl_homg_line_3d_2_points<T >const&); \ 803 template vgl_homg_point_3d<T > vgl_closest_point(vgl_homg_line_3d_2_points<T >const&,vgl_homg_point_3d<T >const&); \ 804 template vgl_homg_point_3d<T > vgl_closest_point(vgl_homg_point_3d<T >const&,vgl_homg_line_3d_2_points<T >const&); \ 805 template std::pair<vgl_point_3d<T >,vgl_point_3d<T > > \ 806 vgl_closest_points(vgl_line_3d_2_points<T >const&, vgl_line_3d_2_points<T >const&, bool*); \ 807 template std::pair<vgl_point_3d<T >,vgl_point_3d<T > > \ 808 vgl_closest_points(vgl_line_segment_3d<T >const&, vgl_line_segment_3d<T >const&, bool*); \ 809 template vgl_point_2d<T > vgl_closest_point(vgl_line_segment_2d<T > const&, vgl_point_2d<T > const&); \ 810 template vgl_point_3d<T > vgl_closest_point(vgl_line_segment_3d<T > const&, vgl_point_3d<T > const&); \ 811 template vgl_point_3d<T> vgl_closest_point(vgl_sphere_3d<T> const& s, vgl_point_3d<T> const& p); \ 812 template vgl_point_3d<T> vgl_closest_point(vgl_pointset_3d<T> const& ptset, vgl_point_3d<T> const& p, T dist); \ 813 template vgl_point_3d<T> vgl_closest_point(vgl_cubic_spline_3d<T> const& cspl, vgl_point_3d<T> const& p) 814 #endif // vgl_closest_point_hxx_ A 3-d cubic spline curve defined by a set of knots (3-d points)
homogeneous plane in 3D projective space
point in projective 3D space
T dot_product(v const &a, v const &b)
dot product or inner product of two vectors.
vgl_point_3d< Type > point1() const
a point in 2D nonhomogeneous space
void vgl_closest_point_to_linesegment(T &ret_x, T &ret_y, T x1, T y1, T x2, T y2, T x0, T y0)
Closest point to (x,y) on the line segment (x1,y1)-(x2,y2).
vgl_point_3d< Type > point_t(const double t) const
Return a point on the line defined by a scalar parameter t such that t=0.0 at point1 and t=1....
Represents a homogeneous 2D line.
vgl_point_3d< Type > p(unsigned i) const
std::vector< vgl_point_3d< Type > > const & const_knots() const
vgl_point_3d< Type > point_t(const double t) const
Return a point on the line defined by a scalar parameter t.
T a() const
Return x coefficient.
direction vector in Euclidean 3D space
Type b() const
Return y coefficient.
Type c() const
Return z coefficient.
bool concurrent(l const &l1, l const &l2, l const &l3)
Are three lines concurrent, i.e., do they pass through a common point?.
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 d() const
Return homogeneous scaling coefficient.
line in projective 2D space
double length(v const &a)
Return the length of a vector.
Represents a homogeneous 3D point.
A class to hold a non-homogeneous representation of a 3D line.
#define DIST_SQR_TO_LINE_SEG_3D(T, x1, y1, z1, x2, y2, z2, x, y, z)
Set of closest-point functions.
vgl_point_2d< T > vgl_closest_point_origin(vgl_line_2d< T > const &l)
Return the point on the given line closest to the origin.
int vgl_closest_point_to_non_closed_polygon(T &ret_x, T &ret_y, T const px[], T const py[], unsigned int n, T x, T y)
Closest point to (x,y) on open polygon (px[i],py[i]).
T b() const
Return y coefficient.
const double SMALL_DOUBLE
a point in 3D nonhomogeneous space
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.
bool closed() const
accessors.
int vgl_closest_point_to_closed_polygon(T &ret_x, T &ret_y, T const px[], T const py[], unsigned int n, T x, T y)
Closest point to (x,y) on closed polygon (px[i],py[i]).
bool has_normals() const
accessors.
vgl_point_3d< Type > point1() const
Return the first point representing this line.
Represents a Euclidean 3D plane.
Represents a 3D line segment using two points.
a sphere in 3D nonhomogeneous space
point in projective 2D space
T d() const
Return constant coefficient.
Type a() const
Return x coefficient.
vgl_point_3d< Type > origin() const
Accessors.
Direction vector in Euclidean 3D space, templated by type of element.
#define DIST_SQR_TO_LINE_SEG_2D(T, x1, y1, x2, y2, x, y)
const vgl_point_3d< Type > & centre() const
double vgl_distance(vgl_point_2d< T >const &p1, vgl_point_2d< T >const &p2)
return the distance between two points.
vgl_homg_point_3d< Type > intersection(l const &l1, l const &l2)
Return the intersection point of two concurrent lines.
a plane in 3D nonhomogeneous space
double vgl_closest_point_t(vgl_line_3d_2_points< T > const &l, vgl_point_3d< T > const &p)
Return the point on the given line which is closest to the given point.
non-homogeneous 3D line, represented by 2 points.
vgl_vector_3d< Type > direction() const
Return the direction vector of this line (not normalised - but perhaps it should be,...
Set of distance functions.
Represents a homogeneous 2D point.
unsigned int num_sheets() const
vgl_homg_point_3d< Type > point_finite() const
Finite point (Could be an ideal point, if the whole line is at infinity.).
vgl_vector_3d< Type > direction() const
void spherical_to_cartesian(Type elevation_rad, Type azimuth_rad, Type &x, Type &y, Type &z) const
convert point on sphere to Cartesian coordinates, angles in radians.
T c() const
Return z coefficient.
std::pair< vgl_homg_point_3d< T >, vgl_homg_point_3d< T > > vgl_closest_points(vgl_homg_line_3d_2_points< T > const &line1, vgl_homg_line_3d_2_points< T > const &line2)
Return the two points of nearest approach of two 3D lines, one on each line.
vgl_vector_3d< Type > n(unsigned i) const
vgl_homg_point_3d< Type > point_infinite() const
Infinite point: the intersection of the line with the plane at infinity.
Represents a homogeneous 3D line using two points.