core/vgl/algo/vgl_homg_operators_3d.h
Go to the documentation of this file.
00001 // This is core/vgl/algo/vgl_homg_operators_3d.h
00002 #ifndef vgl_homg_operators_3d_h_
00003 #define vgl_homg_operators_3d_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief 3D homogeneous functions
00010 // \author Don Hamilton, Peter Tu
00011 // \date Feb 16 2000
00012 //
00013 // \verbatim
00014 //  Modifications
00015 //   31-oct-00 Peter Vanroose - implementations fixed, and vgl_homg_line_3d typedef'd
00016 //   16-Mar-01 Tim Cootes - Tidied up documentation
00017 //   14-Jun-04 Peter Vanroose - implemented conjugate(), unitize(), perp_dist_squared(), midpoint(), planes_to_point()
00018 //    3-Feb-07 Peter Vanroose - changed vnl_vector to vnl_vector_fixed
00019 // \endverbatim
00020 
00021 #include <vcl_vector.h>
00022 #include <vnl/vnl_fwd.h>
00023 #include <vgl/vgl_fwd.h>
00024 #include <vgl/vgl_homg_line_3d_2_points.h>
00025 
00026 //: 3D homogeneous operations
00027 template <class Type>
00028 class vgl_homg_operators_3d
00029 {
00030   typedef vgl_homg_line_3d_2_points<Type> vgl_homg_line_3d;
00031 
00032  public:
00033   //: Get a vnl_vector_fixed representation of a homogeneous object
00034   static vnl_vector_fixed<Type,4> get_vector(vgl_homg_point_3d<Type> const& p);
00035   //: Get a vnl_vector_fixed representation of a homogeneous object
00036   static vnl_vector_fixed<Type,4> get_vector(vgl_homg_plane_3d<Type> const& p);
00037 
00038   //: Normalize vgl_homg_point_3d<Type> to unit magnitude
00039   static void unitize(vgl_homg_point_3d<Type>& a);
00040 
00041   static double angle_between_oriented_lines(const vgl_homg_line_3d& line1,
00042                                              const vgl_homg_line_3d& line2);
00043 
00044   //: Return the Euclidean distance between the points
00045   static Type distance(const vgl_homg_point_3d<Type>& point1,
00046                        const vgl_homg_point_3d<Type>& point2);
00047   //: Return the squared distance between the points
00048   static Type distance_squared(const vgl_homg_point_3d<Type>& point1,
00049                                const vgl_homg_point_3d<Type>& point2);
00050 
00051   //: True if the points are closer than Euclidean distance d.
00052   static bool is_within_distance(const vgl_homg_point_3d<Type>& p1,
00053                                  const vgl_homg_point_3d<Type>& p2, double d)
00054   {
00055     if (d <= 0) return false;
00056     return distance_squared(p1, p2) < d*d;
00057   }
00058 
00059   //: Get the square of the perpendicular distance to a plane.
00060   // This is just the homogeneous form of the familiar
00061   // $ \frac{a x + b y + c z + d}{\sqrt{a^2+b^2+c^2}} $ :
00062   // \[ d = \frac{(l^\top p)}{p_z\sqrt{l_x^2 + l_y^2 l_z^2}} \]
00063   // If either the point or the plane are at infinity an error message is
00064   // printed and Homg::infinity is returned.
00065   static double perp_dist_squared(const vgl_homg_point_3d<Type>& point,
00066                                   const vgl_homg_plane_3d<Type>& plane);
00067   static double perp_dist_squared(const vgl_homg_plane_3d<Type>& plane,
00068                                   const vgl_homg_point_3d<Type>& point)
00069   { return perp_dist_squared(point, plane); }
00070 
00071   static vgl_homg_point_3d<Type> intersect_line_and_plane(const vgl_homg_line_3d&,
00072                                                           const vgl_homg_plane_3d<Type>&);
00073 #if 0 // not yet implemented
00074   static vgl_homg_point_3d<Type> lines_to_point(const vgl_homg_line_3d& line1,
00075                                                 const vgl_homg_line_3d& line2);
00076   static vgl_homg_point_3d<Type> lines_to_point(const vcl_vector<vgl_homg_line_3d>& line_list);
00077 #endif // 0
00078   static double perp_dist_squared(const vgl_homg_line_3d& line,
00079                                   const vgl_homg_point_3d<Type>& point);
00080   static double perp_dist_squared(const vgl_homg_point_3d<Type>& point,
00081                                   const vgl_homg_line_3d& line)
00082   { return perp_dist_squared(line,point); }
00083   static vgl_homg_line_3d perp_line_through_point(const vgl_homg_line_3d& line,
00084                                                   const vgl_homg_point_3d<Type>& point);
00085   static vgl_homg_point_3d<Type> perp_projection(const vgl_homg_line_3d& line,
00086                                                  const vgl_homg_point_3d<Type>& point);
00087   static vgl_homg_line_3d planes_to_line(const vgl_homg_plane_3d<Type>& plane1,
00088                                          const vgl_homg_plane_3d<Type>& plane2);
00089   static Type plane_plane_angle(const vgl_homg_plane_3d<Type>& plane1, 
00090                                 const vgl_homg_plane_3d<Type>& plane2);
00091 #if 0 // not yet implemented
00092   static vgl_homg_line_3d planes_to_line(const vcl_vector<vgl_homg_plane_3d<Type> >& plane_list);
00093   static vgl_homg_line_3d points_to_line(const vgl_homg_point_3d<Type>& point1,
00094                                          const vgl_homg_point_3d<Type>& point2);
00095   static vgl_homg_line_3d points_to_line(const vcl_vector<vgl_homg_point_3d<Type> >& point_list);
00096 
00097   static vgl_homg_plane_3d<Type> points_to_plane(const vgl_homg_point_3d<Type>&,
00098                                                  const vgl_homg_point_3d<Type>&,
00099                                                  const vgl_homg_point_3d<Type>& );
00100   static vgl_homg_plane_3d<Type> points_to_plane(const vcl_vector<vgl_homg_point_3d<Type> >& point_list);
00101 #endif // 0
00102   static vgl_homg_point_3d<Type> intersection(const vgl_homg_plane_3d<Type>&,
00103                                               const vgl_homg_plane_3d<Type>&,
00104                                               const vgl_homg_plane_3d<Type>&);
00105   static vgl_homg_point_3d<Type> intersection(const vcl_vector<vgl_homg_plane_3d<Type> >&);
00106 
00107   //: Return the midpoint of the line joining two homogeneous points
00108   static vgl_homg_point_3d<Type> midpoint(const vgl_homg_point_3d<Type>& p1,
00109                                           const vgl_homg_point_3d<Type>& p2);
00110 
00111   //: Intersect a set of 3D planes to find the least-square point of intersection.
00112   static vgl_homg_point_3d<Type> planes_to_point(const vcl_vector<vgl_homg_plane_3d<Type> >& planes);
00113 
00114   //-----------------------------------------------------------------------------
00115   //: Calculates the cross ratio of four collinear points p1, p2, p3 and p4.
00116   // This number is projectively invariant, and it is the coordinate of p4
00117   // in the reference frame where p2 is the origin (coordinate 0), p3 is
00118   // the unity (coordinate 1) and p1 is the point at infinity.
00119   // This cross ratio is often denoted as ((p1, p2; p3, p4)) (which also
00120   // equals ((p3, p4; p1, p2)) or ((p2, p1; p4, p3)) or ((p4, p3; p2, p1)) )
00121   // and is calculated as
00122   // \verbatim
00123   //                      p1 - p3   p2 - p3      (p1-p3)(p2-p4)
00124   //                      ------- : --------  =  --------------
00125   //                      p1 - p4   p2 - p4      (p1-p4)(p2-p3)
00126   // \endverbatim
00127   //
00128   // In principle, any single nonhomogeneous coordinate from the four points
00129   // can be used as parameters for cross_ratio (but of course the same for all
00130   // points). The most reliable answer will be obtained when the coordinate with
00131   // the largest spacing is used, i.e., the one with smallest slope.
00132   //
00133   // In this implementation, a least-squares result is calculated when the
00134   // points are not exactly collinear.
00135 
00136   static double cross_ratio(const vgl_homg_point_3d<Type>& p1,
00137                             const vgl_homg_point_3d<Type>& p2,
00138                             const vgl_homg_point_3d<Type>& p3,
00139                             const vgl_homg_point_3d<Type>& p4);
00140   static double cross_ratio(const vgl_homg_plane_3d<Type>& p1,
00141                             const vgl_homg_plane_3d<Type>& p2,
00142                             const vgl_homg_plane_3d<Type>& p3,
00143                             const vgl_homg_plane_3d<Type>& p4);
00144 
00145   //: Conjugate point of three given collinear points.
00146   // If cross ratio cr is given (default: -1), the generalized conjugate point
00147   // returned is such that the cross ratio ((x1,x2;x3,answer)) = cr.
00148   static vgl_homg_point_3d<Type> conjugate(const vgl_homg_point_3d<Type>& a,
00149                                            const vgl_homg_point_3d<Type>& b,
00150                                            const vgl_homg_point_3d<Type>& c,
00151                                            double cr = -1.0);
00152 
00153   //: compute most orthogonal vector with SVD
00154   static vnl_vector_fixed<Type,4> most_orthogonal_vector_svd(const vcl_vector<vgl_homg_plane_3d<Type> >& planes);
00155 };
00156 
00157 //: Homographic transformation of a 3D point through a 4x4 projective transformation matrix
00158 template <class Type>
00159 vgl_homg_point_3d<Type> operator*(vnl_matrix_fixed<Type,4,4> const& m,
00160                                   vgl_homg_point_3d<Type> const& p);
00161 
00162 //: Project a 3D point to 2D through a 3x4 projective transformation matrix
00163 template <class Type>
00164 vgl_homg_point_2d<Type> operator*(vnl_matrix_fixed<Type,3,4> const& m,
00165                                   vgl_homg_point_3d<Type> const& p);
00166 
00167 //: Homographic transformation of a 3D plane through a 4x4 projective transformation matrix
00168 template <class Type>
00169 vgl_homg_plane_3d<Type> operator*(vnl_matrix_fixed<Type,4,4> const& m,
00170                                   vgl_homg_plane_3d<Type> const& p);
00171 
00172 //: Backproject a 2D line through a 4x3 projective transformation matrix
00173 template <class Type>
00174 vgl_homg_plane_3d<Type> operator*(vnl_matrix_fixed<Type,4,3> const& m,
00175                                   vgl_homg_line_2d<Type> const& l);
00176 
00177 #define VGL_HOMG_OPERATORS_3D_INSTANTIATE(T) \
00178         "Please #include <vgl/algo/vgl_homg_operators_3d.txx>"
00179 
00180 #endif // vgl_homg_operators_3d_h_