vgl_homg_operators_2d.h
Go to the documentation of this file.
1 // This is core/vgl/algo/vgl_homg_operators_2d.h
2 #ifndef vgl_homg_operators_2d_h_
3 #define vgl_homg_operators_2d_h_
4 //:
5 // \file
6 // \brief 2D homogeneous operations
7 // \author Don Hamilton, Peter Tu
8 // \date Feb 16 2000
9 // \verbatim
10 // Modifications
11 // 31-Oct-00 Peter Vanroose - signatures fixed, and std::list iterator used
12 // 16-Mar-01 Tim Cootes - added documentation
13 // 29-Aug-01 Peter Vanroose - added vgl_conic functions (ported from TargetJr)
14 // 5-Oct-01 Peter Vanroose - added compute_bounding_box functions
15 // 15-May-03 Peter Vanroose - added implementation for closest_point()
16 // 22-Jun-03 Peter Vanroose - std::list replaced by std::vector in lines_to_point
17 // 3-Feb-07 Peter Vanroose - changed vnl_vector to vnl_vector_fixed
18 // 20-Dec-10 Peter Vanroose - bug fix in conic intersection
19 // (when 2 intersection pts have same y coordinate)
20 // \endverbatim
21 
22 #include <list>
23 #include <vector>
24 #ifdef _MSC_VER
25 # include <vcl_msvc_warnings.h>
26 #endif
27 #include <vnl/vnl_fwd.h>
28 #include <vgl/vgl_fwd.h>
29 
30 //: 2D homogeneous operations
31 template <class T>
33 {
34  public:
35  //: get a vnl_vector_fixed representation of a homogeneous object
36  static vnl_vector_fixed<T,3> get_vector(vgl_homg_point_2d<T> const& p);
37 
38  //: get a vnl_vector_fixed representation of a homogeneous object
39  static vnl_vector_fixed<T,3> get_vector(vgl_homg_line_2d<T> const& l);
40 
41  //: get a vnl_vector_fixed representation of a homogeneous object
42  static vnl_vector_fixed<T,6> get_vector(vgl_conic<T> const& c);
43 
44  //: Normalize vgl_homg_point_2d<T> to unit magnitude
45  static void unitize(vgl_homg_point_2d<T>& a);
46 
47  static double angle_between_oriented_lines(const vgl_homg_line_2d<T>& line1,
48  const vgl_homg_line_2d<T>& line2);
49  //: Get the 0 to pi/2 angle between two lines
50  static double abs_angle(const vgl_homg_line_2d<T>& line1,
51  const vgl_homg_line_2d<T>& line2);
52 
53  //: Get the 2D distance between the two points.
54  static T distance(const vgl_homg_point_2d<T>& point1,
55  const vgl_homg_point_2d<T>& point2);
56 
57  //: Get the square of the 2D distance between the two points.
58  static T distance_squared(const vgl_homg_point_2d<T>& point1,
59  const vgl_homg_point_2d<T>& point2);
60 
61  //: Get the square of the perpendicular distance to a line.
62  // This is just the homogeneous form of the familiar
63  // \f$ \frac{a x + b y + c}{\sqrt{a^2+b^2}} \f$ :
64  // \[ d = \frac{(l^\top p)}{p_z\sqrt{l_x^2 + l_y^2}} \]
65  // If either the point or the line are at infinity an error message is
66  // printed and Homg::infinity is returned.
67  static T perp_dist_squared(const vgl_homg_point_2d<T>& point,
68  const vgl_homg_line_2d<T>& line);
69  static T perp_dist_squared(const vgl_homg_line_2d<T>& line,
70  const vgl_homg_point_2d<T>& point)
71  { return perp_dist_squared(point, line); }
72 
73  //: True if the points are closer than Euclidean distance d.
75  const vgl_homg_point_2d<T>& p2, double d)
76  {
77  if (d <= 0) return false;
78  return distance_squared(p1, p2) < d*d;
79  }
80 
81  //: Get the anticlockwise angle between a line and the \a x axis.
82  static double line_angle(const vgl_homg_line_2d<T>& line);
83 
84  //: Get the line through two points (the cross-product).
85  static vgl_homg_line_2d<T> join(const vgl_homg_point_2d<T>& point1,
86  const vgl_homg_point_2d<T>& point2);
87 
88  //: Get the line through two points (the cross-product).
89  // In this case, we assume that the points are oriented,
90  // and ensure the cross is computed with positive point omegas.
92  const vgl_homg_point_2d<T>& point2);
93 
94  //: Get the intersection point of two lines (the cross-product).
96  const vgl_homg_line_2d<T>& line2);
97 
98  //: Get the perpendicular line to line which passes through point.
99  // Params are line \f$(a,b,c)\f$ and point \f$(x,y,1)\f$.
100  // Then the cross product of \f$(x,y,1)\f$ and the line's direction \f$(a,b,0)\f$,
101  // called \f$(p,q,r)\f$ satisfies
102  //
103  // \f$ap+bq=0\f$ (perpendicular condition) and
104  //
105  // \f$px+qy+r=0\f$ (incidence condition).
107  const vgl_homg_point_2d<T>& point);
108 
109  //: Get the perpendicular projection of point onto line.
111  const vgl_homg_point_2d<T>& point);
112 
113  //: Return the midpoint of the line joining two homogeneous points
115  const vgl_homg_point_2d<T>& p2);
116 
117  //: Intersect a set of 2D lines to find the least-square point of intersection.
118  static vgl_homg_point_2d<T> lines_to_point(const std::vector<vgl_homg_line_2d<T> >& lines);
119 
120  //: cross ratio of four collinear points
121  // This number is projectively invariant, and it is the coordinate of p4
122  // in the reference frame where p2 is the origin (coordinate 0), p3 is
123  // the unity (coordinate 1) and p1 is the point at infinity.
124  // This cross ratio is often denoted as ((p1, p2; p3, p4)) (which also
125  // equals ((p3, p4; p1, p2)) or ((p2, p1; p4, p3)) or ((p4, p3; p2, p1)) )
126  // and is calculated as
127  // \verbatim
128  // p1 - p3 p2 - p3 (p1-p3)(p2-p4)
129  // ------- : -------- = --------------
130  // p1 - p4 p2 - p4 (p1-p4)(p2-p3)
131  // \endverbatim
132  // In principle, any single nonhomogeneous coordinate from the four points
133  // can be used as parameters for cross_ratio (but of course the same for all
134  // points). The most reliable answer will be obtained when the coordinate with
135  // the largest spacing is used, i.e., the one with smallest slope.
136  //
137  // In this implementation, a least-squares result is calculated when the
138  // points are not exactly collinear.
139  //
140  static double cross_ratio(const vgl_homg_point_2d<T>& p1,
141  const vgl_homg_point_2d<T>& p2,
142  const vgl_homg_point_2d<T>& p3,
143  const vgl_homg_point_2d<T>& p4);
144 
145  //: Conjugate point of three given collinear points.
146  // If cross ratio cr is given (default: -1), the generalized conjugate point
147  // returned is such that the cross ratio ((x1,x2;x3,answer)) = cr.
149  const vgl_homg_point_2d<T>& b,
150  const vgl_homg_point_2d<T>& c,
151  double cr = -1.0);
152 
153  //: compute most orthogonal vector with vnl_symmetric_eigensystem
154  static vnl_vector_fixed<T,3> most_orthogonal_vector(const std::vector<vgl_homg_line_2d<T> >& lines);
155 
156  //: compute most orthogonal vector with SVD
157  static vnl_vector_fixed<T,3> most_orthogonal_vector_svd(const std::vector<vgl_homg_line_2d<T> >& lines);
158 
159  // coefficient <-> conic matrix conversion -------------------------
160  static vgl_conic<T> vgl_conic_from_matrix(vnl_matrix_fixed<T,3,3> const& mat);
161  static vnl_matrix_fixed<T,3,3> matrix_from_conic(vgl_conic<T> const&);
162  static vnl_matrix_fixed<T,3,3> matrix_from_dual_conic(vgl_conic<T> const&);
163 
164  //: Find all real intersection points of a conic and a line (between 0 and 2, including points at infinity)
165  static std::list<vgl_homg_point_2d<T> > intersection(vgl_conic<T> const& c,
166  vgl_homg_line_2d<T> const& l);
167 
168  //: Find all real intersection points of two conics (between 0 and 4, including points at infinity)
169  static std::list<vgl_homg_point_2d<T> > intersection(vgl_conic<T> const& c1,
170  vgl_conic<T> const& c2);
171 
172  //: Return the (at most) two tangent lines that pass through p and are tangent to the conic.
173  static std::list<vgl_homg_line_2d<T> > tangent_from(vgl_conic<T> const& c,
174  vgl_homg_point_2d<T> const& p);
175 
176  //: Return the list of common tangent lines of two conics.
177  static std::list<vgl_homg_line_2d<T> > common_tangents(vgl_conic<T> const& c1,
178  vgl_conic<T> const& c2);
179 
180  //: Return the point on the line closest to the given point
182  vgl_homg_point_2d<T> const& p);
183 
184  //: Return the point on the conic closest to the given point
186  vgl_homg_point_2d<T> const& p);
187 
188  //: Return the point on the conic closest to the given point
190  vgl_point_2d<T> const& p);
191 
192  //: Return the shortest squared distance between the conic and the point
193  inline static T distance_squared(vgl_conic<T> const& c,
194  vgl_homg_point_2d<T> const& p)
195  { return distance_squared(closest_point(c,p), p); }
196 
197  //: Compute the bounding box of an ellipse
199 
200  private:
201  // Helper functions for conic intersection
202  static std::list<vgl_homg_point_2d<T> > do_intersect(vgl_conic<T> const& q, vgl_homg_line_2d<T> const& l);
203  static std::list<vgl_homg_point_2d<T> > do_intersect(vgl_conic<T> const& c1, vgl_conic<T> const& c2);
204 };
205 
206 //: Transform a point through a 3x3 projective transformation matrix
207 // \relatesalso vgl_homg_point_2d
208 template <class T>
209 vgl_homg_point_2d<T> operator*(vnl_matrix_fixed<T,3,3> const& m,
210  vgl_homg_point_2d<T> const& p);
211 
212 //: Transform a line through a 3x3 projective transformation matrix
213 // \relatesalso vgl_homg_line_2d
214 template <class T>
215 vgl_homg_line_2d<T> operator*(vnl_matrix_fixed<T,3,3> const& m,
216  vgl_homg_line_2d<T> const& p);
217 
218 #define VGL_HOMG_OPERATORS_2D_INSTANTIATE(T) \
219  "Please #include <vgl/algo/vgl_homg_operators_2d.hxx>"
220 
221 #endif // vgl_homg_operators_2d_h_
static vgl_conic< T > vgl_conic_from_matrix(vnl_matrix_fixed< T, 3, 3 > const &mat)
returns the vgl_conic which has the given matrix as its matrix.
static vgl_homg_point_2d< T > conjugate(const vgl_homg_point_2d< T > &a, const vgl_homg_point_2d< T > &b, const vgl_homg_point_2d< T > &c, double cr=-1.0)
Conjugate point of three given collinear points.
static vnl_matrix_fixed< T, 3, 3 > matrix_from_conic(vgl_conic< T > const &)
returns 3x3 matrix containing conic coefficients.
Represents a homogeneous 2D line.
Definition: vgl_fwd.h:14
static vgl_homg_point_2d< T > intersection(const vgl_homg_line_2d< T > &line1, const vgl_homg_line_2d< T > &line2)
Get the intersection point of two lines (the cross-product).
static vgl_homg_line_2d< T > perp_line_through_point(const vgl_homg_line_2d< T > &line, const vgl_homg_point_2d< T > &point)
Get the perpendicular line to line which passes through point.
static std::list< vgl_homg_point_2d< T > > do_intersect(vgl_conic< T > const &q, vgl_homg_line_2d< T > const &l)
This function is called from within intersection(vgl_conic<T>,vgl_homg_line_2d<T>).
static vgl_homg_point_2d< T > midpoint(const vgl_homg_point_2d< T > &p1, const vgl_homg_point_2d< T > &p2)
Return the midpoint of the line joining two homogeneous points.
static vgl_homg_point_2d< T > closest_point(vgl_homg_line_2d< T > const &l, vgl_homg_point_2d< T > const &p)
Return the point on the line closest to the given point.
static vnl_vector_fixed< T, 3 > most_orthogonal_vector(const std::vector< vgl_homg_line_2d< T > > &lines)
compute most orthogonal vector with vnl_symmetric_eigensystem.
static vnl_vector_fixed< T, 3 > get_vector(vgl_homg_point_2d< T > const &p)
get a vnl_vector_fixed representation of a homogeneous object.
2D homogeneous operations.
Definition: vgl_algo_fwd.h:28
static vgl_homg_line_2d< T > join(const vgl_homg_point_2d< T > &point1, const vgl_homg_point_2d< T > &point2)
Get the line through two points (the cross-product).
static void unitize(vgl_homg_point_2d< T > &a)
Normalize vgl_homg_point_2d<T> to unit magnitude.
static vgl_homg_point_2d< T > lines_to_point(const std::vector< vgl_homg_line_2d< T > > &lines)
Intersect a set of 2D lines to find the least-square point of intersection.
A quadratic plane curve.
Definition: vgl_conic.h:70
static double cross_ratio(const vgl_homg_point_2d< T > &p1, const vgl_homg_point_2d< T > &p2, const vgl_homg_point_2d< T > &p3, const vgl_homg_point_2d< T > &p4)
cross ratio of four collinear points.
static T perp_dist_squared(const vgl_homg_line_2d< T > &line, const vgl_homg_point_2d< T > &point)
static vgl_homg_line_2d< T > join_oriented(const vgl_homg_point_2d< T > &point1, const vgl_homg_point_2d< T > &point2)
Get the line through two points (the cross-product).
static vnl_matrix_fixed< T, 3, 3 > matrix_from_dual_conic(vgl_conic< T > const &)
returns 3x3 matrix containing conic coefficients of dual conic.
static vgl_homg_point_2d< T > perp_projection(const vgl_homg_line_2d< T > &line, const vgl_homg_point_2d< T > &point)
Get the perpendicular projection of point onto line.
static T distance_squared(vgl_conic< T > const &c, vgl_homg_point_2d< T > const &p)
Return the shortest squared distance between the conic and the point.
static vnl_vector_fixed< T, 3 > most_orthogonal_vector_svd(const std::vector< vgl_homg_line_2d< T > > &lines)
compute most orthogonal vector with SVD.
static T distance_squared(const vgl_homg_point_2d< T > &point1, const vgl_homg_point_2d< T > &point2)
Get the square of the 2D distance between the two points.
#define l
vgl_homg_point_1d< T > operator *(vnl_matrix_fixed< T, 2, 2 > const &m, vgl_homg_point_1d< T > const &p)
Transform a point through a 2x2 projective transformation matrix.
static vgl_box_2d< T > compute_bounding_box(vgl_conic< T > const &c)
Compute the bounding box of an ellipse.
static double angle_between_oriented_lines(const vgl_homg_line_2d< T > &line1, const vgl_homg_line_2d< T > &line2)
Get the angle between two lines, a number between -PI and PI.
static T distance(const vgl_homg_point_2d< T > &point1, const vgl_homg_point_2d< T > &point2)
Get the 2D distance between the two points.
static double line_angle(const vgl_homg_line_2d< T > &line)
Get the anticlockwise angle between a line and the x axis.
static double abs_angle(const vgl_homg_line_2d< T > &line1, const vgl_homg_line_2d< T > &line2)
Get the 0 to pi/2 angle between two lines.
Represents a homogeneous 2D point.
Definition: vgl_fwd.h:8
static std::list< vgl_homg_line_2d< T > > common_tangents(vgl_conic< T > const &c1, vgl_conic< T > const &c2)
Return the list of common tangent lines of two conics.
static T perp_dist_squared(const vgl_homg_point_2d< T > &point, const vgl_homg_line_2d< T > &line)
Get the square of the perpendicular distance to a line.
static bool is_within_distance(const vgl_homg_point_2d< T > &p1, const vgl_homg_point_2d< T > &p2, double d)
True if the points are closer than Euclidean distance d.
static std::list< vgl_homg_line_2d< T > > tangent_from(vgl_conic< T > const &c, vgl_homg_point_2d< T > const &p)
Return the (at most) two tangent lines that pass through p and are tangent to the conic.