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

_QGAR_GenPolyline.TCC

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 /**
00029  * @file    _QGAR_GenPolyline.TCC
00030  * @brief   Implementation of function members of class qgar::GenPolyline.
00031  *
00032  * @author  <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00033  * @date    December 14, 2004  18:01
00034  * @since   Qgar 2.2
00035  */
00036 
00037 
00038 // STD
00039 #include <algorithm>
00040 #include <deque>
00041 #include <iterator>
00042 #include <iostream>
00043 #include <list>
00044 #include <vector>
00045 // QGAR
00046 #include <qgarlib/ISerializable.H>
00047 #include <qgarlib/QgarErrorUser.H>
00048 
00049 
00050 
00051 namespace qgar
00052 {
00053 
00054 
00055 // -------------------------------------------------------------------
00056 // C O N S T R U C T O R S
00057 // -------------------------------------------------------------------
00058 
00059 
00060 // DEFAULT CONSTRUCTOR
00061 
00062 template <class T>
00063 GenPolyline<T>::GenPolyline()
00064 
00065   : AbstractGenPrimitive<T>(0, 0, 0, 0)
00066 
00067 {
00068   // VOID
00069 }
00070 
00071 
00072 // COPY CONSTRUCTOR
00073 
00074 template <class T>
00075 GenPolyline<T>::GenPolyline(const GenPolyline<T>& aPoly)
00076 
00077   : AbstractGenPrimitive<T>(aPoly._source, aPoly._target),
00078     _vertices(aPoly._vertices)
00079 
00080 {
00081   // VOID
00082 }
00083 
00084 
00085 // INITIALIZE FROM A Qgar POLYLINE
00086 
00087 template <class T>
00088 GenPolyline<T>::GenPolyline(const GenQgarPolyline<T>& aQPoly)
00089 
00090   : AbstractGenPrimitive<T>(aQPoly.accessSource(),
00091                             aQPoly.accessTarget()),
00092     _vertices(aQPoly.accessVertices())
00093 
00094 {
00095   // VOID
00096 }
00097 
00098 
00099 // INITIALIZE FROM A Qgar SEGMENT
00100 
00101 template <class T>
00102 GenPolyline<T>::GenPolyline(const GenQgarSegment<T>& aQSeg)
00103 
00104   : AbstractGenPrimitive<T>(aQSeg.source(), aQSeg.target())
00105 
00106 {
00107   _vertices.push_back(this->_source);
00108   _vertices.push_back(this->_target);
00109 }
00110 
00111 
00112 // INITIALIZE FROM A (GEOMETRICAL) SEGMENT
00113 
00114 template <class T>
00115 GenPolyline<T>::GenPolyline(const GenSegment<T>& aSeg)
00116 
00117   : AbstractGenPrimitive<T>(aSeg.source(), aSeg.target())
00118 
00119 {
00120   _vertices.push_back(this->_source);
00121   _vertices.push_back(this->_target);
00122 }
00123 
00124 
00125 // INITIALIZE FROM TWO VERTICES: SOURCE AND TARGET
00126 
00127 template <class T>
00128 GenPolyline<T>::GenPolyline(const GenPoint<T>& aSource,
00129                             const GenPoint<T>& aTarget)
00130 
00131   : AbstractGenPrimitive<T>(aSource, aTarget)
00132 
00133 {
00134   _vertices.push_front(aSource);
00135   _vertices.push_back(aTarget);
00136 }
00137 
00138 
00139 // INITIALIZE FROM A LIST OF AT LEAST TWO VERTICES
00140 
00141 template <class T>
00142 GenPolyline<T>::GenPolyline(const std::list< GenPoint<T> >& aPtList)
00143 
00144   throw(QgarErrorUser)
00145 
00146   // The points of the given list are copied in the vertices list
00147   : _vertices(aPtList.begin(), aPtList.end())
00148 
00149 {
00150   if (aPtList.size() < 2)
00151     {
00152       throw QgarErrorUser(__FILE__, __LINE__,
00153                           "template <class T> qgar::GenPolyline<T>::GenPolyline(const std::list< qgar::GenPoint<T> >&)",
00154                           "Cannot create a polyline including less than 2 vertices.");
00155     }
00156 
00157   // Update source and target.
00158   this->_source = aPtList.front();
00159   this->_target = aPtList.back();
00160 }
00161 
00162 
00163 // -------------------------------------------------------------------
00164 // D E S T R U C T O R 
00165 // -------------------------------------------------------------------
00166 
00167 
00168 template <class T>
00169 GenPolyline<T>::~GenPolyline()
00170 {
00171   // VOID
00172 }
00173 
00174 
00175 // -------------------------------------------------------------------
00176 // C O P Y
00177 // -------------------------------------------------------------------
00178 
00179 
00180 // DEEP COPY
00181 
00182 template <class T>
00183 GenPolyline<T>*
00184 GenPolyline<T>::clone() const
00185 {
00186   return new GenPolyline<T>(*this);
00187 }
00188 
00189 
00190 // -------------------------------------------------------------------
00191 // O P E R A T O R S 
00192 // -------------------------------------------------------------------
00193 
00194 
00195 // ASSIGNMENT
00196 
00197 template <class T>
00198 GenPolyline<T>&
00199 GenPolyline<T>::operator=(const GenPolyline<T>& aPoly)
00200 {
00201   // Are left hand side and right hand side different objects?
00202   if (this != &aPoly)
00203     {
00204       AbstractGenPrimitive<T>::operator=(aPoly);
00205       this->_vertices = aPoly._vertices;
00206     }
00207 
00208   return *this;
00209 }
00210 
00211 
00212 // -------------------------------------------------------------------
00213 // A C C E S S   T O   V E R T I C E S
00214 // -------------------------------------------------------------------
00215 
00216 
00217 // GET NUMBER OF VERTICES
00218 
00219 template <class T>
00220 inline int
00221 GenPolyline<T>::size() const
00222 {
00223   return (int) _vertices.size();
00224 }
00225 
00226 
00227 // GET THE LIST OF VERTICES
00228 
00229 template <class T>
00230 const std::deque< GenPoint<T> >&
00231 GenPolyline<T>::accessVertices() const
00232 {
00233   return this->_vertices;
00234 }
00235 
00236 
00237 // GIVE NON-PROTECTED ACCESS TO THE VERTICES
00238 
00239 template <class T>
00240 inline std::deque< GenPoint<T> >&
00241 GenPolyline<T>::getVertices()
00242 {
00243   return this->_vertices;
00244 }
00245 
00246 
00247 // GET A COPY OF THE LIST OF VERTICES
00248 
00249 template <class T>
00250 std::deque< GenPoint<T> >
00251 GenPolyline<T>::vertices() const
00252 {
00253   return this->_vertices;
00254 }
00255 
00256 
00257 // -------------------------------------------------------------------
00258 // I N S E R T   V E R T I C E S
00259 // -------------------------------------------------------------------
00260 
00261 
00262 // INSERT A POINT AS NEW SOURCE
00263 
00264 template <class T>
00265 GenPolyline<T>&
00266 GenPolyline<T>::appendSource(const GenPoint<T>& aPt)
00267 {
00268   this->_source = aPt;
00269   _vertices.push_front(aPt);   
00270   return *this;
00271 }
00272  
00273 
00274 // INSERT A POINT AS NEW TARGET
00275 
00276 template <class T>
00277 GenPolyline<T>&
00278 GenPolyline<T>::appendTarget(const GenPoint<T>& aPt)
00279 {
00280   this->_target = aPt;
00281   this->_vertices.push_back(aPt);
00282   return *this;
00283 }
00284 
00285 
00286 // APPEND A POLYLINE
00287 
00288 template<class T>
00289 GenPolyline<T>&
00290 GenPolyline<T>::append(const GenPolyline<T>& aPoly)
00291 {
00292   // Copy the vertices of the given polyline
00293   std::copy(aPoly.accessVertices().begin(), 
00294             aPoly.accessVertices().end(),
00295             back_inserter(this->_vertices));
00296 
00297   // Update target
00298   this->_target = aPoly.target();
00299 
00300   return *this;
00301 }
00302 
00303 
00304 // APPEND A QGAR POLYLINE
00305 
00306 template<class T>
00307 GenPolyline<T>&
00308 GenPolyline<T>::append(const GenQgarPolyline<T>& aQPoly)
00309 {
00310   // Copy the vertices of the given polyline
00311   std::copy(aQPoly.accessVertices().begin(), 
00312             aQPoly.accessVertices().end(),
00313             back_inserter(this->_vertices));
00314 
00315   // Update target
00316   this->_target = aQPoly.target();
00317 
00318   return *this;
00319 }
00320 
00321 
00322 // APPEND A VECTOR OF POINTS
00323 
00324 template<class T>
00325 GenPolyline<T>&
00326 GenPolyline<T>::append(const std::vector<GenPoint<T> >& aPtVect)
00327 {
00328   std::copy(aPtVect.begin(), aPtVect.end(),
00329             back_inserter(this->_vertices));
00330   
00331   // Update target, new target is the last vertex of the vector.
00332   this->_target = aPtVect.back();
00333 
00334   return *this;
00335 }
00336 
00337 
00338 // -------------------------------------------------------------------
00339 // R E M O V E   V E R T I C E S
00340 // -------------------------------------------------------------------
00341 
00342 
00343 // REMOVE A VERTEX FROM THE POLYLINE
00344 
00345 template <class T>
00346 GenPolyline<T>&
00347 GenPolyline<T>::remove(const GenPoint<T>& aPt)
00348 
00349   throw(QgarErrorUser)
00350 
00351 {
00352   // The list of vertices must always include 2 elements at least
00353   if (_vertices.size() == 2)
00354     {
00355       throw QgarErrorUser(__FILE__, __LINE__,
00356                           "template <class T> qgar::GenPolyline<T>& qgar::GenPolyline<T>::remove(const qgar::GenPoint<T>&)",
00357                           "Cannot remove a vertex from a polyline including 2 vertices.");
00358     }
00359 
00360   if ( aPt == _vertices.front() )
00361     {
00362       // Remove first element
00363       _vertices.pop_front();
00364 
00365       // New first element becomes the source of this polyline.
00366       this->_source = _vertices.front();
00367     }
00368   else if ( aPt == _vertices.back() )
00369     {
00370       // Remove last element
00371       _vertices.pop_back();
00372 
00373       // New last element becomes the target of this polyline.
00374       this->_target = _vertices.back();
00375     }
00376   else
00377     {
00378       typename std::deque<GenPoint<T> >::iterator it =
00379         find(_vertices.begin(), _vertices.end(), aPt);
00380   
00381       // Remove vertex if found
00382       if ( it != _vertices.end() )
00383         {
00384           _vertices.erase(it);
00385         }
00386     }
00387 
00388   return *this;
00389 }
00390 
00391 
00392 // -------------------------------------------------------------------
00393 // CONVERSIONS OF THE LIST OF VERTICES
00394 // -------------------------------------------------------------------
00395 
00396 
00397 // GET A VECTOR OF POINTS FROM THE LIST OF VERTICES
00398 
00399 template <class T>
00400 std::vector< GenPoint<T> >
00401 GenPolyline<T>::toPointVector()
00402 {
00403   std::vector< GenPoint<T> > ptVector;
00404 
00405   // Copy all vertices in the vector created above
00406   std::copy(_vertices.begin(),
00407             _vertices.end(), 
00408             std::back_inserter(ptVector));
00409   
00410   return ptVector;
00411 }
00412 
00413 
00414 // GET A LIST OF (GEOMETRICAL) SEGMENTS FROM THE LIST OF VERTICES
00415 
00416 template <class T>
00417 std::list<GenSegment<T> >
00418 GenPolyline<T>::toSegList()
00419 {
00420   typename std::deque< GenPoint<T> >::iterator itDP = _vertices.begin();
00421   std::list<GenSegment<T> > segList;
00422   
00423 
00424   // Current source point
00425   GenPoint<T> source = *itDP;
00426 
00427   // Current target point
00428   GenPoint<T> target = *(++itDP);
00429 
00430   do
00431     {
00432       segList.push_back(GenSegment<T>(source, target));
00433     
00434       source = target;
00435       target = *(++itDP);
00436     }
00437   while (itDP != _vertices.end()) ;
00438 
00439   return segList;
00440 }
00441 
00442 
00443 // GET A LIST OF QGAR SEGMENTS FROM THE LIST OF VERTICES
00444 
00445 template <class T>
00446 std::list<GenQgarSegment<T> >
00447 GenPolyline<T>::toQgarSegList(int aThickness,
00448                               QGEcolor aColor,
00449                               QGEoutline anOutline)
00450 {
00451   typename std::deque< GenPoint<T> >::iterator itDP = _vertices.begin();
00452   std::list<GenQgarSegment<T> > segList;
00453   
00454   // Current source
00455   GenPoint<T> source = *itDP;
00456   
00457   // Current target
00458   GenPoint<T> target = *(++itDP);
00459 
00460   do
00461     {
00462       // Current target
00463       segList.push_back(GenQgarSegment<T>(source,
00464                                           target,
00465                                           aThickness,
00466                                           aColor,
00467                                           anOutline));
00468       source = target;
00469       target = *(++itDP);
00470     }
00471   while ( itDP != _vertices.end() );
00472 
00473   return segList;
00474 }
00475 
00476 
00477 // -------------------------------------------------------------------
00478 // S E R I A L I Z A T I O N / D E S E R I A L I Z A T I O N
00479 // -------------------------------------------------------------------
00480 
00481 
00482 template <class T>
00483 inline std::istream& 
00484 GenPolyline<T>::read(std::istream& anInStream)
00485 {
00486   // Skip name
00487   qgReadObjName(anInStream, "Polyline");
00488 
00489   // Get source and target
00490   qgReadObjData(anInStream, this->_source);
00491   qgReadObjData(anInStream, this->_target);
00492 
00493   // Remove possible stored vertices
00494   (this->_vertices).clear();
00495 
00496   // Get vertices number
00497   int pointCnt;
00498   qgReadObjData(anInStream, pointCnt);
00499   
00500   // Get vertices, conforming to their initial ordering
00501   for(int iCnt = 0 ; iCnt < pointCnt ; ++iCnt)
00502     {
00503       GenPoint<T> point;
00504       qgReadObjData(anInStream, point);
00505       (this->_vertices).push_back(point);
00506     }
00507   
00508   return anInStream;
00509 }
00510 
00511 
00512 template <class T>
00513 inline std::ostream& 
00514 GenPolyline<T>::write(std::ostream& anOutStream) const
00515 {
00516   // Source, target and vertices number
00517 
00518   anOutStream << "Polyline("
00519               << this->_source
00520               << ")("
00521               << this->_target
00522               << ")("
00523               << (this->_vertices).size()
00524               << ')';
00525 
00526   // Vertices
00527 
00528   for(typename std::deque< GenPoint<T> >::const_iterator
00529         itDP = (this->_vertices).begin();
00530       itDP != (this->_vertices).end();
00531       ++itDP)
00532     {
00533       anOutStream << '('
00534                   << *itDP
00535                   << ')';
00536     }
00537 
00538   return anOutStream;
00539 }
00540 
00541 
00542 // VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
00543 // V                                                                 V
00544 // V            IMPLEMENTATION OF PURE VIRTUAL FUNCTIONS             V
00545 // V               INHERITED FROM AbstractGenPrimitive               V
00546 // V                                                                 V
00547 // VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
00548 
00549 
00550 // -------------------------------------------------------------------
00551 // G E O M E T R I C A L   S T R U C T U R E   U P D A T E S
00552 // -------------------------------------------------------------------
00553 
00554 
00555 // THE SOURCE HAS BEEN CHANGED
00556 
00557 template <class T>
00558 void
00559 GenPolyline<T>::updateSource()
00560 {
00561   (this->_vertices.front()).setXY((this->_source).x(), (this->_source).y());
00562 }
00563 
00564 
00565 // THE TARGET HAS BEEN CHANGED
00566 
00567 template <class T>
00568 void
00569 GenPolyline<T>::updateTarget()
00570 {
00571   (this->_vertices.back()).setXY((this->_target).x(), (this->_target).y());
00572 }
00573 
00574 
00575 // BOTH SOURCE AND TARGET HAVE BEEN CHANGED
00576 
00577 template <class T>
00578 void
00579 GenPolyline<T>::updateSourceTarget()
00580 {
00581   this->updateSource();
00582   this->updateTarget();
00583 }
00584 
00585 
00586 // -------------------------------------------------------------------
00587 // G E O M E T R Y :   T R A N S L A T I O N 
00588 // -------------------------------------------------------------------
00589 
00590 
00591 template <class T>
00592 inline void
00593 GenPolyline<T>::translate(T aTransX, T aTransY)
00594 {
00595   // Translate source and target
00596   this->setSourceTarget(this->xSource() + aTransX,
00597                         this->ySource() + aTransY,
00598                         this->xTarget() + aTransX,
00599                         this->yTarget() + aTransY);
00600 
00601   // Translate vertices
00602   for(typename std::deque< GenPoint<T> >::iterator itDP = _vertices.begin();
00603       itDP < _vertices.end();
00604       ++itDP)
00605     {
00606       (*itDP).translate(aTransX, aTransY);
00607     }
00608 }
00609 
00610 
00611 // VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
00612 // V                                                                 V
00613 // VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
00614 
00615 
00616 } // namespace qgar