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

GenConvexHull.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 __GENCONVEXHULL_H_INCLUDED__
00029 #define __GENCONVEXHULL_H_INCLUDED__
00030 
00031 
00032 /**
00033  * @file     GenConvexHull.H
00034  * @brief    Header file of class qgar::GenConvexHull.
00035  *
00036  * @author   <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00037  * @date     March 24, 2004  11:24
00038  * @since    Qgar 2.1.1
00039  */
00040 
00041 
00042 // For RCS/CVS use: Do not delete.
00043 /* $Id: GenConvexHull.H,v 1.21 2005/10/14 17:05:46 masini Exp $ */
00044 
00045 
00046 
00047 // STD
00048 #include <iosfwd> // Avoid including classes when not necessary
00049 #include <list>
00050 #include <set>
00051 // QGAR
00052 #include <qgarlib/ISerializable.H>
00053 #include <qgarlib/primitives.H>
00054 
00055 
00056 
00057 namespace qgar
00058 {
00059 
00060 
00061 /**
00062  * @class GenConvexHull GenConvexHull.H "qgarlib/GenConvexHull.H"
00063  * @ingroup TOOL_HULL
00064  * @brief A convex hull represented by a series of points with
00065  *   coordinates of type <b>T</b>.
00066  *
00067  * The hull is constructed from a set of points using Graham's scan
00068  * <a href="Bibliography.html#Graham-1972">[Graham,&nbsp;1972]</a>.
00069  * This algorithm works in three steps:
00070  * <ol>
00071  * <li>
00072  * Find an extreme point, the so-called <i>pivot</i>, which is guaranteed
00073  * to be on the hull: Here, it is chosen as the point with the minimum Y
00074  * coordinate. In case of equality, the point with the minimum X coordinate is
00075  * selected.
00076  * </li>
00077  * <li>
00078  * Sort the points in order of increasing angles about the pivot.
00079  * The result is a star-shaped polygon, in which the pivot can <i>see</i>
00080  * the whole polygon.
00081  * </li>
00082  * <li>
00083  * Build the hull by marching around the star-shaped polygon, adding edges
00084  * at right turns, and backtracking at left turns.
00085  * </li>
00086  * </ol>
00087  *
00088  * Such a hull may be empty.
00089  * It is implemented by:
00090  * - a point representing the pivot (qgar::GenConvexHull::_pivot),
00091  * - a STL list of the vertices of the polygon constituting the hull
00092  *   (qgar::GenConvexHull::_vertices). The first vertex of the list is
00093  *   always the pivot,
00094  * - a STL multiset including STL pairs associating each vertex with its angle
00095  *   about the pivot (qgar::GenConvexHull::_hull). The pivot does not belong to
00096  *   the multiset. The pairs are sorted according to increasing angles.
00097  *
00098  * <b>The GenConvexHull class is not supposed to be derived: No function member
00099  * (destructor or whatever else) is virtual.</b>
00100  * Predefined instances of the class are
00101  * qgar::ConvexHull,
00102  * qgar::IConvexHull,
00103  * qgar::FConvexHull,
00104  * and qgar::DConvexHull.
00105  *
00106  * @warning <b>The hull is not guaranteed to be valid when constructed
00107  *   from an initial set of points including duplicates.</b>
00108  *
00109  * @todo Class to be completed: In particular, insertion and removal
00110  *   of points are not implemented.
00111  *
00112  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00113  * @date   March 24, 2004  11:24
00114  * @since  Qgar 2.1.1
00115  */
00116 template <class T> class GenConvexHull
00117 
00118   : public ISerializable
00119 
00120 {
00121 // -------------------------------------------------------------------
00122 // T Y P E   D E F I N I T I O N S
00123 // -------------------------------------------------------------------
00124 public:
00125 
00126   /** @name Types */
00127   //        =====
00128   //@{
00129 
00130   /**
00131    * @brief Type of the points.
00132    */
00133   typedef T value_type;
00134 
00135   /**
00136    * @brief Reference to qgar::GenConvexHull::value_type.
00137    */
00138   typedef value_type& reference;
00139 
00140   /**
00141    * @brief Constant reference to qgar::GenConvexHull::value_type.
00142    */
00143   typedef const value_type& const_reference;
00144 
00145   /**
00146    * @brief Pointer to qgar::GenConvexHull::value_type.
00147    */
00148   typedef value_type* pointer;
00149 
00150   /**
00151    * @brief Constant pointer to qgar::GenConvexHull::value_type.
00152    */
00153   typedef const value_type* const_pointer;
00154 
00155   //@}
00156 
00157 // -------------------------------------------------------------------
00158 // P U B L I C    M E M B E R S
00159 // -------------------------------------------------------------------
00160 public:
00161 
00162 /** @name Constructors */
00163 //        ============
00164 //@{
00165 
00166 /**
00167  * @brief Default constructor.
00168  *
00169  * Construct an empty hull.
00170  */
00171 GenConvexHull();
00172 
00173 /**
00174  * @brief Copy constructor.
00175  * @param aCHull  a convex hull
00176  */
00177 GenConvexHull(const GenConvexHull<value_type>& aCHull);
00178 
00179 /**
00180  * @brief Construct from a STL list of points.
00181  * @param aPtList  a STL list of points
00182  *
00183  * The convex hull is constructed using <i>Graham's scan</i>.
00184  * <b>Duplicate points are eliminated.</b>
00185  */
00186 GenConvexHull(const std::list< GenPoint<value_type> >& aPtList);
00187 
00188 //@}
00189 
00190 
00191 /** @name Destructor */
00192 //        ==========
00193 //@{
00194 
00195 /**
00196  * @brief Non-virtual destructor: The class is not supposed to be derived.
00197  */
00198 ~GenConvexHull();
00199 
00200 //@}
00201 
00202 
00203 /** @name Access to characteristics */
00204 //        =========================
00205 //@{
00206 
00207 /**
00208  * @brief Is hull empty?
00209  */
00210 inline bool empty() const;
00211 
00212 /**
00213  * @brief Get number of vertices.
00214  */
00215 inline int size() const;
00216 
00217 //@}
00218 
00219 
00220 /** @name Access to vertices */
00221 //        ==================
00222 //@{
00223 
00224 /**
00225  * @brief Get vertices.
00226  */
00227 const std::list< GenPoint<value_type> >& accessVertices() const;
00228 
00229 /**
00230  * @brief Get a copy of the vertices.
00231  */
00232 std::list< GenPoint<value_type> > vertices() const;
00233 
00234 /**
00235  * @brief Get pivot.
00236  */
00237 const GenPoint<value_type>& accessPivot() const;
00238 
00239 /**
00240  * @brief Get a copy of the pivot.
00241  */
00242 GenPoint<value_type> pivot() const;
00243 
00244 //@}
00245 
00246 
00247 /** @name Operators */
00248 //        =========
00249 //@{
00250 
00251 /**
00252  * @brief Assignment operator.
00253  * @param aCHull  a hull
00254  */
00255 GenConvexHull<value_type>& operator=(const GenConvexHull<value_type>& aCHull);
00256 
00257 //@}
00258 
00259 
00260 /** @name Serialization/deserialization */
00261 //        =============================
00262 //@{
00263 
00264 /**
00265  * @brief Deserializes the current hull from an input stream.
00266  * @param anInStream  the input stream
00267  *
00268  * A serialized hull is represented by:
00269 @verbatim
00270   ConvexHull(<VERTICES COUNT>)(<VERTICE 1>)...(<VERTICE n>)
00271 @endverbatim
00272  */
00273 virtual std::istream& read(std::istream& anInStream);
00274 
00275 /**
00276  * @brief Serializes the current hull to an input stream.
00277  * @param anOutStream  the output stream
00278  *
00279  * A serialized hull is represented by:
00280 @verbatim
00281   ConvexHull(<VERTICES COUNT>)(<VERTICE 1>)...(<VERTICE n>)
00282 @endverbatim
00283  */
00284 virtual std::ostream& write(std::ostream& anOutStream) const;
00285 
00286 //@}
00287 
00288 // -------------------------------------------------------------------
00289 // P R O T E C T E D    M E M B E R S
00290 // -------------------------------------------------------------------
00291 protected:
00292 
00293 /** @name Type definitions */
00294 //        ================
00295 //@{
00296 
00297 /**
00298  * @brief Pair associating a vertex with its angle about the pivot.
00299  */
00300 typedef std::pair< double, GenPoint<value_type> > QGDpair;
00301 
00302 //@}
00303 
00304 
00305 /** @name Auxiliary structure */
00306 //        ===================
00307 //@{
00308 
00309 /**
00310  * @brief To compare angles about the pivot when sorting points
00311  *        to construct their hull.
00312  */
00313 struct _sortPred
00314 {
00315   /**
00316    * @brief Compares angles about the pivot when sorting points to
00317    * construct their hull.
00318    *
00319    * When angles are equal, pairs are sorted according to decreasing
00320    * Y coordinates of the corresponding points, and, when Y coordinates
00321    * are equal, according to increasing X coordinates:
00322    * <b>The pivot is thus guaranteed to be the leftmost point of minimum
00323    * Y coordinate.</b>
00324    *
00325    * @param aPair1 The lhs parameter of the comparison.
00326    * @param aPair2 The rhs parameter of the comparison.
00327    */
00328   bool operator()(const std::pair< double, GenPoint<T> >& aPair1,
00329                   const std::pair< double, GenPoint<T> >& aPair2)
00330   {
00331     return
00332              // increasing angles...
00333              ( (aPair1.first) < (aPair2.first) )
00334           ||
00335              // ...OR, if angles are equal...
00336              (    ( (aPair1.first) == (aPair2.first) )
00337                &&
00338                      // ...decreasing Y coordinates...
00339                   (    ( (aPair1.second.y()) > (aPair2.second.y()) )
00340                     ||
00341                             // ...OR, if y coordinates are equal...
00342                        (    ( (aPair1.second.y()) == (aPair2.second.y()) )
00343                          &&
00344                              // ...increasing X coordinates
00345                              ( (aPair1.second.x()) < (aPair2.second.x()) )
00346                        )
00347                   )
00348              );
00349   }
00350 };
00351 
00352 //@}
00353 
00354 
00355 /** @name The hull */
00356 //        ========
00357 //@{
00358 
00359 /**
00360  * @brief The list of the vertices of the hull.
00361  *
00362  * The first point of the list is the pivot.
00363  */
00364 std::list< GenPoint<value_type> > _vertices;
00365 
00366 /**
00367  * @brief Sorted STL multiset of STL pairs associating a vertex (of the hull)
00368  * with the angle between the X axis and the vector joining the pivot
00369  * and the vertex.
00370  *
00371  * Pairs are sorted in order of increasing angles.
00372  */
00373 std::multiset<QGDpair, _sortPred> _hull;
00374 
00375 /**
00376  * @brief The pivot.
00377  *
00378  * It is the initial given point of minimum ordinate,
00379  * which is guaranteed to belong to the hull.
00380  */
00381 GenPoint<value_type> _pivot;
00382 
00383 //@}
00384 
00385 // -------------------------------------------------------------------
00386 // P R I V A T E    M E M B E R S
00387 // -------------------------------------------------------------------
00388 private:
00389 
00390 /** @name Auxiliary functions */
00391 //        ===================
00392 //@{
00393 
00394 /**
00395  * @brief Perfom Graham's scan to construct the convex hull from 
00396  *        a given list of points.
00397  *
00398  * @param aPtList  the initial list of points, from which to construct
00399  *                 the convex hull
00400  */
00401 void PRIVATEgraham_sScan(const std::list< GenPoint<value_type> >& aPtList);
00402 
00403 //@}
00404 
00405 // -------------------------------------------------------------------
00406 
00407 }; // class GenConvexHull
00408 
00409 
00410 } // namespace qgar
00411 
00412 
00413 
00414 
00415 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00416 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00417 // I M P L E M E N T A T I O N
00418 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00419 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00420 
00421 #include <qgarlib/GenConvexHull.TCC>
00422 
00423 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00424 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00425 
00426 
00427 
00428 
00429 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
00430 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
00431 // P R E D E F I N E D    H U L L    T Y P E S
00432 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
00433 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
00434 
00435 
00436 namespace qgar
00437 {
00438 
00439 
00440 /**
00441  * @name Predefined Convex Hulls Types
00442  * @ingroup TOOL_HULL
00443  */
00444 //{@
00445 
00446 /**
00447  * @brief Hull with integer coordinates.
00448  *
00449  * @see qgar::IConvexHull
00450  */
00451 typedef GenConvexHull<int> ConvexHull;
00452 
00453 /**
00454  * @brief Hull with integer coordinates.
00455  *
00456  * @see qgar::ConvexHull
00457  */
00458 typedef GenConvexHull<int> IConvexHull;
00459 
00460 /**
00461  * @brief Hull with <b>float</b> coordinates.
00462  */
00463 typedef GenConvexHull<float> FConvexHull;
00464 
00465 /**
00466  * @brief Hull with <b>double</b> coordinates.
00467  */
00468 typedef GenConvexHull<double> DConvexHull;
00469 
00470 //@}
00471 
00472 
00473 } // namespace qgar
00474 
00475 
00476 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
00477 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
00478 
00479 
00480 #endif /* __GENCONVEXHULL_H_INCLUDED__ */
00481