core/vgl/algo/vgl_homg_operators_2d.h
Go to the documentation of this file.
00001 // This is core/vgl/algo/vgl_homg_operators_2d.h
00002 #ifndef vgl_homg_operators_2d_h_
00003 #define vgl_homg_operators_2d_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief 2D homogeneous operations
00010 // \author Don Hamilton, Peter Tu
00011 // \date   Feb 16 2000
00012 //
00013 // \verbatim
00014 // Modifications
00015 //   31-Oct-00 Peter Vanroose - signatures fixed, and vcl_list iterator used
00016 //   16-Mar-01 Tim Cootes - added documentation
00017 //   29-Aug-01 Peter Vanroose - added vgl_conic functions (ported from TargetJr)
00018 //    5-Oct-01 Peter Vanroose - added compute_bounding_box functions
00019 //   15-May-03 Peter Vanroose - added implementation for closest_point()
00020 //   22-Jun-03 Peter Vanroose - vcl_list replaced by vcl_vector in lines_to_point
00021 //    3-Feb-07 Peter Vanroose - changed vnl_vector to vnl_vector_fixed
00022 // \endverbatim
00023 
00024 #include <vcl_list.h>
00025 #include <vcl_vector.h>
00026 #include <vnl/vnl_fwd.h>
00027 #include <vgl/vgl_fwd.h>
00028 
00029 //: 2D homogeneous operations
00030 template <class T>
00031 class vgl_homg_operators_2d
00032 {
00033  public:
00034   //: get a vnl_vector_fixed representation of a homogeneous object
00035   static vnl_vector_fixed<T,3> get_vector(vgl_homg_point_2d<T> const& p);
00036 
00037   //: get a vnl_vector_fixed representation of a homogeneous object
00038   static vnl_vector_fixed<T,3> get_vector(vgl_homg_line_2d<T> const& l);
00039 
00040   //: get a vnl_vector_fixed representation of a homogeneous object
00041   static vnl_vector_fixed<T,6> get_vector(vgl_conic<T> const& c);
00042 
00043   //: Normalize vgl_homg_point_2d<T> to unit magnitude
00044   static void unitize(vgl_homg_point_2d<T>& a);
00045 
00046   static double angle_between_oriented_lines(const vgl_homg_line_2d<T>& line1,
00047                                              const vgl_homg_line_2d<T>& line2);
00048   //: Get the 0 to pi/2 angle between two lines
00049   static double abs_angle(const vgl_homg_line_2d<T>& line1,
00050                           const vgl_homg_line_2d<T>& line2);
00051 
00052   //: Get the 2D distance between the two points.
00053   static T distance(const vgl_homg_point_2d<T>& point1,
00054                     const vgl_homg_point_2d<T>& point2);
00055 
00056   //: Get the square of the 2D distance between the two points.
00057   static T distance_squared(const vgl_homg_point_2d<T>& point1,
00058                             const vgl_homg_point_2d<T>& point2);
00059 
00060   //: Get the square of the perpendicular distance to a line.
00061   // This is just the homogeneous form of the familiar
00062   // \f$ \frac{a x + b y + c}{\sqrt{a^2+b^2}} \f$ :
00063   // \[ d = \frac{(l^\top p)}{p_z\sqrt{l_x^2 + l_y^2}} \]
00064   // If either the point or the line are at infinity an error message is
00065   // printed and Homg::infinity is returned.
00066   static T perp_dist_squared(const vgl_homg_point_2d<T>& point,
00067                              const vgl_homg_line_2d<T>& line);
00068   static T perp_dist_squared(const vgl_homg_line_2d<T>& line,
00069                              const vgl_homg_point_2d<T>& point)
00070   { return perp_dist_squared(point, line); }
00071 
00072   //: True if the points are closer than Euclidean distance d.
00073   static bool is_within_distance(const vgl_homg_point_2d<T>& p1,
00074                                  const vgl_homg_point_2d<T>& p2, double d)
00075   {
00076     if (d <= 0) return false;
00077     return distance_squared(p1, p2) < d*d;
00078   }
00079 
00080   //: Get the anticlockwise angle between a line and the \a x axis.
00081   static double line_angle(const vgl_homg_line_2d<T>& line);
00082 
00083   //: Get the line through two points (the cross-product).
00084   static vgl_homg_line_2d<T> join(const vgl_homg_point_2d<T>& point1,
00085                                   const vgl_homg_point_2d<T>& point2);
00086 
00087   //: Get the line through two points (the cross-product).
00088   // In this case, we assume that the points are oriented,
00089   // and ensure the cross is computed with positive point omegas.
00090   static vgl_homg_line_2d<T> join_oriented(const vgl_homg_point_2d<T>& point1,
00091                                            const vgl_homg_point_2d<T>& point2);
00092 
00093   //: Get the intersection point of two lines (the cross-product).
00094   static vgl_homg_point_2d<T> intersection(const vgl_homg_line_2d<T>& line1,
00095                                            const vgl_homg_line_2d<T>& line2);
00096 
00097   //: Get the perpendicular line to line which passes through point.
00098   // Params are line \f$(a,b,c)\f$ and point \f$(x,y,1)\f$.
00099   // Then the cross product of \f$(x,y,1)\f$ and the line's direction \f$(a,b,0)\f$,
00100   // called \f$(p,q,r)\f$ satisfies
00101   //
00102   //   \f$ap+bq=0\f$ (perpendicular condition) and
00103   //
00104   //   \f$px+qy+r=0\f$ (incidence condition).
00105   static vgl_homg_line_2d<T> perp_line_through_point(const vgl_homg_line_2d<T>& line,
00106                                                      const vgl_homg_point_2d<T>& point);
00107 
00108   //: Get the perpendicular projection of point onto line.
00109   static vgl_homg_point_2d<T> perp_projection(const vgl_homg_line_2d<T>& line,
00110                                               const vgl_homg_point_2d<T>& point);
00111 
00112   //: Return the midpoint of the line joining two homogeneous points
00113   static vgl_homg_point_2d<T> midpoint(const vgl_homg_point_2d<T>& p1,
00114                                        const vgl_homg_point_2d<T>& p2);
00115 
00116   //: Intersect a set of 2D lines to find the least-square point of intersection.
00117   static vgl_homg_point_2d<T> lines_to_point(const vcl_vector<vgl_homg_line_2d<T> >& lines);
00118 
00119   //: cross ratio of four collinear points
00120   // This number is projectively invariant, and it is the coordinate of p4
00121   // in the reference frame where p2 is the origin (coordinate 0), p3 is
00122   // the unity (coordinate 1) and p1 is the point at infinity.
00123   // This cross ratio is often denoted as ((p1, p2; p3, p4)) (which also
00124   // equals ((p3, p4; p1, p2)) or ((p2, p1; p4, p3)) or ((p4, p3; p2, p1)) )
00125   // and is calculated as
00126   //  \verbatim
00127   //                      p1 - p3   p2 - p3      (p1-p3)(p2-p4)
00128   //                      ------- : --------  =  --------------
00129   //                      p1 - p4   p2 - p4      (p1-p4)(p2-p3)
00130   // \endverbatim
00131   // In principle, any single nonhomogeneous coordinate from the four points
00132   // can be used as parameters for cross_ratio (but of course the same for all
00133   // points). The most reliable answer will be obtained when the coordinate with
00134   // the largest spacing is used, i.e., the one with smallest slope.
00135   //
00136   // In this implementation, a least-squares result is calculated when the
00137   // points are not exactly collinear.
00138   //
00139   static double cross_ratio(const vgl_homg_point_2d<T>& p1,
00140                             const vgl_homg_point_2d<T>& p2,
00141                             const vgl_homg_point_2d<T>& p3,
00142                             const vgl_homg_point_2d<T>& p4);
00143 
00144   //: Conjugate point of three given collinear points.
00145   // If cross ratio cr is given (default: -1), the generalized conjugate point
00146   // returned is such that the cross ratio ((x1,x2;x3,answer)) = cr.
00147   static vgl_homg_point_2d<T> conjugate(const vgl_homg_point_2d<T>& a,
00148                                         const vgl_homg_point_2d<T>& b,
00149                                         const vgl_homg_point_2d<T>& c,
00150                                         double cr = -1.0);
00151 
00152   //: compute most orthogonal vector with vnl_symmetric_eigensystem
00153   static vnl_vector_fixed<T,3> most_orthogonal_vector(const vcl_vector<vgl_homg_line_2d<T> >& lines);
00154 
00155   //: compute most orthogonal vector with SVD
00156   static vnl_vector_fixed<T,3> most_orthogonal_vector_svd(const vcl_vector<vgl_homg_line_2d<T> >& lines);
00157 
00158   // coefficient <-> conic matrix conversion -------------------------
00159   static vgl_conic<T> vgl_conic_from_matrix(vnl_matrix_fixed<T,3,3> const& mat);
00160   static vnl_matrix_fixed<T,3,3> matrix_from_conic(vgl_conic<T> const&);
00161   static vnl_matrix_fixed<T,3,3> matrix_from_dual_conic(vgl_conic<T> const&);
00162 
00163   //: Find all real intersection points of a conic and a line (between 0 and 2)
00164   static vcl_list<vgl_homg_point_2d<T> > intersection(vgl_conic<T> const& c,
00165                                                       vgl_homg_line_2d<T> const& l);
00166 
00167   //: Find all real intersection points of two conics (between 0 and 4)
00168   static vcl_list<vgl_homg_point_2d<T> > intersection(vgl_conic<T> const& c1,
00169                                                       vgl_conic<T> const& c2);
00170 
00171   //: Return the (at most) two tangent lines that pass through p and are tangent to the conic.
00172   static vcl_list<vgl_homg_line_2d<T> > tangent_from(vgl_conic<T> const& c,
00173                                                      vgl_homg_point_2d<T> const& p);
00174 
00175   //: Return the list of common tangent lines of two conics.
00176   static vcl_list<vgl_homg_line_2d<T> > common_tangents(vgl_conic<T> const& c1,
00177                                                         vgl_conic<T> const& c2);
00178 
00179   //: Return the point on the line closest to the given point
00180   static vgl_homg_point_2d<T> closest_point(vgl_homg_line_2d<T> const& l,
00181                                             vgl_homg_point_2d<T> const& p);
00182 
00183   //: Return the point on the conic closest to the given point
00184   static vgl_homg_point_2d<T> closest_point(vgl_conic<T> const& c,
00185                                             vgl_homg_point_2d<T> const& p);
00186 
00187   //: Return the point on the conic closest to the given point
00188   static vgl_homg_point_2d<T> closest_point(vgl_conic<T> const& c,
00189                                             vgl_point_2d<T> const& p);
00190 
00191   //: Return the shortest squared distance between the conic and the point
00192   inline static T distance_squared(vgl_conic<T> const& c,
00193                                    vgl_homg_point_2d<T> const& p)
00194   { return distance_squared(closest_point(c,p), p); }
00195 
00196   //: Compute the bounding box of an ellipse
00197   static vgl_box_2d<T> compute_bounding_box(vgl_conic<T> const& c);
00198 
00199  private:
00200   // Helper functions for conic intersection
00201   static vcl_list<vgl_homg_point_2d<T> > do_intersect(vgl_conic<T> const& q, vgl_homg_line_2d<T> const& l);
00202   static vcl_list<vgl_homg_point_2d<T> > do_intersect(vgl_conic<T> const& c1, vgl_conic<T> const& c2);
00203 };
00204 
00205 //: Transform a point through a 3x3 projective transformation matrix
00206 // \relatesalso vgl_homg_point_2d
00207 template <class T>
00208 vgl_homg_point_2d<T> operator*(vnl_matrix_fixed<T,3,3> const& m,
00209                                vgl_homg_point_2d<T> const& p);
00210 
00211 //: Transform a line through a 3x3 projective transformation matrix
00212 // \relatesalso vgl_homg_line_2d
00213 template <class T>
00214 vgl_homg_line_2d<T> operator*(vnl_matrix_fixed<T,3,3> const& m,
00215                               vgl_homg_line_2d<T> const& p);
00216 
00217 #define VGL_HOMG_OPERATORS_2D_INSTANTIATE(T) \
00218         "Please #include <vgl/algo/vgl_homg_operators_2d.txx>"
00219 
00220 #endif // vgl_homg_operators_2d_h_