00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <cmath>
00042 #include <deque>
00043 #include <iostream>
00044 #include <list>
00045 #include <vector>
00046
00047 #include <qgarlib/ISerializable.H>
00048
00049
00050
00051 namespace qgar
00052 {
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 template <class T>
00063 GenPolygon<T>::GenPolygon()
00064
00065 : AbstractGenPrimitive<T>(0, 0, 0, 0)
00066
00067 {
00068
00069 }
00070
00071
00072
00073
00074 template <class T>
00075 GenPolygon<T>::GenPolygon(const GenPolygon<T>& aPoly)
00076
00077 : AbstractGenPrimitive<T>(aPoly._source, aPoly._target),
00078 _vertices(aPoly._vertices)
00079
00080 {
00081
00082 }
00083
00084
00085
00086
00087 template <class T>
00088 GenPolygon<T>::GenPolygon(const GenQgarPolygon<T>& aQPoly)
00089
00090 : AbstractGenPrimitive<T>(aQPoly.accessSource(),
00091 aQPoly.accessTarget()),
00092 _vertices(aQPoly.accessVertices())
00093
00094 {
00095
00096 }
00097
00098
00099
00100
00101 template <class T>
00102 GenPolygon<T>::GenPolygon(const std::list< GenPoint<T> >& aPtList)
00103
00104 throw(QgarErrorUser)
00105
00106 {
00107 if (aPtList.size() < 3)
00108 {
00109 throw QgarErrorUser(__FILE__, __LINE__,
00110 "template <class T> qgar::GenPolygon<T>::GenPolygon(const std::list< qgar::GenPoint<T> >&)",
00111 "Cannot create a polygon including less than 3 vertices");
00112 }
00113
00114
00115 for (typename std::list< GenPoint<T> >::const_iterator itPL = aPtList.begin() ;
00116 itPL != aPtList.end() ;
00117 ++itPL)
00118 {
00119 _vertices.push_back(*itPL);
00120 }
00121
00122
00123 this->_source = aPtList.front();
00124 this->_target = aPtList.back();
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 template <class T>
00134 GenPolygon<T>::~GenPolygon()
00135 {
00136
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 template <class T>
00148 GenPolygon<T>*
00149 GenPolygon<T>::clone() const
00150 {
00151 return new GenPolygon<T>(*this);
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 template <class T>
00163 GenPolygon<T>&
00164 GenPolygon<T>::operator=(const GenPolygon<T>& aPoly)
00165 {
00166
00167 if (this != &aPoly)
00168 {
00169 AbstractGenPrimitive<T>::operator=(aPoly);
00170 _vertices = aPoly._vertices;
00171 }
00172
00173 return *this;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 template <class T>
00185 double
00186 GenPolygon<T>::signedArea()
00187 {
00188 typename std::deque< GenPoint<T> >::iterator itDP = _vertices.begin();
00189
00190
00191 double x1 = (double) (*itDP).x();
00192 double y1 = (double) (*itDP).y();
00193
00194 double xp = x1;
00195 double yp = y1;
00196 ++itDP;
00197
00198
00199 double area = 0.;
00200
00201 while (itDP != _vertices.end())
00202 {
00203
00204 double xc = (double) (*itDP).x();
00205 double yc = (double) (*itDP).y();
00206
00207
00208 area += (xp * yc) - (yp * xc);
00209
00210
00211 xp = xc;
00212 yp = yc;
00213
00214
00215 ++itDP;
00216 }
00217
00218
00219 area += (xp * y1) - (yp * x1);
00220
00221 return area / 2.;
00222 }
00223
00224
00225
00226
00227 template <class T>
00228 inline double
00229 GenPolygon<T>::area()
00230 {
00231 return std::fabs(signedArea());
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 template <class T>
00243 inline int
00244 GenPolygon<T>::size() const
00245 {
00246 return _vertices.size();
00247 }
00248
00249
00250
00251
00252 template <class T>
00253 inline const std::deque< GenPoint<T> >&
00254 GenPolygon<T>::accessVertices() const
00255 {
00256 return this->_vertices;
00257 }
00258
00259
00260
00261
00262 template <class T>
00263 inline std::deque< GenPoint<T> >&
00264 GenPolygon<T>::getVertices()
00265 {
00266 return this->_vertices;
00267 }
00268
00269
00270
00271
00272 template <class T>
00273 inline std::deque< GenPoint<T> >
00274 GenPolygon<T>::vertices() const
00275 {
00276 return this->_vertices;
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 template <class T>
00288 GenPolygon<T>&
00289 GenPolygon<T>::appendSource(const GenPoint<T>& aPt)
00290 {
00291 this->_source = aPt;
00292 this->_vertices.push_front(aPt);
00293 return *this;
00294 }
00295
00296
00297
00298
00299 template <class T>
00300 GenPolygon<T>&
00301 GenPolygon<T>::appendTarget(const GenPoint<T>& aPt)
00302 {
00303 this->_target = aPt;
00304 this->_vertices.push_back(aPt);
00305 return *this;
00306 }
00307
00308
00309
00310
00311 template<class T>
00312 GenPolygon<T>&
00313 GenPolygon<T>::append(const std::vector<GenPoint<T> >& aPtVector)
00314 {
00315 std::copy(aPtVector.begin(),
00316 aPtVector.end(),
00317 back_inserter(this->_vertices));
00318
00319
00320 this->_target = aPtVector.back();
00321
00322 return *this;
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 template <class T>
00334 GenPolygon<T>&
00335 GenPolygon<T>::remove(const GenPoint<T>& aPt)
00336
00337 throw(QgarErrorUser)
00338
00339 {
00340
00341 if (this->_vertices.size() == 3)
00342 {
00343 throw QgarErrorUser(__FILE__, __LINE__,
00344 "template <class T> qgar::GenPolygon<T>& qgar::GenPolygon<T>::remove(const qgar::GenPoint<T>&)",
00345 "Cannot remove a vertex from a polygon including 3 vertices");
00346 }
00347
00348 if (aPt == (this->_vertices).front())
00349 {
00350
00351 (this->_vertices).pop_front();
00352
00353
00354 this->_source = this->_vertices.front();
00355 }
00356 else if (aPt == (this->_vertices).back())
00357 {
00358
00359 _vertices.pop_back();
00360
00361
00362 this->_target = _vertices.back();
00363 }
00364 else
00365 {
00366 typename std::deque<GenPoint<T> >::iterator it =
00367 find((this->_vertices).begin(), (this->_vertices).end(), aPt);
00368
00369
00370 if (it != (this->_vertices).end())
00371 {
00372 (this->_vertices).erase(it);
00373 }
00374 }
00375
00376 return *this;
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 template <class T>
00388 std::vector< GenPoint<T> >
00389 GenPolygon<T>::toPointVector()
00390 {
00391 std::vector< GenPoint<T> > ptVector;
00392
00393
00394 std::copy(_vertices.begin(),
00395 _vertices.end(),
00396 std::back_inserter(ptVector));
00397
00398 return ptVector;
00399 }
00400
00401
00402
00403
00404 template <class T>
00405 std::list<GenSegment<T> >
00406 GenPolygon<T>::toSegList()
00407 {
00408 std::list< GenSegment<T> > segList;
00409
00410
00411 typename std::deque< GenPoint<T> >::iterator itDP = _vertices.begin();
00412 typename std::deque< GenPoint<T> >::iterator itDPP = itDP;
00413 ++itDP;
00414
00415 for ( ; itDP != _vertices.end() ; ++itDP)
00416 {
00417
00418 segList.push_back(GenSegment<T>(*itDPP, *itDP));
00419
00420
00421 itDPP = itDP;
00422 }
00423
00424
00425 segList.push_back(GenSegment<T>(*itDPP, _vertices[0]));
00426
00427 return segList;
00428 }
00429
00430
00431
00432
00433 template <class T>
00434 std::list<GenQgarSegment<T> >
00435 GenPolygon<T>::toQgarSegList(int aThickness,
00436 QGEcolor aColor,
00437 QGEoutline anOutline)
00438 {
00439 std::list< GenQgarSegment<T> > segList;
00440
00441
00442 typename std::deque< GenPoint<T> >::iterator itDP = _vertices.begin();
00443 typename std::deque< GenPoint<T> >::iterator itDPP = itDP;
00444 ++itDP;
00445
00446 for ( ; itDP != _vertices.end() ; ++itDP)
00447 {
00448
00449 segList.push_back(GenQgarSegment<T>(*itDPP,
00450 *itDP,
00451 aThickness,
00452 aColor,
00453 anOutline));
00454
00455
00456 itDPP = itDP;
00457 }
00458
00459
00460 segList.push_back(GenQgarSegment<T>(*itDPP,
00461 _vertices[0],
00462 aThickness,
00463 aColor,
00464 anOutline));
00465
00466 return segList;
00467 }
00468
00469
00470
00471
00472
00473
00474
00475 template <class T>
00476 std::istream&
00477 GenPolygon<T>::read(std::istream& anInStream)
00478 {
00479
00480 qgReadObjName(anInStream, "Polygon");
00481
00482
00483 qgReadObjData(anInStream, this->_source);
00484 qgReadObjData(anInStream, this->_target);
00485
00486
00487 (this->_vertices).clear();
00488
00489
00490 int pointCnt;
00491 qgReadObjData(anInStream, pointCnt);
00492
00493
00494 for(int iCnt = 0 ; iCnt < pointCnt ; ++iCnt)
00495 {
00496 GenPoint<T> point;
00497 qgReadObjData(anInStream, point);
00498 (this->_vertices).push_back(point);
00499 }
00500
00501 return anInStream;
00502 }
00503
00504
00505 template <class T>
00506 std::ostream&
00507 GenPolygon<T>::write(std::ostream& anOutStream) const
00508 {
00509
00510
00511 anOutStream << "Polygon("
00512 << this->source()
00513 << ")("
00514 << this->target()
00515 << ")("
00516 << (this->accessVertices()).size()
00517 << ')';
00518
00519
00520
00521 for(typename std::deque< GenPoint<T> >::const_iterator itDP
00522 = (this->accessVertices()).begin();
00523 itDP != (this->accessVertices()).end();
00524 ++itDP)
00525 {
00526 anOutStream << '('
00527 << *itDP
00528 << ')';
00529 }
00530
00531 return anOutStream;
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 template <class T>
00551 void
00552 GenPolygon<T>::updateSource()
00553 {
00554 (_vertices.front()).setXY(this->_source.x(), this->_source.y());
00555 }
00556
00557
00558
00559
00560 template <class T>
00561 void
00562 GenPolygon<T>::updateTarget()
00563 {
00564 (_vertices.back()).setXY(this->_target.x(), this->_target.y());
00565 }
00566
00567
00568
00569
00570 template <class T>
00571 void
00572 GenPolygon<T>::updateSourceTarget()
00573 {
00574 this->updateSource();
00575 this->updateTarget();
00576 }
00577
00578
00579
00580
00581
00582
00583
00584 template <class T>
00585 void
00586 GenPolygon<T>::translate(T aTransX, T aTransY)
00587 {
00588
00589 this->setSourceTarget(this->xSource() + aTransX,
00590 this->ySource() + aTransY,
00591 this->xTarget() + aTransX,
00592 this->yTarget() + aTransY);
00593
00594
00595 for(typename std::deque< GenPoint<T> >::iterator itDP = _vertices.begin();
00596 itDP < _vertices.end();
00597 ++itDP)
00598 {
00599 (*itDP).translate(aTransX, aTransY);
00600 }
00601 }
00602
00603
00604
00605
00606
00607
00608
00609 }