Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

FreemanCode.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------*
00002  | Library QgarLib, graphics analysis and recognition                  |
00003  | Copyright (C) 2004  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 license. |
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 __FREEMANCODE_H_INCLUDED__
00029 #define __FREEMANCODE_H_INCLUDED__
00030 
00031 
00032 /**
00033  * @file     FreemanCode.H
00034  * @brief    Header file of class qgar::FreemanCode.
00035  *
00036  * @author   <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00037  * @date     February 3, 2004  17:17
00038  * @since    Qgar 2.1.1
00039  */
00040 
00041 
00042 // For RCS/CVS use: Do not delete.
00043 /* $Id: FreemanCode.H,v 1.14 2005/10/14 17:05:46 masini Exp $ */
00044 
00045 
00046 
00047 // STD
00048 #include <iostream>
00049 #include <string>
00050 // QGAR
00051 #include <qgarlib/image.H>
00052 #include <qgarlib/ISerializable.H>
00053 #include <qgarlib/primitives.H>
00054 #include <qgarlib/QgarErrorInvalidArg.H>
00055 
00056 
00057 
00058 namespace qgar
00059 {
00060 
00061 
00062 /**
00063  * @class FreemanCode FreemanCode.H "qgarlib/FreemanCode.H"
00064  * @ingroup DS_POINT
00065  * @brief A Freeman code, defined as a pair (direction, length).
00066  * 
00067  * A direction is coded using predefined enum type qgar::QGEdirection.
00068  * As the origin of the coordinates system in images is at top left
00069  * corner, North and South are upside down for more convenience:
00070 @verbatim
00071   (0,0) +---------------------------------------------> X
00072         |
00073         |                 QGE_DIRECTION_N
00074         |                        |  
00075         |     QGE_DIRECTION_NW \ | / QGE_DIRECTION_NE
00076         |                       \|/
00077         |   QGE_DIRECTION_W -----+----- QGE_DIRECTION_E
00078         |                       /|\
00079         |     QGE_DIRECTION_SW / | \ QGE_DIRECTION_SE
00080         |                        |
00081         |                 QGE_DIRECTION_S
00082       Y V
00083 @endverbatim
00084  *
00085  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00086  * @date   February 3, 2004  17:17
00087  * @since  Qgar 2.1.1
00088  */
00089 class FreemanCode
00090 
00091   : public ISerializable
00092 
00093 {
00094 // -------------------------------------------------------------------
00095 // P U B L I C    M E M B E R S
00096 // -------------------------------------------------------------------
00097 public:
00098 
00099   /** @name Constructors */
00100   //        ============
00101   //@{
00102   /**
00103    * @brief Default constructor.
00104    *
00105    * Direction is initialized to <b>qgar::QGE_DIRECTION_N</b>
00106    * and length to <b>0</b>.
00107    */
00108   FreemanCode();
00109 
00110   /**
00111    * @brief Copy constructor.
00112    * @param aCode  a Freeman code
00113    */
00114   FreemanCode(const FreemanCode& aCode);
00115 
00116   /**
00117    * @brief Initialize with a direction and a length.
00118    * @param aDir     a direction
00119    * @param aLength  a length
00120    *
00121    * @warning Length may be initialized to <b>0</b>.
00122    */
00123   FreemanCode(QGEdirection aDir, unsigned int aLength);
00124   //@}
00125 
00126 
00127   /** @name Destructor */
00128   //        ==========
00129   //@{
00130   /**
00131    * @brief Virtual destructor.
00132    */
00133   virtual ~FreemanCode();
00134   //@}
00135 
00136 
00137   /** @name Access */
00138   //        ======
00139   //@{
00140   /**
00141    * @brief Get direction.
00142    */
00143   inline QGEdirection direction() const;
00144 
00145   /**
00146    * @brief Get length.
00147    */
00148   inline int length() const;
00149   //@}
00150 
00151 
00152   /** @name Transformation */
00153   //        ==============
00154   //@{
00155   /**
00156    * @brief Set direction.
00157    * @param aDir  a direction
00158    */
00159   inline void setDir(QGEdirection aDir);
00160 
00161   /**
00162    * @brief Set length.
00163    * @param aLength  a direction
00164    *
00165    * @warning Length may be initialized to <b>0</b>.
00166    */
00167   inline void setLength(unsigned int aLength);
00168 
00169   /**
00170    * @brief Set both direction and length.
00171    * @param aDir     a direction
00172    * @param aLength  a length
00173    *
00174    * @warning Length may be initialized to <b>0</b>.
00175    */
00176   inline void setDirLength(QGEdirection aDir, unsigned int aLength);
00177   //@}
00178 
00179 
00180   /** @name Conversions */
00181   //        ===========
00182   //@{
00183   /**
00184    * @brief Return the point at the location defined by the current Freeman
00185    *        code, starting from the given point.
00186    * @param aPt  a point
00187    *
00188    * @exception qgar::QgarErrorInvalidArg (unknown direction)
00189    */
00190   template <class T>
00191   GenPoint<T> toPoint(const GenPoint<T>& aPt) const;
00192 
00193   /**
00194    * @brief Return the point at the location defined by the current Freeman
00195    *        code, whose direction is changed into its opposite, starting
00196    *        from the given point.
00197    * @param aPt  a point
00198    *
00199    * @exception qgar::QgarErrorInvalidArg (unknown direction)
00200    */
00201   template <class T>
00202   GenPoint<T> toOppositePoint(const GenPoint<T>& aPt) const;
00203   //@}
00204 
00205 
00206   /** @name Operators */
00207   //        =========
00208   //@{
00209   /**
00210    * @brief Assignment operator.
00211    * @param aCode  a Freeman code
00212    */
00213   FreemanCode& operator=(const FreemanCode& aCode);
00214   //@}
00215 
00216 
00217   /** @name Serialization/deserialization */
00218   //        =============================
00219   //@{
00220   /**
00221    * @brief Deserializes the current Freeman code from an input stream.
00222    * @param anInStream  the input stream
00223    *
00224    * A serialized Freeman code is represented as:
00225 @verbatim
00226 FreemanCode ( <DIRECTION> ) ( <LENGTH> )
00227 @endverbatim
00228    *
00229    * @see qgar::qgReadObjName, qgar::qgReadObjData
00230    */
00231   virtual std::istream& read(std::istream& anInStream);
00232 
00233 
00234   /**
00235    * @brief Serializes the current Freeman code to an input stream.
00236    * @param anOutStream  the output stream
00237    *
00238    * A serialized Freeman code is represented as:
00239 @verbatim
00240 FreemanCode ( <DIRECTION> ) ( <LENGTH> )
00241 @endverbatim
00242    */
00243   virtual std::ostream& write(std::ostream& anOutStream) const;
00244   //@}
00245 
00246 // -------------------------------------------------------------------
00247 // P R O T E C T E D    M E M B E R S
00248 // -------------------------------------------------------------------
00249 protected:
00250 
00251   /** @name Representation of a Freeman code */
00252   //        ================================
00253   //@{
00254   /**
00255    * @brief The direction code.
00256    */
00257   QGEdirection _direction;
00258 
00259   /**
00260    * @brief The length.
00261    */
00262   int _length;
00263   //@}
00264 
00265 // -------------------------------------------------------------------
00266 // P R I V A T E    M E M B E R S
00267 // -------------------------------------------------------------------
00268 private:
00269 
00270   /** @name Auxiliaries */
00271   //        ===========
00272   //@{
00273   /**
00274    * @brief Return the point located at given length in given direction
00275    *        from the given point.
00276    * @param aPt      a point
00277    * @param aDir     a direction
00278    * @param aLength  a length
00279    */
00280   template <class T>
00281   GenPoint<T> toPointAUX(const GenPoint<T>& aPt,
00282                          QGEdirection aDir,
00283                          unsigned int aLength) const
00284     throw(QgarErrorInvalidArg);
00285   //@}
00286 
00287 // -------------------------------------------------------------------
00288 }; // class FreemanCode
00289 
00290 
00291 
00292 
00293 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00294 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00295 // I N L I N E    F U N C T I O N S    I M P L E M E N T A T I O N
00296 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00297 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00298 
00299 
00300 // ======
00301 // ACCESS
00302 // ======
00303 
00304 // Get direction
00305 
00306 QGEdirection
00307 FreemanCode::direction() const
00308 {
00309   return _direction;
00310 }
00311 
00312 // Get length
00313 
00314 int
00315 FreemanCode::length() const
00316 {
00317   return _length;
00318 }
00319 
00320 
00321 // ==============
00322 // TRANSFORMATION
00323 // ==============
00324 
00325 // Set direction
00326 
00327 void
00328 FreemanCode::setDir(QGEdirection aDir)
00329 {
00330   _direction = aDir;
00331 }
00332 
00333 // Set length
00334 
00335 void
00336 FreemanCode::setLength(unsigned int aLength)
00337 {
00338   _length = aLength;
00339 }
00340 
00341 // Set both direction and length
00342 
00343 void
00344 FreemanCode::setDirLength(QGEdirection aDir, unsigned int aLength)
00345 {
00346   _direction = aDir;
00347   _length    = aLength;
00348 }
00349 
00350 
00351 // ===========
00352 // CONVERSIONS
00353 // ===========
00354 
00355 // Apply the current Freeman code to the given point
00356 
00357 template <class T>
00358 GenPoint<T>
00359 FreemanCode::toPoint(const GenPoint<T>& aPt) const
00360 {
00361   return toPointAUX(aPt, _direction, _length);
00362 }
00363 
00364 
00365 // Apply the current Freeman code to the given point, in the opposite direction
00366 
00367 template <class T>
00368 GenPoint<T>
00369 FreemanCode::toOppositePoint(const GenPoint<T>& aPt) const
00370 {
00371   return toPointAUX(aPt, qgOpposite(_direction), _length);
00372 }
00373 
00374 
00375 // ===========
00376 // AUXILIARIES
00377 // ===========
00378 
00379 // RETURN THE POINT LOCATED IN GIVEN DIRECTION AT GIVEN LENGTH
00380 // FROM THE GIVEN POINT.
00381 
00382 template <class T>
00383 GenPoint<T>
00384 FreemanCode::toPointAUX(const GenPoint<T>& aPt,
00385                         QGEdirection aDir,
00386                         unsigned int aLength) const
00387 
00388   throw(QgarErrorInvalidArg)
00389 
00390 {
00391   switch (aDir)
00392     {
00393     case QGE_DIRECTION_N:
00394       {
00395         return GenPoint<T>(aPt.x(), aPt.y() - aLength);
00396       }
00397     case QGE_DIRECTION_NE:
00398       {
00399         return GenPoint<T>(aPt.x() + aLength, aPt.y() - aLength);
00400       }
00401     case QGE_DIRECTION_E:
00402       {
00403         return GenPoint<T>(aPt.x() + aLength, aPt.y());
00404       }
00405     case QGE_DIRECTION_SE:
00406       {
00407         return GenPoint<T>(aPt.x() + aLength, aPt.y() + aLength);
00408       }
00409     case QGE_DIRECTION_S:
00410       {
00411         return GenPoint<T>(aPt.x(), aPt.y() + aLength);
00412       }
00413     case QGE_DIRECTION_SW:
00414       {
00415         return GenPoint<T>(aPt.x() - aLength, aPt.y() + aLength);
00416       }
00417     case QGE_DIRECTION_W:
00418       {
00419         return GenPoint<T>(aPt.x() - aLength, aPt.y());
00420       }
00421     case QGE_DIRECTION_NW:
00422       {
00423         return GenPoint<T>(aPt.x() - aLength, aPt.y() - aLength);
00424       }
00425     default:
00426       {
00427         // *************************************************************
00428         // CONTROL SHOULD NEVER REACH THIS POINT
00429         // *************************************************************
00430         std::ostringstream os;
00431         os << "Unknown direction: "
00432            << aDir;
00433         throw QgarErrorInvalidArg(__FILE__, __LINE__,
00434                                   "template <class T> qgar::GenPoint<T> qgar::FreemanCode::toPointAUX(const qgar::GenPoint<T>&, qgar::QGEdirection, unsigned int) const",
00435                                   os.str());
00436         // *************************************************************
00437       }
00438     }
00439 }
00440 
00441 
00442 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00443 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00444 // E N D   O F    F U N C T I O N S    I M P L E M E N T A T I O N
00445 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00446 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00447 
00448 
00449 } // namespace qgar
00450 
00451 
00452 #endif /* __FREEMANCODE_H_INCLUDED__ */