core/vgl/vgl_conic.h
Go to the documentation of this file.
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_