core/vgl/vgl_closest_point.h
Go to the documentation of this file.
00001 // This is core/vgl/vgl_closest_point.h
00002 #ifndef vgl_closest_point_h_
00003 #define vgl_closest_point_h_
00004 //:
00005 // \file
00006 // \brief Set of closest-point functions
00007 // \author Peter Vanroose
00008 //
00009 // All these functions have two arguments which are geometry objects, and
00010 // return either a pair of points (one from each object) which are the ones
00011 // closest to each other, or just 1 point in case one of the objects is a point.
00012 //
00013 // See also vgl_distance if you only need the shortest distance between two
00014 // geometric objects and not the actual closest points.
00015 //
00016 // \verbatim
00017 //  Modifications
00018 //    5 June 2003 Peter Vanroose created from bits and pieces in vgl_distance
00019 //    5 June 2003 Brendan McCane added closest-point algo for 3D lines
00020 //   11 June 2003 Peter Vanroose added closest-point on 3D line from point
00021 //   14 Nov. 2003 Peter Vanroose made all functions templated
00022 //   25 Sept 2004 Peter Vanroose added full 3D interface
00023 // \endverbatim
00024 
00025 #include <vgl/vgl_fwd.h> // forward declare various vgl classes
00026 #include <vcl_utility.h> // for vcl_pair<T,U>
00027 
00028 //: Closest point to \a (x,y) on the line segment \a (x1,y1)-(x2,y2)
00029 template <class T>
00030 void vgl_closest_point_to_linesegment(T& ret_x, T& ret_y,
00031                                       T x1, T y1,
00032                                       T x2, T y2,
00033                                       T x, T y);
00034 
00035 //: Closest point to \a (x,y,z) on the line segment \a (x1,y1,z1)-(x2,y2,z2)
00036 template <class T>
00037 void vgl_closest_point_to_linesegment(T& ret_x, T& ret_y, T& ret_z,
00038                                       T x1, T y1, T z1,
00039                                       T x2, T y2, T z2,
00040                                       T x, T y, T z);
00041 
00042 //: Closest point to \a (x,y) on open polygon \a (px[i],py[i])
00043 //  Also returns the index of the polygon line segment where this point lies.
00044 template <class T>
00045 int vgl_closest_point_to_non_closed_polygon(T& ret_x, T& ret_y,
00046                                             T const px[], T const py[], unsigned int n,
00047                                             T x, T y);
00048 
00049 //: Closest point to \a (x,y,z) on open polygon \a (px[i],py[i],pz[i])
00050 //  Also returns the index of the polygon line segment where this point lies.
00051 template <class T>
00052 int vgl_closest_point_to_non_closed_polygon(T& ret_x, T& ret_y, T& ret_z,
00053                                             T const px[], T const py[], T const pz[], unsigned int n,
00054                                             T x, T y, T z);
00055 
00056 //: Closest point to \a (x,y) on closed polygon \a (px[i],py[i])
00057 //  Also returns the index of the polygon line segment where this point lies.
00058 template <class T>
00059 int vgl_closest_point_to_closed_polygon(T& ret_x, T& ret_y,
00060                                         T const px[], T const py[], unsigned int n,
00061                                         T x, T y);
00062 
00063 //: Closest point to \a (x,y,z) on closed polygon \a (px[i],py[i],pz[i])
00064 //  Also returns the index of the polygon line segment where this point lies.
00065 template <class T>
00066 int vgl_closest_point_to_closed_polygon(T& ret_x, T& ret_y, T& ret_z,
00067                                         T const px[], T const py[], T const pz[], unsigned int n,
00068                                         T x, T y, T z);
00069 
00070 //: Return the point on the given line closest to the origin
00071 // \relatesalso vgl_line_2d
00072 // \relatesalso vgl_point_2d
00073 template <class T>
00074 vgl_point_2d<T> vgl_closest_point_origin(vgl_line_2d<T> const& l);
00075 
00076 //: Return the point on the given line closest to the origin
00077 // \relatesalso vgl_homg_line_2d
00078 // \relatesalso vgl_homg_point_2d
00079 template <class T>
00080 vgl_homg_point_2d<T> vgl_closest_point_origin(vgl_homg_line_2d<T> const& l);
00081 
00082 //: Return the point on the given plane closest to the origin
00083 // \relatesalso vgl_plane_3d
00084 // \relatesalso vgl_point_3d
00085 template <class T>
00086 vgl_point_3d<T> vgl_closest_point_origin(vgl_plane_3d<T> const& pl);
00087 
00088 //: Return the point on the given plane closest to the origin
00089 // \relatesalso vgl_homg_plane_3d
00090 // \relatesalso vgl_homg_point_3d
00091 template <class T>
00092 vgl_homg_point_3d<T> vgl_closest_point_origin(vgl_homg_plane_3d<T> const& pl);
00093 
00094 //: Return the point on the given line closest to the origin
00095 // \relatesalso vgl_line_3d_2_points
00096 // \relatesalso vgl_point_3d
00097 template <class T>
00098 vgl_point_3d<T> vgl_closest_point_origin(vgl_line_3d_2_points<T> const& l);
00099 
00100 //: Return the point on the given line closest to the origin
00101 // \relatesalso vgl_homg_line_3d_2_points
00102 // \relatesalso vgl_homg_point_3d
00103 template <class T>
00104 vgl_homg_point_3d<T> vgl_closest_point_origin(vgl_homg_line_3d_2_points<T> const& l);
00105 
00106 //: Return the point on the given line closest to the given point
00107 // \relatesalso vgl_point_2d
00108 // \relatesalso vgl_line_2d
00109 template <class T>
00110 vgl_point_2d<T> vgl_closest_point(vgl_line_2d<T> const& l,
00111                                   vgl_point_2d<T> const& p);
00112 template <class T> inline
00113 vgl_point_2d<T> vgl_closest_point(vgl_point_2d<T> const& p,
00114                                   vgl_line_2d<T> const& l)
00115 { return vgl_closest_point(l,p); }
00116 
00117 //: Return the point on the given line closest to the given point
00118 // \relatesalso vgl_homg_point_2d
00119 // \relatesalso vgl_homg_line_2d
00120 template <class T>
00121 vgl_homg_point_2d<T> vgl_closest_point(vgl_homg_line_2d<T> const& l,
00122                                        vgl_homg_point_2d<T> const& p);
00123 template <class T> inline
00124 vgl_homg_point_2d<T> vgl_closest_point(vgl_homg_point_2d<T> const& p,
00125                                        vgl_homg_line_2d<T> const& l)
00126 { return vgl_closest_point(l,p); }
00127 
00128 //: Return the point on the given plane closest to the given point
00129 // \relatesalso vgl_point_3d
00130 // \relatesalso vgl_plane_3d
00131 template <class T>
00132 vgl_point_3d<T> vgl_closest_point(vgl_plane_3d<T> const& pl,
00133                                   vgl_point_3d<T> const& p);
00134 template <class T> inline
00135 vgl_point_3d<T> vgl_closest_point(vgl_point_3d<T> const& p,
00136                                   vgl_plane_3d<T> const& pl)
00137 { return vgl_closest_point(pl,p); }
00138 
00139 //: Return the point on the given plane closest to the given point
00140 // \relatesalso vgl_homg_point_3d
00141 // \relatesalso vgl_homg_plane_3d
00142 template <class T>
00143 vgl_homg_point_3d<T> vgl_closest_point(vgl_homg_plane_3d<T> const& pl,
00144                                        vgl_homg_point_3d<T> const& p);
00145 template <class T> inline
00146 vgl_homg_point_3d<T> vgl_closest_point(vgl_homg_point_3d<T> const& p,
00147                                        vgl_homg_plane_3d<T> const& pl)
00148 { return vgl_closest_point(pl,p); }
00149 
00150 //: Return the point on the given polygon closest to the given point
00151 //  If the third argument is "false", the edge from last to first point of
00152 //  each polygon sheet is not considered part of the polygon.
00153 // \relatesalso vgl_point_2d
00154 // \relatesalso vgl_polygon
00155 template <class T>
00156 vgl_point_2d<T> vgl_closest_point(vgl_polygon<T> const& poly,
00157                                   vgl_point_2d<T> const& point,
00158                                   bool closed=true);
00159 
00160 template <class T> inline
00161 vgl_point_2d<T> vgl_closest_point(vgl_point_2d<T> const& point,
00162                                   vgl_polygon<T> const& poly,
00163                                   bool closed=true)
00164 { return vgl_closest_point(poly, point, closed); }
00165 
00166 //: Return the two points of nearest approach of two 3D lines, one on each line.
00167 //
00168 // There are 3 cases: the lines intersect (hence these two points are equal);
00169 // the lines are parallel (an infinite number of solutions viz all points);
00170 // the lines are neither parallel nor do they intersect (the general case).
00171 // This method handles all 3 cases. In all cases, a pair of points is returned;
00172 // in case 1, the two returned points are equal;
00173 // in case 2, both points are the common point at infinity of the two lines.
00174 //
00175 // Note that case 2 also comprises the case where the given lines are identical.
00176 // Hence, when observing a point at infinity as a return value, one should
00177 // interpret this as "all points are closest points".
00178 //
00179 // \param line1
00180 // \param line2
00181 //
00182 // \return vcl_pair<vgl_homg_point_3d<T>,vgl_homg_point_3d<T> >
00183 // \relatesalso vgl_homg_line_3d_2_points
00184 //
00185 // \author Paul Bourke, modified for use in VXL by Brendan McCane
00186 //
00187 // \note This routine is adapted from code written by Paul Bourke and
00188 // available online at
00189 // http://astronomy.swin.edu.au/~pbourke/geometry/lineline3d/
00190 
00191 template <class T>
00192 vcl_pair<vgl_homg_point_3d<T>, vgl_homg_point_3d<T> >
00193 vgl_closest_points(vgl_homg_line_3d_2_points<T> const& line1,
00194                    vgl_homg_line_3d_2_points<T> const& line2);
00195 
00196 //: Return the point on the given line which is closest to the given point.
00197 //  If the given point is at infinity, the point at infinity of the line is returned.
00198 // \relatesalso vgl_homg_line_3d_2_points
00199 // \relatesalso vgl_homg_point_3d
00200 template <class T>
00201 vgl_homg_point_3d<T> vgl_closest_point(vgl_homg_line_3d_2_points<T> const& l,
00202                                        vgl_homg_point_3d<T> const& p);
00203 
00204 template <class T> inline
00205 vgl_homg_point_3d<T> vgl_closest_point(vgl_homg_point_3d<T> const& p,
00206                                        vgl_homg_line_3d_2_points<T> const& l)
00207 { return vgl_closest_point(l,p); }
00208 
00209 //: Return the point on the given line which is closest to the given point.
00210 // \relatesalso vgl_line_3d_2_points
00211 // \relatesalso vgl_point_3d
00212 template <class T>
00213 vgl_point_3d<T> vgl_closest_point(vgl_line_3d_2_points<T> const& l,
00214                                   vgl_point_3d<T> const& p);
00215 
00216 template <class T> inline
00217 vgl_point_3d<T> vgl_closest_point(vgl_point_3d<T> const& p,
00218                                   vgl_line_3d_2_points<T> const& l)
00219 { return vgl_closest_point(l,p); }
00220 
00221 template <class T> inline
00222 vgl_point_3d<T> vgl_closest_point(vgl_point_3d<T> const& p,
00223                                   vgl_infinite_line_3d<T> const& l){
00224   vgl_line_3d_2_points<T> l2(l.point(), l.point_t(T(1)));
00225   return vgl_closest_point(p,l2);}
00226 
00227 template <class T> inline
00228 vgl_point_3d<T> vgl_closest_point(vgl_infinite_line_3d<T> const& l,
00229                                   vgl_point_3d<T> const& p){
00230   return vgl_closest_point(p,l);}
00231 
00232 template <class T>
00233 vgl_point_3d<T> vgl_closest_point(vgl_point_3d<T> const& p,
00234                                   vgl_ray_3d<T> const& r);
00235 
00236 template <class T> inline
00237 vgl_point_3d<T> vgl_closest_point(vgl_ray_3d<T> const& r,
00238                                   vgl_point_3d<T> const& p){
00239   return vgl_closest_point(p,r);}
00240 //: Return the point on the given line which is closest to the given point.
00241 // The closest point is expressed in parametric form.
00242 // \relatesalso vgl_line_3d_2_points
00243 // \relatesalso vgl_point_3d
00244 // \sa vgl_line_3d_2_points::point_t()
00245 // \sa vgl_closest_point(vgl_line_3d_2_points<T> const&, vgl_point_3d<T> const&)
00246 template <class T>
00247 double vgl_closest_point_t(vgl_line_3d_2_points<T> const& l,
00248                            vgl_point_3d<T> const& p);
00249 
00250 template <class T> inline
00251 double vgl_closest_point_t(vgl_point_3d<T> const& p,
00252                            vgl_line_3d_2_points<T> const& l)
00253 { return vgl_closest_point_t(l,p); }
00254 
00255 
00256 //: Return the points of closest approach on 2 3D lines.
00257 // Uses non-homogeneous representations.
00258 // \return The pair of closest points, the first on \a l1, the second on \a l2.
00259 // \retval unique If provided, will be set to true if the returned points are unique,
00260 // otherwise many solutions exist and the returned points are an arbitrary choice.
00261 // The distance between the points is still valid, however.
00262 // \relatesalso vgl_line_3d_2_points
00263 template <class T>
00264 vcl_pair<vgl_point_3d<T>, vgl_point_3d<T> >
00265 vgl_closest_points(const vgl_line_3d_2_points<T>& l1,
00266                    const vgl_line_3d_2_points<T>& l2,
00267                    bool* unique=0);
00268 
00269 
00270 //: Return the points of closest approach on two infinite 3D lines.
00271 // Uses non-homogeneous representations.
00272 // \return The pair of closest points, the first on \a l1, the second on \a l2.
00273 // \retval unique If provided, will be set to true if the returned points are unique,
00274 // otherwise many solutions exist and the returned points are an arbitrary choice.
00275 // The distance between the points is still valid, however.
00276 // \relatesalso vgl_line_3d_2_points
00277 template <class T>
00278 vcl_pair<vgl_point_3d<T>, vgl_point_3d<T> >
00279 vgl_closest_points(const vgl_infinite_line_3d<T>& l1,
00280                    const vgl_infinite_line_3d<T>& l2,
00281                    bool* unique=0)
00282 {
00283   vgl_line_3d_2_points<T> l21(l1.point(), l1.point_t(T(1)));
00284   vgl_line_3d_2_points<T> l22(l2.point(), l2.point_t(T(1)));
00285   return vgl_closest_points(l21, l22, unique);
00286 }
00287 
00288 //: Return the points of closest approach on 2 3D line segments.
00289 // Uses non-homogeneous representations.
00290 // \return The pair of closest points, the first on \a l1, the second on \a l2.
00291 // \retval unique If provided, will be set to true if the returned points are unique,
00292 // otherwise many solutions exist and the returned points are an arbitrary choice.
00293 // The distance between the points is still valid, however.
00294 // \relatesalso vgl_line_segment_3d
00295 template <class T>
00296 vcl_pair<vgl_point_3d<T>, vgl_point_3d<T> >
00297 vgl_closest_points(const vgl_line_segment_3d<T>& l1,
00298                    const vgl_line_segment_3d<T>& l2,
00299                    bool* unique=0);
00300 
00301 //: Return the closest point on a line segment \a l to a point \a p in 2D
00302 // \relatesalso vgl_point_2d
00303 // \relatesalso vgl_line_segment_2d
00304 // \sa vgl_distance_to_linesegment()
00305 template <class T>
00306 vgl_point_2d<T> vgl_closest_point(vgl_line_segment_2d<T> const& l,
00307                                   vgl_point_2d<T> const& p);
00308 template <class T> inline
00309 vgl_point_2d<T> vgl_closest_point(vgl_point_2d<T> const& p,
00310                                   vgl_line_segment_2d<T> const& l) { return vgl_closest_point(l,p); }
00311 
00312 //: Return the closest point on a line segment \a l to a point \a p in 3D
00313 // \relatesalso vgl_point_3d
00314 // \relatesalso vgl_line_segment_3d
00315 // \sa vgl_distance_to_linesegment()
00316 template <class T>
00317 vgl_point_3d<T> vgl_closest_point(vgl_line_segment_3d<T> const& l,
00318                                   vgl_point_3d<T> const& p);
00319 template <class T> inline
00320 vgl_point_3d<T> vgl_closest_point(vgl_point_3d<T> const& p,
00321                                   vgl_line_segment_3d<T> const& l) { return vgl_closest_point(l,p); }
00322 
00323 
00324 #endif // vgl_closest_point_h_