contrib/gel/vsol/vsol_conic_2d.h
Go to the documentation of this file.
00001 // This is gel/vsol/vsol_conic_2d.h
00002 #ifndef vsol_conic_2d_h_
00003 #define vsol_conic_2d_h_
00004 //*****************************************************************************
00005 //:
00006 // \file
00007 // \brief Euclidean general conic class in 2D space
00008 //
00009 // The conic is defined by its cartesian equation
00010 // a x^2 +b xy +c y^2 +d x +e y +f
00011 // This class inherits both from vsol_curve_2d and vgl_conic<double>.
00012 // From the latter it inherits most of its geometric functionality, but
00013 // robustified (with "eps" values to catch rounding errors), non-templated,
00014 // and with non-homogeneous Euclidean 2D geometry terminology instead of
00015 // homogeneous 3-tuples.
00016 //
00017 // \author François BERTEL
00018 // \date   2000-04-28
00019 //
00020 // \verbatim
00021 //  Modifications
00022 //   2000-04-28 François BERTEL Creation
00023 //   2000-06-17 Peter Vanroose  Implemented all operator==()s and type info
00024 //   2001-08-29 Peter Vanroose  midpoint() added
00025 //   2001-08-29 Peter Vanroose  conic intersection added (implemented in vgl)
00026 //   2001-08-29 Peter Vanroose  closest_point and distance to point added
00027 //   2001-08-30 Peter Vanroose  now inheriting from vgl_conic
00028 //   2001-08-31 Peter Vanroose  constructor added from centre, size, orientation
00029 //   2002-04-05 Peter Vanroose  axis() added
00030 //   2003-01-08 Peter Vanroose  moved static private methods to vsol_conic_2d.cxx
00031 //   2004-05-11 Joseph Mundy    added binary I/O methods
00032 //   2004-09-23 Ming-Ching Chang Changed cast_to_conic_2d() to cast_to_conic()
00033 // \endverbatim
00034 //*****************************************************************************
00035 
00036 #include <vgl/vgl_fwd.h>
00037 #include <vgl/vgl_conic.h> // parent class
00038 #include <vgl/vgl_conic_segment_2d.h>
00039 #include <vsl/vsl_binary_io.h>
00040 #include <vsol/vsol_curve_2d.h>
00041 #include <vsol/vsol_point_2d.h>
00042 #include <vsol/vsol_line_2d.h>
00043 #include <vsol/vsol_line_2d_sptr.h>
00044 #include <vnl/vnl_double_3x3.h>
00045 #include <vcl_list.h>
00046 #include <vcl_iostream.h>
00047 
00048 //: Euclidean general conic class, part of the vsol_curve_2d hierarchy
00049 
00050 class vsol_conic_2d : public vsol_curve_2d, public vgl_conic<double>
00051 {
00052   //***************************************************************************
00053   // Data members
00054   //***************************************************************************
00055 
00056   //---------------------------------------------------------------------------
00057   //: First point of the curve
00058   //---------------------------------------------------------------------------
00059   vsol_point_2d_sptr p0_;
00060 
00061   //---------------------------------------------------------------------------
00062   //: Last point of the curve
00063   //---------------------------------------------------------------------------
00064   vsol_point_2d_sptr p1_;
00065 
00066  public:
00067   //---------------------------------------------------------------------------
00068   //: the different kinds of conic
00069   //---------------------------------------------------------------------------
00070   enum vsol_conic_type
00071   {
00072     invalid=0, // not 'degenerate' since numbers 7 to 11 are degenerate - PVr
00073     real_ellipse,
00074     real_circle,
00075     complex_ellipse,
00076     complex_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   };
00085 
00086  private: // has been superseded by is_a()
00087   //: Return the curve type
00088   virtual vsol_curve_2d_type curve_type() const { return vsol_curve_2d::CONIC; }
00089 
00090  public:
00091   //***************************************************************************
00092   // Initialization
00093   //***************************************************************************
00094 
00095   //---------------------------------------------------------------------------
00096   //: Default Constructor
00097   //  produces and invalid conic (needed for binary I/O)
00098   //---------------------------------------------------------------------------
00099   vsol_conic_2d() : vsol_curve_2d(), vgl_conic<double>() {}
00100 
00101   //---------------------------------------------------------------------------
00102   //: Constructor from coefficients of the cartesian equation
00103   //  `a'x^2+`b'xy+`c'y^2+`d'x+`e'y+`f'
00104   //---------------------------------------------------------------------------
00105   vsol_conic_2d(double ta, double tb, double tc, double td, double te, double tf)
00106     : vsol_curve_2d(), vgl_conic<double>(ta, tb, tc, td, te, tf) {}
00107 
00108   //---------------------------------------------------------------------------
00109   //: Ellipse/hyperbola constructor from centre, size and orientation.
00110   //  This constructor can only be used for non-degenerate, real ellipses and
00111   //  hyperbolas: if rx and ry have the same sign, an ellipse is defined
00112   //  (and any ellipse can uniquely be specified this way);
00113   //  rx is the length of one main axis, ry of the other axis.
00114   //  Hyperbolas are obtained if rx and ry have opposite sign; the positive
00115   //  one determines the distance from bots tops to the centre, and the other
00116   //  one specified the 'minor' axis length.
00117   //---------------------------------------------------------------------------
00118   vsol_conic_2d(vsol_point_2d const& cntr, double rx, double ry, double theta);
00119 
00120   //---------------------------------------------------------------------------
00121   //: Parabola constructor from direction, top and eccentricity parameter.
00122   //  This constructor can only be used for non-degenerate parabolas:
00123   //  specify the direction of the symmetry axis, the top, and an eccentricity
00124   //  parameter theta.
00125   //---------------------------------------------------------------------------
00126   vsol_conic_2d(vgl_vector_2d<double> const& dir, vsol_point_2d const& top, double theta);
00127 
00128   //---------------------------------------------------------------------------
00129   //: Set ellipse/hyperbola from centre, size and orientation.
00130   //  Can only be used for non-degenerate, real ellipses and
00131   //  hyperbolas: if rx and ry have the same sign, an ellipse is defined
00132   //  (and any ellipse can uniquely be specified this way);
00133   //  rx is the length of one main axis, ry of the other axis.
00134   //  Hyperbolas are obtained if rx and ry have opposite sign; the positive
00135   //  one determines the distance from bots tops to the centre, and the other
00136   //  one specified the 'minor' axis length.
00137   //---------------------------------------------------------------------------
00138   void set_central_parameters(vsol_point_2d const& cntr, double rx, double ry, double theta);
00139 
00140   //---------------------------------------------------------------------------
00141   //: Set parabola from direction, top and eccentricity parameter.
00142   //  This can only be used for non-degenerate parabolas:
00143   //  specify the direction of the symmetry axis, the top, and an eccentricity
00144   //  parameter theta.
00145   //---------------------------------------------------------------------------
00146   void set_parabola_parameters(vgl_vector_2d<double> const& dir,
00147                                vsol_point_2d const& top, double theta);
00148 
00149   //---------------------------------------------------------------------------
00150   //: Constructor from vgl_conic_segment_2d
00151   //---------------------------------------------------------------------------
00152   vsol_conic_2d(vgl_conic_segment_2d<double> & cs) : vsol_curve_2d(), vgl_conic<double>(cs.conic()),
00153      p0_(new vsol_point_2d(cs.point1())), p1_(new vsol_point_2d(cs.point2())) {}
00154 
00155   //---------------------------------------------------------------------------
00156   //: Copy constructor
00157   //---------------------------------------------------------------------------
00158   vsol_conic_2d(vsol_conic_2d const& co):vsol_curve_2d(co),vgl_conic<double>(co) {}
00159 
00160   //---------------------------------------------------------------------------
00161   //: Destructor
00162   //---------------------------------------------------------------------------
00163   virtual ~vsol_conic_2d() {}
00164 
00165   //---------------------------------------------------------------------------
00166   //: Clone `this': creation of a new object and initialization
00167   // See Prototype pattern
00168   //---------------------------------------------------------------------------
00169   virtual vsol_spatial_object_2d* clone() const;
00170 
00171   //***************************************************************************
00172   // Access
00173   //***************************************************************************
00174 
00175   //---------------------------------------------------------------------------
00176   //: Return the first point of `this';  pure virtual of vsol_curve_2d
00177   //---------------------------------------------------------------------------
00178   virtual vsol_point_2d_sptr p0() const { return p0_; }
00179 
00180   //---------------------------------------------------------------------------
00181   //: Return the last point of `this';  pure virtual of vsol_curve_2d
00182   //---------------------------------------------------------------------------
00183   virtual vsol_point_2d_sptr p1() const { return p1_; }
00184 
00185   //***************************************************************************
00186   // Comparison
00187   //***************************************************************************
00188 
00189   //---------------------------------------------------------------------------
00190   //: Has `this' the same coefficients and the same end points than `other' ?
00191   //---------------------------------------------------------------------------
00192   virtual bool operator==(vsol_conic_2d const& other) const;
00193   virtual bool operator==(vsol_spatial_object_2d const&) const; // virtual of vsol_spatial_object_2d
00194 
00195   //---------------------------------------------------------------------------
00196   //: Has `this' not the same coeffs than `other', or different end points ?
00197   //---------------------------------------------------------------------------
00198   inline bool operator!=(vsol_conic_2d const& o) const {return !operator==(o);}
00199 
00200   //***************************************************************************
00201   // Status report
00202   //***************************************************************************
00203 
00204   //---------------------------------------------------------------------------
00205   //: Return the real type of the conic from its coefficients
00206   //---------------------------------------------------------------------------
00207   vsol_conic_type real_type() const;
00208   vcl_string real_conic_type() const { return static_cast<vgl_conic<double> >(*this).real_type(); }
00209 
00210   //---------------------------------------------------------------------------
00211   //: Is `this' a real ellipse ?
00212   //---------------------------------------------------------------------------
00213   bool is_real_ellipse() const;
00214 
00215   //---------------------------------------------------------------------------
00216   //: Is `this' a real circle ?
00217   //---------------------------------------------------------------------------
00218   bool is_real_circle() const;
00219 
00220   //---------------------------------------------------------------------------
00221   //: Is `this' a complex ellipse ?
00222   //---------------------------------------------------------------------------
00223   bool is_complex_ellipse() const;
00224 
00225   //---------------------------------------------------------------------------
00226   //: Is `this' a complex circle ?
00227   //---------------------------------------------------------------------------
00228   bool is_complex_circle() const;
00229 
00230   //---------------------------------------------------------------------------
00231   //: Is `this' a parabola ?
00232   //---------------------------------------------------------------------------
00233   bool is_parabola() const;
00234 
00235   //---------------------------------------------------------------------------
00236   //: Is `this' a hyperbola ?
00237   //---------------------------------------------------------------------------
00238   bool is_hyperbola() const;
00239 
00240   //---------------------------------------------------------------------------
00241   //: Is `this' a pair of real intersecting lines ?
00242   //---------------------------------------------------------------------------
00243   bool is_real_intersecting_lines() const;
00244 
00245   //---------------------------------------------------------------------------
00246   //: Is `this' a pair of complex intersecting lines ?
00247   //---------------------------------------------------------------------------
00248   bool is_complex_intersecting_lines() const;
00249 
00250   //---------------------------------------------------------------------------
00251   //: Is `this' a pair of coincident lines ?
00252   //---------------------------------------------------------------------------
00253   bool is_coincident_lines() const;
00254 
00255   //---------------------------------------------------------------------------
00256   //: Return 3 ellipse parameters:
00257   //  -                            centre (`cx',`cy'),
00258   //  -                            orientation `phi',
00259   //  -                            size (`width',`height')
00260   //  REQUIRE: is_real_ellipse()
00261   //---------------------------------------------------------------------------
00262   void ellipse_parameters(double &cx,
00263                           double &cy,
00264                           double &phi,
00265                           double &width,
00266                           double &height) const;
00267 
00268   //---------------------------------------------------------------------------
00269   //: Return ellipse angular position
00270   //  -   input pt  , a point on the ellipse
00271   //  -   output angle
00272   //  -
00273   //  REQUIRE: is_real_ellipse()
00274   //---------------------------------------------------------------------------
00275   double ellipse_angular_position(vsol_point_2d_sptr const& pt) const;
00276 
00277   //---------------------------------------------------------------------------
00278   //: Return 3 hyperbola parameters:
00279   //  -                            centre (`cx',`cy'),
00280   //  -                            orientation `phi',
00281   //  -                            size (`half-axis',-`half-secondary-axis')
00282   //  REQUIRE: is_hyperbola()
00283   //---------------------------------------------------------------------------
00284   void hyperbola_parameters(double &cx,
00285                             double &cy,
00286                             double &phi,
00287                             double &main_axis,
00288                             double &secondary_axis) const;
00289 
00290   //---------------------------------------------------------------------------
00291   //: Return 2 parabola parameters:
00292   //  -                             top (`cx',`cy'),
00293   //  -                             orientation (`cosphi',`sinphi')
00294   //  REQUIRE: is_parabola()
00295   //---------------------------------------------------------------------------
00296   void parabola_parameters(double &cx,
00297                            double &cy,
00298                            double &cosphi,
00299                            double &sinphi) const;
00300 
00301   //---------------------------------------------------------------------------
00302   //: Return the length of `this'
00303   //---------------------------------------------------------------------------
00304   virtual double length() const; // pure virtual of vsol_curve_2d
00305 
00306   //---------------------------------------------------------------------------
00307   //: Return the matrix associated with the coefficients.
00308   //---------------------------------------------------------------------------
00309   vnl_double_3x3 matrix() const;
00310 
00311   //***************************************************************************
00312   // Status setting
00313   //***************************************************************************
00314 
00315   //---------------------------------------------------------------------------
00316   //: Set the first point of the curve
00317   //  REQUIRE: in(new_p0)
00318   //---------------------------------------------------------------------------
00319   virtual void set_p0(vsol_point_2d_sptr const& new_p0);
00320 
00321   //---------------------------------------------------------------------------
00322   //: Set the last point of the curve
00323   //  REQUIRE: in(new_p1)
00324   //---------------------------------------------------------------------------
00325   virtual void set_p1(vsol_point_2d_sptr const& new_p1);
00326 
00327   //***************************************************************************
00328   // Basic operations
00329   //***************************************************************************
00330 
00331   //---------------------------------------------------------------------------
00332   //: Return the centre or symmetry point of a central conic.
00333   //---------------------------------------------------------------------------
00334   vsol_point_2d_sptr midpoint() const;
00335 
00336   //---------------------------------------------------------------------------
00337   //: Return the main symmetry axis, if not degenerate.
00338   //---------------------------------------------------------------------------
00339   vsol_line_2d_sptr axis() const;
00340 
00341   //---------------------------------------------------------------------------
00342   //: Is `p' in `this' ? (ie `p' verifies the equation, within some margin)
00343   //---------------------------------------------------------------------------
00344   virtual bool in(vsol_point_2d_sptr const& p) const;
00345 
00346   //---------------------------------------------------------------------------
00347   //: Returns the tangent to the conic in the point p, if p is on the conic.
00348   //  In general, returns the polar line of the point w.r.t. the conic.
00349   //---------------------------------------------------------------------------
00350   virtual vgl_homg_line_2d<double>* tangent_at_point(vsol_point_2d_sptr const& p) const;
00351 
00352   //---------------------------------------------------------------------------
00353   //: Return the set of (real) intersection points of this conic with a line
00354   //---------------------------------------------------------------------------
00355   vcl_list<vsol_point_2d_sptr> intersection(vsol_line_2d const& line) const;
00356 
00357   //---------------------------------------------------------------------------
00358   //: Return the set of (real) intersection points of two conics
00359   //---------------------------------------------------------------------------
00360   vcl_list<vsol_point_2d_sptr> intersection(vsol_conic_2d const& co) const;
00361 
00362   //---------------------------------------------------------------------------
00363   //: Return the point on the conic boundary which is closest to the given point
00364   //---------------------------------------------------------------------------
00365   vsol_point_2d_sptr closest_point_on_curve(vsol_point_2d_sptr const& pt) const;
00366 
00367   //---------------------------------------------------------------------------
00368   //: Return the shortest distance of the point to the conic boundary
00369   //---------------------------------------------------------------------------
00370   double distance(vsol_point_2d_sptr const& pt) const;
00371 
00372   //---------------------------------------------------------------------------
00373   //: output description to stream
00374   //---------------------------------------------------------------------------
00375   inline void describe(vcl_ostream &strm, int blanking=0) const
00376   {
00377     if (blanking < 0) blanking = 0; while (blanking--) strm << ' ';
00378     strm << "vsol_conic_2d<" << static_cast<vgl_conic<double> >(*this)
00379          << '>' << vcl_endl;
00380   }
00381 
00382   //---------------------------------------------------------------------------
00383   //: Return `this' if `this' is a conic, 0 otherwise
00384   //---------------------------------------------------------------------------
00385   virtual vsol_conic_2d const*cast_to_conic() const { return this; }
00386   virtual vsol_conic_2d *cast_to_conic() { return this; }
00387 
00388   // ==== Binary IO methods ======
00389 
00390   //: Binary save self to stream.
00391   void b_write(vsl_b_ostream &os) const;
00392 
00393   //: Binary load self from stream.
00394   void b_read(vsl_b_istream &is);
00395 
00396   //: Return IO version number;
00397   short version() const;
00398 
00399   //: Print an ascii summary to the stream
00400   void print_summary(vcl_ostream &os) const;
00401 
00402   //: Return a platform independent string identifying the class
00403   virtual vcl_string is_a() const { return "vsol_conic_2d"; }
00404 
00405   //: Return true if the argument matches the string identifying the class or any parent class
00406   virtual bool is_class(vcl_string const& cls) const { return cls==is_a(); }
00407 };
00408 
00409 //: Binary save vsol_conic_2d* to stream.
00410 void vsl_b_write(vsl_b_ostream &os, const vsol_conic_2d* p);
00411 
00412 //: Binary load vsol_conic_2d* from stream.
00413 void vsl_b_read(vsl_b_istream &is, vsol_conic_2d* &p);
00414 
00415 #endif // vsol_conic_2d_h_