00001 // This is core/vgl/vgl_conic.h 00002 #ifndef vgl_conic_h_ 00003 #define vgl_conic_h_ 00004 //: 00005 // \file 00006 // \brief A quadratic plane curve 00007 // 00008 // This example tells you the type of the given conic equation, 00009 // and prints the equation in readable form: 00010 // \code 00011 // vgl_conic<double> c(1, 0, 2, 0, 0, -3); 00012 // vcl_cout << c.real_type() << '\n'; // prints "real ellipse" 00013 // vcl_cout << c << '\n'; // prints the equation: X^2 + 2 Y^2 - 3 = 0 00014 // \endcode 00015 // 00016 // \verbatim 00017 // Modifications 00018 // Peter Vanroose, 10 sep 1996 wrote description and example file. 00019 // Peter Vanroose, 17 jun 1998 added PolarLine() and PolarPoint(). 00020 // Peter Vanroose, 18 jun 1998 added Hyperbola and Circle interface. 00021 // Peter Vanroose, 19 jun 1998 added dual space functions. 00022 // Peter Vanroose, 21 jun 1998 added Parabola interface. 00023 // Peter Vanroose, 27 jun 1998 added ComputeParabolaParameters(). 00024 // M.Vergauwen & P.Vanroose, 4 jul 1998 added Intersect() & CommonTangents() 00025 // Peter Vanroose, 29 aug 2001 ported from Geometry to vgl 00026 // Peter Vanroose, 30 aug 2001 complete rewrite of most of the code 00027 // Peter Vanroose, 31 aug 2001 added extensive testing + fixed some bugs 00028 // Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line 00029 // Ricardo Fabbri, 08 nov 2008 added curvature_at() method. 00030 // \endverbatim 00031 // 00032 //----------------------------------------------------------------------------- 00033 00034 #include <vcl_list.h> 00035 #include <vcl_string.h> 00036 #include <vcl_iosfwd.h> 00037 00038 #include <vgl/vgl_homg_point_2d.h> 00039 #include <vgl/vgl_homg_line_2d.h> 00040 00041 //: A quadratic plane curve 00042 // 00043 // A conic is either an ellipse (or circle), a hyperbola, or a parabola. 00044 // It is represented by a quadratic equation in two nonhomogeneous 00045 // or three homogeneous coordinates. Conversely, every quadratic 00046 // equation represents a conic, be it that it can be degenerate: 00047 // either in two (intersecting or parallel) lines, or in two 00048 // coincident lines. Also, it can have no "visible", real points, 00049 // when it is an imaginary ellipse, or consist of two complementary 00050 // imaginary lines in which case it only has one real point, which could 00051 // still be at infinity. 00052 // 00053 // These 11 cases are the possible values of vgl_conic::real_type(). 00054 // The default constructor sets the type to "invalid conic"; 00055 // otherwise the correct type is automatically set when the equation 00056 // of the conic is given to the constructor that takes 6 numeric values 00057 // (a,b,c,d,e,f): the cartesian equation is then 00058 // $ax^2 + bxy + cy^2 + dx + ey + f = 0$; the homogeneous equation is 00059 // $ax^2 + bxy + cy^2 + dxw + eyw + fw^2 = 0$. (Sometimes with $z$ for $w$.) 00060 // The numeric type (typically double or float) is the template argument 00061 // of this class. 00062 // 00063 // When the conic is degenerate and consists of two lines, the method 00064 // components() returns a list of two (possibly identical) lines. 00065 // Otherwise, this method returns an empty list. 00066 00067 template <class T> 00068 class vgl_conic 00069 { 00070 public: 00071 enum vgl_conic_type { 00072 no_type=0, 00073 real_ellipse, 00074 real_circle, 00075 imaginary_ellipse, 00076 imaginary_circle, 00077 hyperbola, 00078 parabola, 00079 real_intersecting_lines, 00080 complex_intersecting_lines, 00081 real_parallel_lines, 00082 complex_parallel_lines, 00083 coincident_lines, 00084 num_conic_types // is here to enable iterating through this list 00085 }; 00086 00087 private: 00088 // DATA MEMBERS 00089 00090 vgl_conic_type type_; 00091 T a_; //!< coefficient of \a x^2 00092 T b_; //!< coefficient of \a xy 00093 T c_; //!< coefficient of \a y^2 00094 T d_; //!< coefficient of \a xw 00095 T e_; //!< coefficient of \a yw 00096 T f_; //!< coefficient of \a w^2 00097 00098 public: 00099 inline vgl_conic_type type() const { return type_; } 00100 00101 //: Returns the type of the conic as a string. 00102 // Possible returned strings are: 00103 // "real ellipse", "real circle", "imaginary ellipse", "imaginary circle", 00104 // "hyperbola", "parabola", 00105 // "real intersecting lines", "complex intersecting lines", 00106 // "real parallel lines", "complex parallel lines", "coincident lines". 00107 // The default constructor sets the type to "invalid conic". 00108 vcl_string real_type() const; 00109 00110 //: Returns the internal enum value corresponding to the string argument. 00111 // Useful for comparison purposes, or for use in "case" statements. 00112 static vgl_conic_type type_by_name(vcl_string const& name); 00113 00114 //: Converts the conic type from enum (internal representation) to string. 00115 static vcl_string type_by_number(vgl_conic_type type); 00116 00117 //: Returns the coefficient of \f$X^2\f$ 00118 inline T a() const { return a_; } 00119 00120 //: Returns the coefficient of \f$XY\f$ 00121 inline T b() const { return b_; } 00122 00123 //: Returns the coefficient of \f$Y^2\f$ 00124 inline T c() const { return c_; } 00125 00126 //: Returns the coefficient of \f$XW\f$ 00127 inline T d() const { return d_; } 00128 00129 //: Returns the coefficient of \f$YW\f$ 00130 inline T e() const { return e_; } 00131 00132 //: Returns the coefficient of \f$W^2\f$ 00133 inline T f() const { return f_; } 00134 00135 // CONSTRUCTORS AND RELATED STUFF 00136 00137 // default constructor 00138 vgl_conic() : type_(no_type) {} 00139 #if 0 // The compiler defaults for these are all right 00140 // copy constructor 00141 vgl_conic(vgl_conic<T> const& c) 00142 : type_(c.type()), a_(c.a()), b_(c.b()), c_(c.c()), d_(c.d()), e_(c.e()), f_(c.f()) {} 00143 // assignment operator 00144 vgl_conic& operator=(vgl_conic<T> const& c) { 00145 type_=c.type(); a_=c.a(); b_=c.b(); c_=c.c(); d_=c.d(); e_=c.e(); f_=c.f(); 00146 return *this; 00147 } 00148 // destructor 00149 ~vgl_conic() {} 00150 #endif 00151 00152 //: constructor using polynomial coefficients. 00153 // The order of the coefficients is: $X^2$, $XY$, $Y^2$, $XW$, $YW$, $W^2$, 00154 // where $W$ is the homogeneous coordinate (sometimes denoted by $Z$). 00155 vgl_conic(T a, T b, T c, T d, T e, T f); 00156 00157 //: constructor using polynomial coefficients, given as a C array. 00158 // The order of the coefficients is: $X^2$, $XY$, $Y^2$, $XW$, $YW$, $W^2$, 00159 // where $W$ is the homogeneous coordinate (sometimes denoted by $Z$). 00160 vgl_conic(T const coeff[]); 00161 00162 //: constructor using centre, signed radii, and angle. 00163 // This constructor can only be used for non-degenerate, real 00164 // conics: If the centre point c is a finite point and rx and ry 00165 // have the same sign, an ellipse is defined (any ellipse can 00166 // uniquely be specified this way); rx is the length of one main 00167 // axis, ry of the other axis. Hyperbolas are obtained if rx and 00168 // ry have opposite sign; the positive one determines the distance 00169 // from bots tops to the centre, and the other one specified the 00170 // 'minor' axis length. The rotation is about the centre of the 00171 // ellipse or hyperbola, measured counterclockwise from the X axis. 00172 // A parabola is obtained when the centre has w()=0, 00173 // i.e., is a point at infinity. In that case (rx,ry) is the 00174 // top, and theta is an eccentricity parameter (since the centre 00175 // already specifies the direction of the symmetry axis). 00176 vgl_conic(vgl_homg_point_2d<T> const& c, T rx, T ry, T theta); 00177 00178 //: set or reset the conic using polynomial coefficients. 00179 // The order of the coefficients is: $X^2$, $XY$, $Y^2$, $XW$, $YW$, $W^2$, 00180 // where $W$ is the homogeneous coordinate (sometimes denoted by $Z$). 00181 void set(T a, T b, T c, T d, T e, T f); 00182 00183 //: comparison operator. 00184 // Comparison is on the conic, not the equation coefficients. Hence two 00185 // conics are identical if their coefficient vectors are multiples of 00186 // each other. 00187 bool operator==(vgl_conic<T> const& c) const; 00188 00189 // UTILITY FUNCTIONS 00190 00191 //: Returns true if this conic is degenerate, i.e., if it consists of 2 lines. 00192 bool is_degenerate() const; 00193 00194 //: Returns true if a central conic, i.e., an ellipse, circle, or hyperbola. 00195 // Also the degenerate versions of these return true. 00196 // Returns false if a parabola or two parallel or coinciding lines. 00197 bool is_central() const; 00198 00199 //: Returns true if the point pt belongs to the conic. 00200 // I.e., if it \e exactly satisfies the conic equation. 00201 // Beware of rounding for floating point type T! An "almost" returns false! 00202 bool contains(vgl_homg_point_2d<T> const& pt) const; 00203 00204 //: Returns the list of component lines, when degenerate and real components. 00205 // Otherwise returns an empty list. 00206 // If two coinciding lines, the list contains two identical elements. 00207 // Hence this list always has length 0 or 2. 00208 vcl_list<vgl_homg_line_2d<T> > components() const; 00209 00210 // Elementary geometric functions ---------------------------------- 00211 00212 //: Returns the polar line of the given point, w.r.t. this conic. 00213 // For a non-degenerate conic, the polar line of a point outside of the conic 00214 // is the connection line of the two points on the conic that form the conic 00215 // "contour" as seen from that point, i.e., the touch points of the two 00216 // tangents to the conic going through the given point. 00217 // 00218 // For a point on the conic, it is just the tangent in that point. 00219 // 00220 // And for a point inside the conic, it is the set of all polar points of 00221 // the lines through the given point. This set happens to be a straight line. 00222 vgl_homg_line_2d<T> polar_line(vgl_homg_point_2d<T> const& p) const; 00223 00224 //: Returns the polar point of the given line, w.r.t. this conic. 00225 // For a non-degenerate conic, the polar point of a line that intersects the 00226 // conic in two points is the intersection point of the two tangent lines 00227 // though those two points. Hence it is the point of which this line is 00228 // the polar line. 00229 // 00230 // For a tangent line to the conic, it is just the tangent point. 00231 // 00232 // And for a line not intersecting the conic, it is the common intersection 00233 // point (inside the conic) of the polar lines of all points of that line. 00234 vgl_homg_point_2d<T> polar_point(vgl_homg_line_2d<T> const& l) const; 00235 00236 //: Returns the tangent to the conic in the point p, if p is on the conic. 00237 // In general, returns the polar line of the point w.r.t. the conic. 00238 vgl_homg_line_2d<T> tangent_at(vgl_homg_point_2d<T> const& p) const { return polar_line(p); } 00239 00240 //: Returns the centre of the conic, or its point at infinity if a parabola. 00241 // When two intersecting or parallel lines, returns their intersection point. 00242 // In all cases this is the polar point of the line at infinity. 00243 vgl_homg_point_2d<T> centre() const { return polar_point(vgl_homg_line_2d<T>(0,0,1)); } 00244 00245 //: Returns the curvature of the conic at point p, assuming p is on the conic. 00246 double curvature_at(vgl_point_2d<T> const& p) const; 00247 00248 //: Converts the coefficients to a geometric description of an ellipse. 00249 // Returns false if the conic is not an ellipse. Double is appropriate 00250 // since integer coefficients can produce non-integer ellipse parameters. 00251 bool ellipse_geometry(double& xc, double& yc, double& major_axis_length, 00252 double& minor_axis_length, double& angle_in_radians) const; 00253 00254 // Functions related to dual space --------------------------------- 00255 00256 //: Returns the dual or tangential representation of this conic. 00257 // The homogeneous coordinates of the points belonging to the dual conic 00258 // are the coefficients of the equations of all tangents to the original 00259 // conic. 00260 vgl_conic dual_conic() const; 00261 00262 //: Returns the dual or tangential representation of this conic. 00263 vgl_conic tangential_form() const { return dual_conic(); } 00264 00265 //: Modify this conic by translating it over distance \a x in the \a X direction and distance \a y in the \a Y direction. 00266 void translate_by(T x, T y); 00267 00268 private: 00269 //-------------------------------------------------------------------------- 00270 //: set conic type from polynomial coefficients and store in member type_ 00271 // This method must be called by all constructors (except the default 00272 // constructor) and all methods that change the coefficients. 00273 void set_type_from_equation(); 00274 }; 00275 00276 //: Write "<vgl_conic aX^2+bXY+cY^2+dXW+eYW+fW^2>" to stream 00277 // \relatesalso vgl_conic 00278 template <class T> 00279 vcl_ostream& operator<<(vcl_ostream& s, vgl_conic<T> const& c); 00280 00281 //: Read a b c d e f from stream 00282 // \relatesalso vgl_conic 00283 template <class T> 00284 vcl_istream& operator>>(vcl_istream& s, vgl_conic<T>& c); 00285 00286 #define VGL_CONIC_INSTANTIATE(T) extern "please include vgl/vgl_conic.txx first" 00287 00288 #endif // vgl_conic_h_