00001 /*---------------------------------------------------------------------+ 00002 | Library QgarLib, graphics analysis and recognition | 00003 | Copyright (C) 2002 Qgar Project, LORIA | 00004 | | 00005 | This library is free software; you can redistribute it and/or | 00006 | modify it under the terms of the GNU Lesser General Public | 00007 | License version 2.1, as published by the Free Software Foundation. | 00008 | | 00009 | This library is distributed in the hope that it will be useful, | 00010 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 00011 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 00012 | See the GNU Lesser General Public License for more details. | 00013 | | 00014 | The GNU Lesser General Public License is included in the file | 00015 | LICENSE.LGPL, in the root directory of the Qgar packaging. See | 00016 | http://www.gnu.org/licenses/lgpl.html for the terms of the licence. | 00017 | To receive a paper copy, write to the Free Software Foundation, | 00018 | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | 00019 | | 00020 | Contact Project Qgar for any information: | 00021 | LORIA - équipe Qgar | 00022 | B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France | 00023 | email: qgar-contact@loria.fr | 00024 | http://www.qgar.org/ | 00025 *---------------------------------------------------------------------*/ 00026 00027 00028 #ifndef ___QGAR_GENSEGMENT_H_INCLUDED__ 00029 #define ___QGAR_GENSEGMENT_H_INCLUDED__ 00030 00031 00032 /** 00033 * @file _QGAR_GenSegment.H 00034 * @brief Header file of class qgar::GenSegment. 00035 * 00036 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a> 00037 * @date December 14, 2004 18:28 00038 * @since Qgar 2.2 00039 */ 00040 00041 00042 // For RCS/CVS use: Do not delete 00043 /* $Id: _QGAR_GenSegment.H,v 1.6 2005/10/14 17:05:48 masini Exp $ */ 00044 00045 00046 00047 // STD 00048 #include <iosfwd> // Avoid including classes when not necessary 00049 // QGAR 00050 #include <qgarlib/ISerializable.H> 00051 #include <qgarlib/math.H> 00052 00053 00054 00055 namespace qgar 00056 { 00057 00058 00059 /** 00060 * @class GenSegment _QGAR_GenSegment.H "qgarlib/GenSegment.H" 00061 * @ingroup DS_PRIM_GEOM 00062 * @brief Geometrical segment, with coordinates of type <b>T</b>. 00063 * 00064 * <ul> 00065 * 00066 * <li> 00067 @verbatim 00068 O 00069 +---------------> X 00070 |\ | 00071 | \ <-' 00072 | \ angle (in radians, unless specified) 00073 | \ 00074 | 00075 v 00076 00077 Y 00078 @endverbatim 00079 * The origin of the coordinate system is at top left corner 00080 * and angles are clockwise from the X axis. 00081 * </li> 00082 * 00083 * <li> 00084 @verbatim 00085 O 00086 +---------------> X 00087 | 00088 | + source 00089 | / 00090 | / 00091 | v 00092 | + target 00093 v 00094 00095 Y 00096 @endverbatim 00097 * A segment is oriented: It is provided with a so-called 00098 * <i>source point</i> and a so-called <i>target point</i>, 00099 * which determine the orientation of the vector representing 00100 * the segment in geometrical computations. 00101 * 00102 * Computational geometry equations can be found in the FAQ section 00103 * of comp.graphics.algorithms and are based on 00104 * [<a href="Bibliography.html#Kirk-1992">Kirk, 1992</a>], 00105 * pages 199-202, and 00106 * [<a href="Bibliography.html#ORourke-1994">O'Rourke, 1994</a>], 00107 * pages 249-51. 00108 * </li> 00109 * 00110 * <li> 00111 * Predefined types: 00112 * qgar::Segment, 00113 * qgar::ISegment, 00114 * qgar::FSegment, 00115 * qgar::DSegment. 00116 * </li> 00117 * 00118 * <li> 00119 * A segment has no attribute. For <i>graphical</i> segments, 00120 * typically resulting from vectorization and provided with attributes 00121 * (thickness, color, outline), see class qgar::GenQgarSegment. 00122 * </li> 00123 * 00124 * </ul> 00125 * 00126 * 00127 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a> 00128 * @date June 23, 2003 15:05 00129 * @since Qgar 1.0 00130 */ 00131 template <class T> class GenSegment 00132 00133 : public AbstractGenPrimitive<T>, 00134 public ISerializable 00135 00136 { 00137 // ------------------------------------------------------------------- 00138 // T Y P E D E F I N I T I O N S 00139 // ------------------------------------------------------------------- 00140 public: 00141 00142 00143 /** @name Types */ 00144 // ===== 00145 //@{ 00146 00147 /** 00148 * @brief Type of the source and target coordinates. 00149 */ 00150 typedef T value_type; 00151 00152 /** 00153 * @brief Reference to qgar::GenSegment::value_type. 00154 */ 00155 typedef value_type& reference; 00156 00157 /** 00158 * @brief Constant reference to qgar::GenSegment::value_type. 00159 */ 00160 typedef const value_type& const_reference; 00161 00162 /** 00163 * @brief Pointer to qgar::GenSegment::value_type. 00164 */ 00165 typedef value_type* pointer; 00166 00167 /** 00168 * @brief Constant pointer to qgar::GenSegment::value_type. 00169 */ 00170 typedef const value_type* const_pointer; 00171 00172 //@} 00173 00174 00175 // ------------------------------------------------------------------- 00176 // P U B L I C M E M B E R S 00177 // ------------------------------------------------------------------- 00178 public: 00179 00180 00181 /** @name Constructors */ 00182 // ============ 00183 //@{ 00184 00185 /** 00186 * @brief Default constructor. 00187 * 00188 * Zero-length segment located at the origin of the coordinate system. 00189 * 00190 * @todo The created segment does not conform 00191 * to the definition of a segment! 00192 */ 00193 GenSegment(); 00194 00195 /** 00196 * @brief Copy constructor. 00197 */ 00198 GenSegment(const GenSegment<value_type>& aSeg); 00199 00200 /** 00201 * @brief Initialize from a Qgar segment. 00202 * 00203 * @param aQSeg a Qgar segment 00204 * 00205 * @warning This kind of conversion must be explicitely 00206 * specified by the client. 00207 */ 00208 explicit GenSegment(const GenQgarSegment<value_type>& aQSeg); 00209 00210 /** 00211 * @brief Initialize from source and target points. 00212 * 00213 * @param aSource source point 00214 * @param aTarget target point 00215 */ 00216 GenSegment(const GenPoint<value_type>& aSource, 00217 const GenPoint<value_type>& aTarget); 00218 00219 /** 00220 * @brief Initialize from coordinates. 00221 * 00222 * @param aXSource X coordinate of the source point 00223 * @param aYSource Y coordinate of the source point 00224 * @param aXTarget X coordinate of the target point 00225 * @param aYTarget X coordinate of the target point 00226 */ 00227 GenSegment(const value_type aXSource, 00228 const value_type aYSource, 00229 const value_type aXTarget, 00230 const value_type aYTarget); 00231 00232 //@} 00233 00234 00235 /**@name Destructor */ 00236 // ========== 00237 //@{ 00238 00239 /** 00240 * @brief Virtual destructor. 00241 */ 00242 virtual ~GenSegment(); 00243 00244 //@} 00245 00246 00247 /**@name Copy */ 00248 // ==== 00249 //@{ 00250 00251 /** 00252 * @brief Return a deep copy of the surrent segment. 00253 */ 00254 virtual GenSegment<value_type>* clone() const; 00255 00256 //@} 00257 00258 00259 /** @name Access to geometrical features */ 00260 // ============================== 00261 //@{ 00262 00263 /** 00264 * @brief Get length of the segment. 00265 */ 00266 inline double length() const; 00267 00268 /** 00269 * @brief Get squared length of the segment. 00270 */ 00271 double sqr_length() const; 00272 00273 /** 00274 * @brief Distance between point <b>(0,0)</b> and its perpendicular 00275 * projection onto the line supporting the segment. 00276 * 00277 * Always positive. 00278 */ 00279 double rho() const; 00280 00281 /** 00282 * @brief Angle between the X axis and the segment, 00283 * in <b>[0,2PI[</b> radians. 00284 * 00285 @verbatim 00286 ----->/ 00287 O O / / 00288 +------------------> X +---------|-------------> X 00289 | \ | | | / | 00290 | \ <-' angle | angle \_ /__/ 00291 | \ | / 00292 | + source | + target 00293 | \ | ^ 00294 | \ | / 00295 | v | / 00296 v + target v + source 00297 00298 Y Y 00299 @endverbatim 00300 * 00301 * @warning The current segment is assimilited to a vector 00302 * joining its source to its target. 00303 */ 00304 inline double theta() const; 00305 00306 /** 00307 * @brief Same as qgar::GenSegment::theta. 00308 */ 00309 inline double angle() const; 00310 00311 /** 00312 * @brief Angle between the X axis and the segment, 00313 * in <b>[0,PI[</b> radians. 00314 * 00315 @verbatim 00316 O O 00317 +------------------> X +-----------------> X 00318 | \ | | \ | 00319 | \ <-' angle | \ <-' angle 00320 | \ | \ 00321 | + source | + target 00322 | \ | \ 00323 | \ | \ 00324 | \ | \ 00325 v + target v + source 00326 00327 Y Y 00328 @endverbatim 00329 * 00330 * @warning The current segment is not assimilited to a vector. 00331 */ 00332 inline double slope() const; 00333 00334 /** 00335 * @brief Same as qgar::GenSegment::theta, 00336 * but the result is given in <b>[0,360[</b> degrees. 00337 */ 00338 inline double thetaDegrees() const; 00339 00340 /** 00341 * @brief Same as qgar::GenSegment::theta, 00342 * but the result is given in <b>[0,360[</b> degrees. 00343 */ 00344 inline double angleDegrees() const; 00345 00346 /** 00347 * @brief Same as qgar::GenSegment::slope, 00348 * but the result is given in <b>[0,180[</b> degrees. 00349 */ 00350 inline double slopeDegrees() const; 00351 00352 //@} 00353 00354 00355 /**@name Geometrical predicates */ 00356 // ====================== 00357 //@{ 00358 00359 /** 00360 * @brief Return <b>true</b> if the given point approximately 00361 * belongs to the current segment. 00362 * 00363 * Here, ''to belong'' means to be at a distance smaller or equal 00364 * to the given threshold from somed point between the source 00365 * and the target of the segment. 00366 * 00367 * @param c a point 00368 * @param aDist threshold used to decide whether the given point 00369 * belongs to the segment (default qgar::Math::epsilonD) 00370 * 00371 * @todo Use values computed for 'r' to get the distance between 00372 * the point and the segment, instead of using function qgar::qgDist, 00373 * which computes again these values. 00374 */ 00375 inline bool 00376 contains(const GenPoint<T>& c, double aDist = Math::epsilonD()); 00377 00378 //@} 00379 00380 00381 /**@name Operators */ 00382 // ========= 00383 //@{ 00384 00385 /** 00386 * @brief Assignment. 00387 * 00388 * @param aSeg a segment 00389 */ 00390 inline GenSegment<value_type>& 00391 operator=(const GenSegment<value_type>& aSeg); 00392 00393 /** 00394 * @brief Same as function qgar::GenSegment::eq 00395 */ 00396 inline bool 00397 operator==(const GenSegment<value_type>& aSeg) const; 00398 00399 /** 00400 * @brief Same as function qgar::GenSegment::notEq. 00401 */ 00402 inline bool 00403 operator!=(const GenSegment<value_type>& aSeg) const; 00404 00405 //@} 00406 00407 00408 /**@name Functional operators */ 00409 // ==================== 00410 //@{ 00411 00412 /** 00413 * @brief Equality. 00414 * 00415 * @param aSeg a segment 00416 * 00417 * @return <b>true</b> if the current segment 00418 * and the given segment have the same coordinates. 00419 */ 00420 bool eq(const GenSegment<value_type>& aSeg) const; 00421 00422 /** 00423 * @brief Inequality. 00424 * 00425 * @param aSeg a segment 00426 * 00427 * @return <b>true</b> if the coordinates of the current 00428 * and given segments are different. 00429 */ 00430 bool notEq(const GenSegment<value_type>& aSeg) const; 00431 00432 //@} 00433 00434 00435 /**@name Geometry: Translation */ 00436 // ===================== 00437 //@{ 00438 00439 /** 00440 * @brief Translate current segment along X and Y axis. 00441 * 00442 * @param aTransX X translation factor 00443 * @param aTransY Y translation factor 00444 */ 00445 virtual void translate(value_type aTransX, value_type aTransY); 00446 00447 //@} 00448 00449 00450 /** @name Serialization/deserialization */ 00451 // ============================= 00452 //@{ 00453 00454 /** 00455 * @brief Deserializes the current segment from an input stream. 00456 * 00457 * A serialized segment is represented as: 00458 @verbatim 00459 Segment(<SOURCE>)(<TARGET>) 00460 @endverbatim 00461 * 00462 * @param anInStream the input stream 00463 * 00464 * @see qgar::qgReadObjName, qgar::qgReadObjData 00465 */ 00466 virtual std::istream& read(std::istream& anInStream); 00467 00468 /** 00469 * @brief Serializes the current segment to an input stream. 00470 * 00471 * A serialized segment is represented as: 00472 @verbatim 00473 Segment(<SOURCE>)(<TARGET>) 00474 @endverbatim 00475 * 00476 * @param anOutStream the output stream 00477 */ 00478 virtual std::ostream& write(std::ostream& anOutStream) const; 00479 00480 //@} 00481 00482 00483 // ------------------------------------------------------------------- 00484 // P R O T E C T E D M E M B E R S 00485 // ------------------------------------------------------------------- 00486 protected: 00487 00488 00489 /** @name Updates subsequent to source and target modifications */ 00490 // ===================================================== 00491 //@{ 00492 00493 /** 00494 * @brief Update the geometrical structure 00495 * when the source has been changed. 00496 * 00497 * Inherited from qgar::AbstractGenPrimitive. 00498 */ 00499 virtual void updateSource(); 00500 00501 /** 00502 * @brief Update the geometrical structure 00503 * when the target has been changed. 00504 */ 00505 virtual void updateTarget(); 00506 00507 /** 00508 * @brief Update the geometrical structure 00509 * when both source and target have been changed. 00510 */ 00511 virtual void updateSourceTarget(); 00512 00513 //@} 00514 00515 00516 // ------------------------------------------------------------------- 00517 }; // class GenSegment 00518 00519 00520 00521 00522 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT 00523 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT 00524 // P R E D E F I N E D S E G M E N T T Y P E S 00525 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT 00526 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT 00527 00528 00529 /** @name Segment types */ 00530 // ============= 00531 //@{ 00532 00533 /** 00534 * @brief Segment with <b>integer</b> coordinates. 00535 * @ingroup DS_PRIM_GEOM 00536 * 00537 * @see qgar::ISegment 00538 */ 00539 typedef GenSegment<int> Segment; 00540 00541 /** 00542 * @brief Segment with <b>integer</b> coordinates. 00543 * @ingroup DS_PRIM_GEOM 00544 * 00545 * @see qgar::Segment 00546 */ 00547 typedef GenSegment<int> ISegment; 00548 00549 /** 00550 * @brief Segment with <b>float</b> coordinates. 00551 * @ingroup DS_PRIM_GEOM 00552 */ 00553 typedef GenSegment<float> FSegment; 00554 00555 /** 00556 * @brief Segment with <b>double</b> coordinates. 00557 * @ingroup DS_PRIM_GEOM 00558 */ 00559 typedef GenSegment<double> DSegment; 00560 00561 //@} 00562 00563 00564 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT 00565 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT 00566 00567 00568 } // namespace qgar 00569 00570 00571 #endif /* ___QGAR_GENSEGMENT_H_INCLUDED__ */