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