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_