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

FreemanChain.H

Go to the documentation of this file.
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 __FREEMANCHAIN_H_INCLUDED__
00029 #define __FREEMANCHAIN_H_INCLUDED__
00030 
00031 
00032 /**
00033  * @file   FreemanChain.H
00034  * @brief  Header file of class qgar::FreemanChain.
00035  *
00036  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00037  * @date   December 19, 2003  17:30
00038  * @since  Qgar 2.1.1
00039  */
00040 
00041 
00042 // For RCS/CVS use: Do not delete
00043 /* $Id: FreemanChain.H,v 1.15 2005/07/13 16:29:01 masini Exp $ */
00044 
00045 
00046 
00047 // STL
00048 #include <list>
00049 // QGAR
00050 #include <qgarlib/AbstractGenPointChain.H>
00051 #include <qgarlib/FreemanCode.H>
00052 namespace qgar
00053 {
00054   // Avoid #include's when not necessary
00055   template <class T> class GenPoint;
00056 }
00057 
00058 
00059 
00060 namespace qgar
00061 {
00062 
00063 
00064 /**
00065  * @class FreemanChain FreemanChain.H "qgarlib/FreemanChain.H"
00066  * @ingroup DS_POINT
00067  * @brief Chain of Freeman codes.
00068  *
00069  * A Freeman chain represents a series of consecutive points,
00070  * <b>in an integer (<i>i.e.</i> discrete) coordinate system</b>.
00071  * It is coded as a series of <b>integer</b> vectors,
00072  * defined by pairs (direction, length), starting from a point
00073  * of given coordinates:
00074 @verbatim
00075                                      etc.
00076                                       *
00077                                      *
00078                             POINT-2 @ ^
00079                                     * |
00080                                     * |
00081                                   ^ * |
00082                                   | * |
00083                       DIRECTION-2 | * LENGTH-2
00084                                   | * |
00085                                     * |
00086                                     * |
00087   (STARTING)      DIRECTION-1 -->   * |
00088     POINT-0  @**********************@ V
00089              <------ LENGTH-1 ------> POINT-1
00090 @endverbatim
00091  *
00092  * A direction is coded using predefined enum type qgar::QGEdirection.
00093  * As the origin of the coordinates system in images is at top left
00094  * corner, North and South are upside down for more convenience:
00095 @verbatim
00096   (0,0) +---------------------------------------------> X
00097         |
00098         |                 QGE_DIRECTION_N
00099         |                        |  
00100         |     QGE_DIRECTION_NW \ | / QGE_DIRECTION_NE
00101         |                       \|/
00102         |   QGE_DIRECTION_W -----+----- QGE_DIRECTION_E
00103         |                       /|\
00104         |     QGE_DIRECTION_SW / | \ QGE_DIRECTION_SE
00105         |                        |
00106         |                 QGE_DIRECTION_S
00107       Y V
00108 @endverbatim
00109  *
00110  * A Freeman chain is implemented using a STL list of Freeman codes,
00111  * instances of class qgar::FreemanCode:
00112 @verbatim
00113                                      _iter  (current point)
00114                                        |
00115                                        V
00116                +-----+    +----+    +----+             +----+
00117                |North|    | D1 |    | D2 |             | Dn |
00118      _chain    +-----+<==>+----+<==>+----+<==> ... <==>+----+
00119                |  0  |    | L1 |    | L2 |             | Ln |
00120                +-----+    +----+    +----+             +----+
00121 
00122 @endverbatim
00123  * The direction of the first code is always North (qgar::QGE_DIRECTION_N,
00124  * the first value of the qgar::QGEdirection predefined enum type)
00125  * and the length of the first code is always <b>0</b>: The first code
00126  * represents the first point of the chain (a null vector from the given
00127  * starting point). In this way, the complete chain of points is
00128  * consistently coded, which allows easier algorithm implementations.
00129  *
00130  * An (internal) iterator, qgar::FreemanChain::_iter, allows bidirectional
00131  * traversal of the chain. The validity of the iterator is preserved by any
00132  * legal operation on the chain, unless the chain is empty.
00133  *
00134  * Three points are permanently available as effective points, <i>i.e.</i>
00135  * instances of class qgar::GenPoint<int>:
00136  * - the starting/first point of the chain (qgar::FreemanChain::_first),
00137  * - the current point of the chain (qgar::FreemanChain::_current),
00138  *   that is pointed by iterator qgar::FreemanChain::_iter
00139  * - the last point of the chain (qgar::FreemanChain::_last)
00140  *
00141  * Use cases of a Freeman chain:
00142  * - To set the iterator to the beginning (resp. end) of the chain,
00143  *   function qgar::FreemanChain::setToBegin
00144  *   (resp. qgar::FreemanChain::setToEnd)
00145  * - To test if the iterator points to the beginning (resp. end)
00146  *   of the chain, function qgar::FreemanChain::isAtBegin
00147  *   (resp. qgar::FreemanChain::isAtEnd)
00148  * - To test if the chain includes at least one point after (resp. before)
00149  *   the current point,  function qgar::FreemanChain::hasNext
00150  *   (resp. qgar::FreemanChain::hasPrevious)
00151  * - To move to the next (resp. previous) point, function
00152  *   qgar::FreemanChain::moveNext (resp. qgar::FreemanChain::movePrevious)
00153  * - To get the current point, functions qgar::FreemanChain::current
00154  *   or qgar::FreemanChain::accessCurrent
00155  * - To get the next (resp. previous) point, functions
00156  *   qgar::FreemanChain::next or qgar::FreemanChain::accessNext
00157  *   (resp. qgar::FreemanChain::previous or qgar::FreemanChain::accessPrevious)
00158  * - To insert a new point at the beginning (resp. end) of the chain,
00159  *   function qgar::FreemanChain::push_front
00160  *   (resp. qgar::FreemanChain::push_back)
00161  *
00162  * @warning <b>A Freeman chain is not an appropriate way of representing
00163  * a chain of points if efficiency is required for insertions or chain
00164  * traversals.</b> Class qgar::GenPointChain should be better used in this
00165  * case. A STL list of the points coded by a Freeman chain can be also
00166  * obtained using function qgar::FreemanChain::pointList.
00167  *
00168  * @author  <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>,
00169  *          from previous work by Karl Tombre
00170  * @date    December 19, 2003  17:30
00171  * @since   Qgar 2.1.1
00172  */
00173 class FreemanChain
00174 
00175   : public AbstractGenPointChain<int>
00176 
00177 {
00178 // -------------------------------------------------------------------
00179 // P U B L I C    M E M B E R S
00180 // -------------------------------------------------------------------
00181 public:
00182 
00183   /** @name Constructors */
00184   //        ============
00185   //@{
00186 
00187   ///**
00188   // * @brief Default constructor.
00189   // *
00190   // * @warning No default constructor is defined. 
00191   // */
00192   //FreemanChain();
00193 
00194   /**
00195    * @brief Copy constructor.
00196    *
00197    * @param aFreemanCh  a Freeman chain
00198    *
00199    * @warning The iterator points to the beginning of the chain.
00200    */
00201   FreemanChain(const FreemanChain& aFreemanCh);
00202 
00203   /**
00204    * @brief Construct from a point, that becomes the current point.
00205    * @param aPt  a point (integer coordinates)
00206    *
00207    * The iterator points to this point.
00208    */
00209   FreemanChain(const GenPoint<int>& aPt);
00210 
00211   /**
00212    * @brief Construct from given point, direction and length.
00213    *
00214    * @param aPt       a point (integer coordinates)
00215    * @param aDir      direction code of the initial part of chain
00216    * @param aLength   length of the initial part of chain
00217    *
00218    * The iterator points to the end of the chain.
00219    *
00220    * @warning The given length is supposed to be different from zero.
00221    * Otherwise, the validity of the resulting chain is absolutely not
00222    * guaranteed.
00223    */
00224   FreemanChain(const GenPoint<int>& aPt,
00225                QGEdirection aDir,
00226                unsigned int aLength);
00227 
00228   //@}
00229 
00230 
00231   /** @name Destructor */
00232   //        ==========
00233   //@{
00234 
00235   /**
00236    * @brief Virtual destructor.
00237    */
00238   virtual ~FreemanChain();
00239 
00240   //@}
00241 
00242 
00243   /** @name Access to chain characteristics */
00244   //        ===============================
00245   //@{
00246 
00247   /**
00248    * @brief Is current chain empty?
00249    */
00250   virtual bool empty() const;
00251   
00252   /**
00253    * @brief Get chain length (number of points).
00254    */
00255   virtual int size() const;
00256 
00257   //@}
00258 
00259 
00260   /** @name Iterator */
00261   //        ========
00262   //@{
00263 
00264   /**
00265    * @brief Make the internal iterator point to the beginning
00266    *        (first point) of the chain, that becomes the current point.
00267    *
00268    * @warning The chain is supposed not to be empty.
00269    */
00270   virtual void setToBegin();
00271 
00272   /**
00273    * @brief Make the internal iterator point to the end
00274    *        (last point) of the chain, that becomes the current point.
00275    *
00276    * @warning The chain is supposed not to be empty.
00277    */
00278   virtual void setToEnd();
00279 
00280   /**
00281    * @brief Does internal iterator points to the beginning of the chain?
00282    */
00283   virtual bool isAtBegin() const;
00284 
00285   /**
00286    * @brief Does internal iterator points to the end of the chain?
00287    */
00288   virtual bool isAtEnd() const;
00289 
00290   /**
00291    * @brief Is there a point after the current point?
00292    *
00293    * @warning The chain is supposed not to be empty.
00294    */
00295   virtual bool hasNext() const;
00296   
00297   /**
00298    * @brief Is there a point before the current point?
00299    *
00300    * @warning The chain is supposed not to be empty.
00301    */
00302   virtual bool hasPrevious() const;
00303   
00304   /**
00305    * @brief Move to next point, that becomes the current point.
00306    *
00307    * @warning The chain is supposed not to be empty.
00308    */
00309   virtual void moveNext();
00310 
00311   /**
00312    * @brief Move to previous point, that becomes the current point.
00313    *
00314    * @warning The chain is supposed not to be empty.
00315    */
00316   virtual void movePrevious();
00317 
00318   //@}
00319 
00320 
00321   /** @name Access to points */
00322   //        ================
00323   //@{
00324 
00325   /**
00326    * @brief Get the first point.
00327    *
00328    * @warning The chain is supposed not to be empty.
00329    */
00330   virtual const GenPoint<int>& accessFront() const;
00331 
00332   /**
00333    * @brief Get a copy of the first point.
00334    *
00335    * @warning The chain is supposed not to be empty.
00336    */
00337   virtual GenPoint<int> front() const;
00338 
00339   /**
00340    * @brief Get the last point.
00341    *
00342    * @warning The chain is supposed not to be empty.
00343    */
00344   virtual const GenPoint<int>& accessBack() const;
00345 
00346   /**
00347    * @brief Get a copy of the last point.
00348    *
00349    * @warning The chain is supposed not to be empty.
00350    */
00351   virtual GenPoint<int> back() const;
00352 
00353   /**
00354    * @brief Get the current point.
00355    *
00356    * @warning The chain is supposed not to be empty.
00357    */
00358   virtual const GenPoint<int>& accessCurrent() const;
00359 
00360   /**
00361    * @brief Get a copy of the current point.
00362    *
00363    * @warning The chain is supposed not to be empty.
00364    */
00365   virtual GenPoint<int> current() const;
00366 
00367   /**
00368    * @brief Get the successor of the current point.
00369    *
00370    * @warning The chain is supposed not to be empty,
00371    * and the iterator is supposed not to point to the last point.
00372    */
00373   virtual const GenPoint<int>& accessNext();
00374 
00375   /**
00376    * @brief Get a copy of the successor of the current point.
00377    *
00378    * @warning The chain is supposed not to be empty,
00379    * and the iterator is supposed not to point to the last point.
00380    */
00381   virtual GenPoint<int> next();
00382 
00383   /**
00384    * @brief Get the predecessor of the current point.
00385    *
00386    * @warning The chain is supposed not to be empty,
00387    * and the iterator is supposed not to point to the first point.
00388    */
00389   virtual const GenPoint<int>& accessPrevious();
00390 
00391   /**
00392    * @brief Get a copy of the predecessor of the current point.
00393    *
00394    * @warning The chain is supposed not to be empty,
00395    * and the iterator is supposed not to point to the first point.
00396    */
00397   virtual GenPoint<int> previous();
00398 
00399   //@}
00400 
00401 
00402   /** @name Access to Freeman codes */
00403   //        =======================
00404   //@{
00405 
00406   /**
00407    * @brief Get the (STL) list of Freeman codes.
00408    *
00409    * The first element is an extra code including <b>qgar::QGE_DIRECTION_N</b>
00410    * as direction and <b>0</b> as length:
00411 @verbatim
00412     +-----+      +----+      +----+               +----+
00413     |North|      | D1 |      | D2 |               | Dn |
00414     +-----+ <==> +----+ <==> +----+ <==> ... <==> +----+
00415     |  0  |      | L1 |      | L2 |               | Ln |
00416     +-----+      +----+      +----+               +----+
00417 @endverbatim
00418    * This implementation allows an easier implementation of algorithms.
00419    *
00420    * Using this function to traverse the chain is much more efficient
00421    * than using appropriate member functions like
00422    * qgar::FreemanChain::setToBegin, qgar::FreemanChain::hasNext,
00423    * qgar::FreemanChain::moveNext, etc. In particular, the points
00424    * represented by the chain may be obtained by applying the successive
00425    * Freeman codes of the chain to a point initialized to the first point
00426    * of the chain, in the following way:
00427 @verbatim
00428     const std::list<FreemanCode>& lFc = myChain.accessCodesList();
00429     GenPoint<int> p = myChain.first();
00430 
00431     for (std::list<FreemanCode>::const_iterator it = lFc.begin();
00432          it != lFc.end();
00433          it++)
00434       {
00435         // Current point
00436         p = (*it).toPoint(p);
00437         // Processing continues...
00438         ...
00439       }
00440 @endverbatim
00441    */
00442   const std::list<FreemanCode>& accessCodesList() const;
00443 
00444   //@}
00445 
00446 
00447   /** @name Insertion */
00448   //        =========
00449   //@{
00450 
00451   /**
00452    * @brief Insert a point at the beginning of the chain.
00453    * @param aPt  a point
00454    *
00455    * @warning
00456    * - <b>When the chain is not empty, the new point is supposed
00457    *   to be consistent with the coding of the chain: All the points
00458    *   of the segment joining the first point of the chain to the
00459    *   new point must be strictly aligned along one of the 8 Freeman
00460    *   directions.</b>
00461    * - <b>A new point is always inserted in the chain, even when
00462    *   the given point is the same as the first point of the chain
00463    *   or is aligned with the first segment of the chain.</b>
00464    */
00465   virtual void push_front(const GenPoint<int>& aPt);
00466 
00467   /**
00468    * @brief Insert a point whose location is defined by the given
00469    *        Freeman code, starting from the first point of the chain.
00470    * @param aCode  a Freeman code
00471    *
00472    * @warning
00473    * - <b>The chain is supposed not to be empty.</b>
00474    * - <b>A new point is always inserted in the chain, even when
00475    *   the direction of the given Freeman code is the same as
00476    *   the direction of the first Freeman code of the chain, or when
00477    *   it is the opposite of the direction of the first Freeman code
00478    *   of the chain.</b> 
00479    */
00480   void push_front(const FreemanCode& aCode);
00481 
00482   /**
00483    * @brief Insert a point at the end of the chain.
00484    * @param aPt  a point
00485    *
00486    * @warning
00487    * - <b>When the chain is not empty, the new point is supposed
00488    *   to be consistent with the coding of the chain: All the points
00489    *   of the segment joining the last point of the chain to the
00490    *   new point must be strictly aligned along one of the 8 Freeman
00491    *   directions.</b>
00492    * - <b>A new point is always inserted in the chain, even when
00493    *   the given point is the same as the last point of the chain
00494    *   or is aligned with the last segment of the chain.</b>
00495    */
00496   virtual void push_back(const GenPoint<int>& aPt);
00497 
00498   /**
00499    * @brief Insert a point whose location is defined by the given
00500    *        Freeman code, starting from the last point of the chain.
00501    * @param aCode  a Freeman code
00502    *
00503    * @warning
00504    * - <b>The chain is supposed not to be empty.</b>
00505    * - <b>A new point is always inserted in the chain, when
00506    *   the direction of the given Freeman code is the same as
00507    *   the direction of the last Freeman code of the chain, or when
00508    *   it is the opposite of the direction of the last Freeman code
00509    *   of the chain.</b>
00510    */
00511   void push_back(const FreemanCode& aCode);
00512 
00513   //@}
00514 
00515 
00516   /** @name Transformations */
00517   //        ===============
00518   //@{
00519 
00520   /**
00521    * @brief Reverse elements order in the list.
00522    *
00523    * @warning The internal iterator points to the same <i>element</i>
00524    * of the chain (but the content of this element has changed) once
00525    * the operation is completed.
00526    */
00527   virtual void reverse();
00528 
00529   //@}
00530 
00531 
00532   /** @name Conversions */
00533   //        ===========
00534   //@{
00535 
00536   /**
00537    * @brief Convert into a (STL) list of points having integer coordinates.
00538    */
00539   virtual std::list< GenPoint<int> > toPointList() const;
00540 
00541   /**
00542    * @brief Convert into a (STL) list of points having float coordinates.
00543    */
00544   virtual std::list< GenPoint<float> > toFPointList() const;
00545 
00546   /**
00547    * @brief Convert into a (STL) list of points having double coordinates.
00548    */
00549   virtual std::list< GenPoint<double> > toDPointList() const;
00550 
00551   //@}
00552 
00553 
00554   /** @name Operators */
00555   //        =========
00556   //@{
00557 
00558   /**
00559    * @brief Assignment.
00560    * @param aFreemanCh  a Freeman chain
00561    *
00562    * @warning The internal iterator points to the beginning of the chain.
00563    */
00564   FreemanChain& operator=(const FreemanChain& aFreemanCh);
00565 
00566   //@}
00567 
00568 
00569 // -------------------------------------------------------------------
00570 // P R O T E C T E D    M E M B E R S
00571 // -------------------------------------------------------------------
00572 protected:
00573 
00574 
00575   /** @name Representation of a Freeman chain */
00576   //        =================================
00577   //@{
00578 
00579   /**
00580    * @brief The (STL) list of Freeman codes defining the points
00581    *        of the chain.
00582    */
00583   std::list<FreemanCode> _chain;
00584 
00585   /**
00586    * @brief Iterator on the list of Freeman codes.
00587    */
00588   std::list<FreemanCode>::iterator _iter;
00589 
00590   //@}
00591 
00592 
00593   /** @name Pre-computed points */
00594   //        ===================
00595   //@{
00596 
00597   /**
00598    * @brief First point of the chain.
00599    */
00600   GenPoint<int> _first;
00601 
00602   /**
00603    * @brief Current point of the chain.
00604    */
00605   GenPoint<int> _current;
00606 
00607   /**
00608    * @brief Last point of the chain.
00609    */
00610   GenPoint<int> _last;
00611 
00612   //@}
00613 
00614 
00615 // -------------------------------------------------------------------
00616 // P R I V A T E   M E M B E R S
00617 // -------------------------------------------------------------------
00618 private:
00619 
00620 
00621   /** @name Constructors */
00622   //        ============
00623   //@{
00624 
00625   /**
00626    * @brief Disabled default constructor.
00627    *
00628    * The default constructor belongs to the private section
00629    * so that a client cannot use it.
00630    */
00631   FreemanChain();
00632 
00633 
00634 // -------------------------------------------------------------------
00635 }; // class FreemanChain
00636 
00637 
00638 } // namespace qgar
00639 
00640 
00641 #endif /* __FREEMANCHAIN_H_INCLUDED__ */