00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "TeAssertions.h"
00025 #include "TeGeometryAlgorithms.h"
00026 #include "TeDefines.h"
00027
00028 #include "TeIntersector.h"
00029 #include "TeFragmentation.h"
00030
00031 #include <algorithm>
00032 #include <iterator>
00033 #include <set>
00034
00035
00036 using namespace std;
00037
00038
00039
00040
00041 double Theta(const TeCoord2D& c1, const TeCoord2D& c2)
00042 {
00043 register double dx = c2.x() - c1.x();
00044 register double ax = fabs(dx);
00045 register double dy = c2.y() - c1.y();
00046 register double ay = fabs(dy);
00047 register double t = 0.0;
00048
00049 if((dx == 0.0) && (dy == 0.0))
00050 t = 0.0;
00051 else
00052 t = dy / (ax + ay);
00053
00054 if(dx < 0.0)
00055 t = 2 - t;
00056 else
00057 if(dy < 0.0)
00058 t = 4.0 + t;
00059
00060 return t * 90.0;
00061 }
00062
00063
00064 struct ThetaOrder
00065 {
00066
00067 TeCoord2D anchor;
00068
00069 ThetaOrder(const TeCoord2D& c)
00070 : anchor(c)
00071 {
00072 }
00073
00074
00075 bool operator()(const TeCoord2D& c1, const TeCoord2D& c2) const
00076 {
00077 register double t1 = Theta(anchor, c1);
00078 register double t2 = Theta(anchor, c2);
00079
00080 if(t1 < t2)
00081 return true;
00082
00083 if(t1 > t2)
00084 return false;
00085
00086 if(c1.x() < c2.x())
00087 return true;
00088
00089 if(c1.x() > c2.x())
00090 return false;
00091
00092 return false;
00093 }
00094 };
00095
00096
00097
00098
00099 template<class T> struct xOrder
00100 {
00101 bool operator()(T c1, T c2)
00102 {
00103 if(c1.x() < c2.x())
00104 return true;
00105
00106 if(c1.x() > c2.x())
00107 return false;
00108
00109 if(c1.y() < c2.y())
00110 return true;
00111
00112 return false;
00113 }
00114 };
00115
00116
00117
00118
00119
00120
00121
00122
00123 double Te2Area(const TeLinearRing& r)
00124 {
00125 double S2 = 0.0;
00126
00127 TeLinearRing::iterator it = r.begin();
00128 TeLinearRing::iterator end = r.end() - 1;
00129 while(it != end)
00130 {
00131 S2 += (it->x() + (it + 1)->x()) * ((it + 1)->y() - it->y());
00132 ++it;
00133 }
00134
00135 return S2;
00136 }
00137
00138
00139
00140
00141
00142 inline short ConverseRelation(const short& rel)
00143 {
00144 switch(rel)
00145 {
00146 case TeCOVEREDBY : return TeCOVERS;
00147 case TeWITHIN : return TeCONTAINS;
00148 case TeCOVERS : return TeCOVEREDBY;
00149 case TeCONTAINS : return TeWITHIN;
00150 default : return rel;
00151 }
00152 }
00153
00154
00155
00156
00157
00158
00159
00160 bool MayTouches(const TeLine2D& lRed, const TeLine2D& lBlue, TeINTERSECTOR2::TeVectorBoundaryIP& report)
00161 {
00162 if(lRed.isRing() && lBlue.isRing())
00163 return false;
00164
00165 TeINTERSECTOR2::TeVectorBoundaryIP::iterator it = report.begin();
00166 TeINTERSECTOR2::TeVectorBoundaryIP::iterator it_end = report.end();
00167
00168
00169
00170 TeCoord2D line1_boundary1 = lRed[0];
00171 TeCoord2D line1_boundary2 = lRed[lRed.size() - 1u];
00172
00173 TeCoord2D line2_boundary1 = lBlue[0];
00174 TeCoord2D line2_boundary2 = lBlue[lBlue.size() - 1u];
00175
00176
00177 while(it != it_end)
00178 {
00179
00180 for(unsigned int i = 0; i < it->coords_.size(); ++i)
00181 {
00182 TeCoord2D ip_coord = it->coords_[i];
00183
00184 if(lRed.isRing())
00185 {
00186 if(!(TeEquals(ip_coord, line2_boundary1) || TeEquals(ip_coord, line2_boundary2)))
00187 return false;
00188 }
00189 else if(lBlue.isRing())
00190 {
00191 if(!(TeEquals(ip_coord, line1_boundary1) || TeEquals(ip_coord, line1_boundary2)))
00192 return false;
00193 }
00194 else
00195 {
00196 if(!(TeEquals(ip_coord, line1_boundary1) || TeEquals(ip_coord, line1_boundary2) || TeEquals(ip_coord, line2_boundary1) || TeEquals(ip_coord, line2_boundary2)))
00197 return false;
00198 }
00199 }
00200
00201 ++it;
00202 }
00203
00204 return true;
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 short Relation(const TeLine2D& lRed, const TeLine2D& lBlue, TeINTERSECTOR2::TeVectorBoundaryIP& report, const short& relation)
00218 {
00219 if(report.size() == 0u)
00220 return TeDISJOINT;
00221
00222
00223
00224
00225 bool mayTouches = MayTouches(lRed, lBlue, report);
00226
00227
00228 if(relation == TeTOUCHES && !mayTouches)
00229 return TeUNDEFINEDREL;
00230
00231
00232 TeLineSet redFragments;
00233 TeLineSet redBoundaryFragments;
00234 TeLine2D lRedAux;
00235 lRedAux.copyElements(lRed);
00236 TeLineSet lSet; lSet.add(lRedAux);
00237
00238 TeFragmentBoundary(lSet, report, redBoundaryFragments, redFragments);
00239
00240 unsigned int redFragmentsSize = redFragments.size();
00241
00242 short mask = TeUNKNOWNPOSITION;
00243
00244 if(redBoundaryFragments.size() > 0u)
00245 mask |= TeINSIDE;
00246
00247
00248 for(unsigned int j = 0u; j < redFragmentsSize; ++j)
00249 {
00250 TeCoord2D middle;
00251
00252 if(redFragments[j].size() == 2u)
00253 TeGetMiddlePoint(redFragments[j][0u], redFragments[j][1u], middle);
00254 else
00255 middle = redFragments[j][(unsigned int)((double(redFragments[j].size()) / 2.0 + 0.5)) - 1];
00256
00257 if(TeIsOnLine(middle, lBlue))
00258 mask |= TeINSIDE;
00259 else
00260 mask |= TeOUTSIDE;
00261
00262 if((mask & TeOUTSIDE) && (mask & TeINSIDE))
00263 break;
00264 }
00265
00266
00267 if(mayTouches && mask == TeOUTSIDE)
00268 {
00269 return TeTOUCHES;
00270 }
00271
00272
00273 if(relation == TeTOUCHES)
00274 return TeUNDEFINEDREL;
00275
00276
00277
00278 if(mask == TeOUTSIDE)
00279 return TeCROSSES;
00280
00281
00282 if(relation == TeCROSSES)
00283 return TeUNDEFINEDREL;
00284
00285 TeCoord2D firstRedCoord = lRed[0];
00286 TeCoord2D lastRedCoord = lRed[lRed.size() - 1];
00287
00288 TeCoord2D firstBlueCoord = lBlue[0];
00289 TeCoord2D lastBlueCoord = lBlue[lBlue.size() - 1];
00290
00291
00292
00293 if(!(mask & TeOUTSIDE))
00294 {
00295
00296
00297 if(TeEquals(firstRedCoord, firstBlueCoord) || TeEquals(firstRedCoord, lastBlueCoord))
00298 {
00299 if(TeEquals(lastRedCoord, firstBlueCoord) || TeEquals(lastRedCoord, lastBlueCoord))
00300 {
00301 return TeEQUALS;
00302 }
00303 else
00304 {
00305 if(lBlue.isRing())
00306 return TeWITHIN;
00307 else
00308 return TeCOVEREDBY;
00309 }
00310 }
00311
00312 if(TeEquals(lastRedCoord, firstBlueCoord) || TeEquals(lastRedCoord, lastBlueCoord))
00313 {
00314 if(lBlue.isRing())
00315 return TeWITHIN;
00316 else
00317 return TeCOVEREDBY;
00318 }
00319
00320 return TeWITHIN;
00321 }
00322
00323 return TeUNDEFINEDREL;
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 short Relation(const TeLine2D& line, const TeLinearRing& ring)
00336 {
00337 if(TeDisjoint(line.box(), ring.box()))
00338 return TeOUTSIDE;
00339
00340 TeINTERSECTOR2::TeVectorBoundaryIP report;
00341
00342 if(TeINTERSECTOR2::TeSafeIntersections(line, ring, report))
00343 {
00344 short mask = TeBOUNDARY;
00345
00346
00347 TeLineSet lSet;
00348 TeLineSet boundaryFragments;
00349 TeLine2D lineAux;
00350 lineAux.copyElements(line);
00351 TeLineSet auxLineSet; auxLineSet.add(lineAux);
00352
00353 TeFragmentBoundary(auxLineSet, report, boundaryFragments, lSet);
00354
00355
00356 unsigned int lSetSize = lSet.size();
00357
00358
00359 for(unsigned int j = 0; j < lSetSize; ++j)
00360 {
00361 TeCoord2D middle;
00362
00363 if(lSet[j].size() == 2)
00364 TeGetMiddlePoint(lSet[j][0], lSet[j][1], middle);
00365 else
00366 middle = lSet[j][(unsigned int)((double(lSet[j].size()) / 2.0 + 0.5)) - 1];
00367
00368
00369 mask |= TeRelation(middle, ring);
00370
00371 if((mask & TeOUTSIDE) && (mask & TeINSIDE))
00372 break;
00373 }
00374
00375 return mask;
00376 }
00377 else
00378 return TeRelation(line[0], ring);
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 short TopologicRelation(const TeLine2D& line, const TeLinearRing& r)
00391 {
00392 short mask = Relation(line, r);
00393
00394 if(mask & TeBOUNDARY)
00395 {
00396 if(mask & TeOUTSIDE)
00397 {
00398 if(mask & TeINSIDE)
00399 return TeCROSSES;
00400 else
00401 return TeTOUCHES;
00402 }
00403 else
00404 return TeCOVEREDBY;
00405
00406 }
00407 else
00408 {
00409 if(mask & TeINSIDE)
00410 return TeWITHIN;
00411 else
00412 return TeDISJOINT;
00413 }
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423 short TopologicRelation(const TeLinearRing& rRed, const TeLinearRing& rBlue)
00424 {
00425
00426 short rel = Relation(rRed, rBlue);
00427
00428 if((rel & TeOUTSIDE) && (rel & TeINSIDE) && (rel & TeBOUNDARY))
00429 return TeOVERLAPS;
00430
00431 if((rel & TeOUTSIDE) && !(rel & TeINSIDE) && (rel & TeBOUNDARY))
00432 {
00433 if(TeWithinOrCoveredByOrEquals(rBlue.box(), rRed.box()))
00434 {
00435 short rel_aux = Relation(rBlue, rRed);
00436
00437 if(rel_aux == TeBOUNDARY)
00438 return TeCOVERS;
00439
00440 if((rel_aux & TeINSIDE) && !(rel_aux & TeOUTSIDE) && (rel_aux & TeBOUNDARY))
00441 return TeCOVERS;
00442 }
00443
00444 return TeTOUCHES;
00445 }
00446
00447 if((rel & TeOUTSIDE) && !(rel & TeINSIDE) && !(rel & TeBOUNDARY))
00448 {
00449 if(TeWithinOrCoveredByOrEquals(rBlue.box(), rRed.box()))
00450 {
00451 if(TeRelation(rBlue[0], rRed) == TeINSIDE)
00452 return TeCONTAINS;
00453 }
00454
00455 return TeDISJOINT;
00456 }
00457
00458 if(!(rel & TeOUTSIDE) && (rel & TeINSIDE) && !(rel & TeBOUNDARY))
00459 return TeWITHIN;
00460
00461 if(!(rel & TeOUTSIDE) && (rel & TeINSIDE) && (rel & TeBOUNDARY))
00462 return TeCOVEREDBY;
00463
00464 if(rel == TeBOUNDARY)
00465 return TeEQUALS;
00466
00467 return TeINTERSECTS;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 short LookAtInnerRings(const TeLinearRing& rRed, const TePolygon& pBlue, vector<TeLinearRing>& rings, short& rel)
00480 {
00481 register unsigned int i = 1;
00482 register unsigned int nRings = pBlue.size();
00483
00484 for(; i < nRings; ++i)
00485 {
00486 switch(TopologicRelation(rRed, pBlue[i]))
00487 {
00488 case TeCOVEREDBY : return TeTOUCHES;
00489
00490 case TeWITHIN : return TeDISJOINT;
00491
00492 case TeOVERLAPS : return TeOVERLAPS;
00493
00494 case TeEQUALS : return TeTOUCHES;
00495
00496 case TeDISJOINT : continue;
00497
00498 case TeTOUCHES : rel = TeCOVEREDBY;
00499 continue;
00500
00501 case TeCOVERS : rings.push_back(pBlue[i]);
00502 rel = TeCOVEREDBY;
00503 break;
00504
00505 case TeCONTAINS : rings.push_back(pBlue[i]);
00506 break;
00507 }
00508 }
00509
00510 return TeUNDEFINEDREL;
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520 short TestInnerRings(const TePolygon& pRed, vector<TeLinearRing>& rings)
00521 {
00522 unsigned int nRedRings = pRed.size();
00523 unsigned int nBlueRings = rings.size();
00524
00525
00526
00527
00528 unsigned int i = 1;
00529 unsigned int j = 0;
00530
00531 bool find = false;
00532
00533 set<unsigned int> blueRingsProcessed;
00534
00535 set<unsigned int> redRingsContainsCovers;
00536
00537 short rel = 0;
00538
00539 for(; i < nRedRings; ++i)
00540 {
00541 find = false;
00542
00543 for(j = 0; j < nBlueRings; ++j)
00544 {
00545 if(blueRingsProcessed.find(j) != blueRingsProcessed.end())
00546 continue;
00547
00548 switch(TopologicRelation(pRed[i], rings[j]))
00549 {
00550 case TeDISJOINT : continue;
00551
00552 case TeEQUALS :
00553 rel |= TeEQUALS;
00554 blueRingsProcessed.insert(j);
00555 find = true;
00556 break;
00557
00558 case TeCONTAINS :
00559 if(redRingsContainsCovers.find(i) != redRingsContainsCovers.end())
00560 return TeOVERLAPS;
00561
00562 rel |= TeCONTAINS;
00563
00564 redRingsContainsCovers.insert(i);
00565 blueRingsProcessed.insert(j);
00566 find = true;
00567 break;
00568
00569 case TeCOVERS :
00570 if(redRingsContainsCovers.find(i) != redRingsContainsCovers.end())
00571 return TeOVERLAPS;
00572
00573 rel |= TeCOVERS;
00574
00575 redRingsContainsCovers.insert(i);
00576 blueRingsProcessed.insert(j);
00577 find = true;
00578 break;
00579
00580
00581 default : return TeOVERLAPS;
00582 }
00583
00584 if(find)
00585 break;
00586 }
00587
00588 if(!find)
00589 return TeOVERLAPS;
00590 }
00591
00592 return rel;
00593 }
00594
00595
00596
00597
00598 template<> bool TeEquals(const TeCoord2D& c1, const TeCoord2D& c2)
00599 {
00600 if(TeGeometryAlgorithmsPrecision::IsDifferent(c1.x(), c2.x()))
00601 return false;
00602
00603 if(TeGeometryAlgorithmsPrecision::IsDifferent(c1.y(), c2.y()))
00604 return false;
00605
00606 return true;
00607 }
00608
00609 template<> bool TeEquals(const TePoint& p1, const TePoint& p2)
00610 {
00611 return TeEquals(p1.location(), p2.location());
00612 }
00613
00614 template<> bool TeEquals(const TeLine2D& redLine, const TeLine2D& blueLine)
00615 {
00616 if(TeEquals(redLine.box(), blueLine.box()))
00617 return TeRelation(redLine, blueLine, TeEQUALS) == TeEQUALS;
00618 else
00619 return false;
00620 }
00621
00622 template<> bool TeEquals(const TePolygon& redPol, const TePolygon& bluePol)
00623 {
00624 if(TeEquals(redPol.box(), bluePol.box()))
00625 {
00626 if(redPol.size() != bluePol.size())
00627 return false;
00628
00629 return TeRelation(redPol, bluePol) == TeEQUALS;
00630 }
00631 else
00632 return false;
00633 }
00634
00635 template<> bool TeEquals( const TePolygonSet& ps1, const TePolygonSet& ps2 )
00636 {
00637 if( ps1.size() == ps2.size() ) {
00638 TePolygonSet::iterator it1 = ps1.begin();
00639 TePolygonSet::iterator it1_end = ps1.end();
00640 TePolygonSet::iterator it2 = ps2.begin();
00641
00642 while( it1 != it1_end ) {
00643 if( ! TeEquals( (*it1), (*it2) ) ) {
00644 return false;
00645 }
00646
00647 ++it1;
00648 ++it2;
00649 }
00650
00651 return true;
00652 } else {
00653 return false;
00654 }
00655 }
00656
00657 template<> bool TeEquals(const TeBox& bx1, const TeBox& bx2)
00658 {
00659 if(TeGeometryAlgorithmsPrecision::IsDifferent(bx1.x1(), bx2.x1()))
00660 return false;
00661
00662 if(TeGeometryAlgorithmsPrecision::IsDifferent(bx1.y1(), bx2.y1()))
00663 return false;
00664
00665 if(TeGeometryAlgorithmsPrecision::IsDifferent(bx1.x2(), bx2.x2()))
00666 return false;
00667
00668 if(TeGeometryAlgorithmsPrecision::IsDifferent(bx1.y2(), bx2.y2()))
00669 return false;
00670
00671 return true;
00672 }
00673
00674 template<> bool TeEquals(const TeCell& cell1, const TeCell& cell2)
00675 {
00676 return TeEquals(cell1.box(), cell2.box());
00677 }
00678
00679
00680
00681 bool TeDisjoint(const TeCoord2D& c1, const TeCoord2D& c2)
00682 {
00683 if(TeGeometryAlgorithmsPrecision::IsDifferent(c1.x(), c2.x()))
00684 return true;
00685
00686 if(TeGeometryAlgorithmsPrecision::IsDifferent(c1.y(), c2.y()))
00687 return true;
00688
00689 return false;
00690 }
00691
00692 bool TeDisjoint(const TeCoord2D& c, const TeBox& b)
00693 {
00694
00695 if(TeGeometryAlgorithmsPrecision::IsGreater(c.x(), b.x2()))
00696 return true;
00697
00698
00699 if(TeGeometryAlgorithmsPrecision::IsGreater(b.x1(), c.x()))
00700 return true;
00701
00702
00703 if(TeGeometryAlgorithmsPrecision::IsGreater(c.y(), b.y2()))
00704 return true;
00705
00706
00707 if(TeGeometryAlgorithmsPrecision::IsGreater(b.y1(), c.y()))
00708 return true;
00709
00710 return false;
00711 }
00712
00713 bool TeDisjoint(const TeBox& bx1, const TeBox& bx2)
00714 {
00715
00716 if(TeGeometryAlgorithmsPrecision::IsGreater(bx1.x1(), bx2.x2()))
00717 return true;
00718
00719
00720 if(TeGeometryAlgorithmsPrecision::IsGreater(bx2.x1(), bx1.x2()))
00721 return true;
00722
00723
00724 if(TeGeometryAlgorithmsPrecision::IsGreater(bx2.y1(), bx1.y2()))
00725 return true;
00726
00727
00728 if(TeGeometryAlgorithmsPrecision::IsGreater(bx1.y1(), bx2.y2()))
00729 return true;
00730
00731 return false;
00732 }
00733
00734 bool TeDisjoint(const TeCoord2D& c, const TeLine2D& l)
00735 {
00736 return TeRelation(c, l) == TeOUTSIDE;
00737 }
00738
00739 bool TeDisjoint(const TeCoord2D& c, const TePolygon& pol)
00740 {
00741 return TeRelation(c, pol) == TeOUTSIDE;
00742 }
00743
00744 bool TeDisjoint(const TePoint& p1, const TePoint& p2)
00745 {
00746 return TeDisjoint(p1.location(), p2.location());
00747 }
00748
00749 bool TeDisjoint(const TePoint& p, const TeLine2D& l)
00750 {
00751 return TeDisjoint(p.location(), l);
00752 }
00753
00754 bool TeDisjoint(const TePoint& p, const TePolygon& pol)
00755 {
00756 return TeDisjoint(p.location(), pol);
00757 }
00758
00759 bool TeDisjoint(const TeLine2D& redLine, const TeLine2D& blueLine)
00760 {
00761 if(TeDisjoint(redLine.box(), blueLine.box()))
00762 return true;
00763
00764 return !TeINTERSECTOR2::TeIntersects(redLine, blueLine);
00765 }
00766
00767 bool TeDisjoint(const TeLine2D& l, const TePolygon& pol)
00768 {
00769 if(TeDisjoint(l.box(), pol.box()))
00770 return true;
00771
00772 return TeRelation(l, pol) == TeDISJOINT;
00773 }
00774
00775 bool TeDisjoint(const TePolygon& redPol, const TePolygon& bluePol)
00776 {
00777 if(TeDisjoint(redPol.box(), bluePol.box()))
00778 return true;
00779 else
00780 return TeRelation(redPol, bluePol) == TeDISJOINT;
00781 }
00782
00783 bool TeDisjoint(const TeCell& cell1, const TeCell& cell2)
00784 {
00785 return TeDisjoint(cell1.box(), cell2.box());
00786 }
00787
00788 bool TeDisjoint(const TeCell& cell, const TeLine2D& line)
00789 {
00790 return TeDisjoint(line, TeMakePolygon(cell.box()));
00791 }
00792
00793 bool TeDisjoint(const TeCell& cell, const TePolygon& pol)
00794 {
00795 return TeDisjoint(pol, TeMakePolygon(cell.box()));
00796 }
00797
00798 bool TeDisjoint(const TeCell& cell, const TePoint& point)
00799 {
00800 return TeDisjoint(point.location(), cell.box());
00801 }
00802
00803
00804
00805
00806 template<> bool TeIntersects(const TeCoord2D& c, const TeBox& b)
00807 {
00808
00809 if(TeGeometryAlgorithmsPrecision::IsGreater(c.x(), b.x2()))
00810 return false;
00811
00812
00813 if(TeGeometryAlgorithmsPrecision::IsGreater(b.x1(), c.x()))
00814 return false;
00815
00816
00817 if(TeGeometryAlgorithmsPrecision::IsGreater(c.y(), b.y2()))
00818 return false;
00819
00820
00821 if(TeGeometryAlgorithmsPrecision::IsGreater(b.y1(), c.y()))
00822 return false;
00823
00824 return true;
00825 }
00826
00827 template<> bool TeIntersects(const TePoint& p, const TeBox& b)
00828 {
00829 return TeIntersects(p.location(), b);
00830 }
00831
00832 template<> bool TeIntersects(const TeBox& bx1, const TeBox& bx2)
00833 {
00834
00835 if(TeGeometryAlgorithmsPrecision::IsGreater(bx1.x1(), bx2.x2()))
00836 return false;
00837
00838
00839 if(TeGeometryAlgorithmsPrecision::IsGreater(bx2.x1(), bx1.x2()))
00840 return false;
00841
00842
00843 if(TeGeometryAlgorithmsPrecision::IsGreater(bx2.y1(), bx1.y2()))
00844 return false;
00845
00846
00847 if(TeGeometryAlgorithmsPrecision::IsGreater(bx1.y1(), bx2.y2()))
00848 return false;
00849
00850 return true;
00851 }
00852
00853
00854
00855 bool TeTouches(const TeCoord2D& c, const TeLine2D& l)
00856 {
00857 return TeRelation(c, l) == TeBOUNDARY;
00858 }
00859
00860 bool TeTouches(const TeCoord2D& c, const TePolygon& pol)
00861 {
00862 return TeRelation(c, pol) == TeBOUNDARY;
00863 }
00864
00865 bool TeTouches(const TePoint& p, const TeLine2D& l)
00866 {
00867 return TeTouches(p.location(), l);
00868 }
00869
00870 bool TeTouches(const TePoint& p, const TePolygon& pol)
00871 {
00872 return TeTouches(p.location(), pol);
00873 }
00874
00875 bool TeTouches(const TeLine2D& redLine, const TeLine2D& blueLine)
00876 {
00877 if(TeDisjoint(redLine.box(), blueLine.box()))
00878 return false;
00879
00880 return TeRelation(redLine, blueLine, TeTOUCHES) == TeTOUCHES;
00881 }
00882
00883 bool TeTouches(const TeLine2D& l, const TePolygon& pol)
00884 {
00885 if(TeDisjoint(l.box(), pol.box()))
00886 return false;
00887
00888 return TeRelation(l, pol) == TeTOUCHES;
00889 }
00890
00891 bool TeTouches(const TePolygon& redPol, const TePolygon& bluePol)
00892 {
00893 if(TeDisjoint(redPol.box(), bluePol.box()))
00894 return false;
00895
00896 return TeRelation(redPol, bluePol) == TeTOUCHES;
00897 }
00898
00899 bool TeTouches(const TeBox& bx1, const TeBox& bx2)
00900 {
00901
00902
00903 if(TeGeometryAlgorithmsPrecision::IsEqual(bx1.x2(), bx2.x1()) || TeGeometryAlgorithmsPrecision::IsEqual(bx1.x1(), bx2.x2()))
00904 {
00905
00906 if(TeGeometryAlgorithmsPrecision::IsGreater(bx2.y1(), bx1.y2()))
00907 return false;
00908
00909
00910 if(TeGeometryAlgorithmsPrecision::IsGreater(bx1.y1(), bx2.y2()))
00911 return false;
00912
00913
00914 return true;
00915 }
00916
00917
00918
00919 if(TeGeometryAlgorithmsPrecision::IsEqual(bx1.y1(), bx2.y2()) || TeGeometryAlgorithmsPrecision::IsEqual(bx1.y2(), bx2.y1()))
00920 {
00921
00922 if(TeGeometryAlgorithmsPrecision::IsGreater(bx2.x1(), bx1.x2()))
00923 return false;
00924
00925
00926 if(TeGeometryAlgorithmsPrecision::IsGreater(bx1.x1(), bx2.x2()))
00927 return false;
00928
00929
00930 return true;
00931 }
00932
00933
00934 return false;
00935 }
00936
00937 bool TeTouches(const TeCell& c1, const TeCell& c2)
00938 {
00939 return TeTouches(c1.box(), c2.box());
00940 }
00941
00942 bool TeTouches(const TeLine2D& line, const TeCell& cell)
00943 {
00944 return TeTouches(line, TeMakePolygon(cell.box()));
00945 }
00946
00947 bool TeTouches(const TeCell& c1, const TePolygon& poly)
00948 {
00949 return TeTouches (poly, TeMakePolygon(c1.box()));
00950 }
00951
00952 bool TeTouches(const TePoint& point,const TeCell& c1)
00953 {
00954 return TeTouches(point.location(), TeMakePolygon(c1.box()));
00955 }
00956
00957
00958
00959 bool TeCrosses(const TeLine2D& redLine, const TeLine2D& blueLine)
00960 {
00961 if(TeDisjoint(redLine.box(), blueLine.box()))
00962 return false;
00963 else
00964 return TeRelation(redLine, blueLine, TeCROSSES) == TeCROSSES;
00965 }
00966
00967 bool TeCrosses(const TeLine2D& l, const TePolygon& pol)
00968 {
00969 if(TeDisjointOrTouches(l.box(), pol.box()))
00970 return false;
00971 else
00972 return TeRelation(l, pol) == TeCROSSES;
00973 }
00974
00975 bool TeCrosses(const TeLine2D& l, const TeCell& cell)
00976 {
00977 return TeCrosses(l, TeMakePolygon(cell.box()));
00978 }
00979
00980
00981
00982 bool TeWithin(const TeCoord2D& c1, const TeCoord2D& c2)
00983 {
00984 return TeEquals(c1, c2);
00985 }
00986
00987 bool TeWithin(const TeCoord2D& c, const TeBox& b)
00988 {
00989
00990
00991 return (TeGeometryAlgorithmsPrecision::IsGreater(c.x(), b.x1()) && TeGeometryAlgorithmsPrecision::IsGreater(b.x2(), c.x()) && TeGeometryAlgorithmsPrecision::IsGreater(b.y2(), c.y()) && TeGeometryAlgorithmsPrecision::IsGreater(c.y(), b.y1()));
00992 }
00993
00994 bool TeWithin(const TeCoord2D& c, const TeLine2D& l)
00995 {
00996 return TeRelation(c, l) == TeINSIDE;
00997 }
00998
00999 bool TeWithin(const TeCoord2D& c, const TePolygon& pol)
01000 {
01001 return TeRelation(c, pol) == TeINSIDE;
01002 }
01003
01004 bool TeWithin(const TePoint& p1, const TePoint& p2)
01005 {
01006 return TeWithin(p1.location(), p2.location());
01007 }
01008
01009 bool TeWithin(const TePoint& p, const TeLine2D& l)
01010 {
01011 return TeWithin(p.location(), l);
01012 }
01013
01014 bool TeWithin(const TePoint& p, const TePolygon& pol)
01015 {
01016 return TeWithin(p.location(), pol);
01017 }
01018
01019 bool TeWithin(const TeLine2D& redLine, const TeLine2D& blueLine)
01020 {
01021 if(TeWithinOrCoveredByOrEquals(redLine.box(), blueLine.box()))
01022 return TeRelation(redLine, blueLine, TeWITHIN) == TeWITHIN;
01023 else
01024 return false;
01025 }
01026
01027 bool TeWithin(const TeLine2D& l, const TePolygon& pol)
01028 {
01029 if(TeWithinOrCoveredByOrEquals(l.box(), pol.box()))
01030 return TeRelation(l, pol) == TeWITHIN;
01031
01032
01033 return false;
01034 }
01035
01036 bool TeWithin(const TePolygon& redPol, const TePolygon& bluePol)
01037 {
01038 if(TeWithinOrCoveredByOrEquals(redPol.box(), bluePol.box()))
01039 return TeRelation(redPol, bluePol) == TeWITHIN;
01040 else
01041 return false;
01042 }
01043
01044 bool TeWithin(const TeBox& bx1, const TeBox& bx2)
01045 {
01046
01047 if(TeGeometryAlgorithmsPrecision::IsGreaterEqual(bx2.x1(), bx1.x1()))
01048 return false;
01049
01050
01051 if(TeGeometryAlgorithmsPrecision::IsGreaterEqual(bx1.x2(), bx2.x2()))
01052 return false;
01053
01054
01055 if(TeGeometryAlgorithmsPrecision::IsGreaterEqual(bx2.y1(), bx1.y1()))
01056 return false;
01057
01058
01059 if(TeGeometryAlgorithmsPrecision::IsGreaterEqual(bx1.y2(), bx2.y2()))
01060 return false;
01061
01062 return true;
01063 }
01064
01065 bool TeWithin(const TeCell& cell1, const TeCell& cell2)
01066 {
01067 return TeWithin(cell1.box(), cell2.box());
01068 }
01069
01070 bool TeWithin(const TeLine2D& line, const TeCell& cell)
01071 {
01072 return TeWithin(line, TeMakePolygon(cell.box()));
01073 }
01074
01075
01076 bool TeWithin(const TeCell& cell, const TePolygon& poly)
01077 {
01078 return TeWithin(TeMakePolygon(cell.box()), poly);
01079 }
01080
01081 bool TeWithin(const TePoint& point, const TeCell& cell)
01082 {
01083 return TeWithin(point.location(), cell.box());
01084 }
01085
01086
01087
01088 bool TeOverlaps(const TeLine2D& redLine, const TeLine2D& blueLine)
01089 {
01090 if(TeDisjoint(redLine.box(), blueLine.box()))
01091 return false;
01092 else
01093 return TeRelation(redLine, blueLine, TeOVERLAPS) == TeOVERLAPS;
01094 }
01095
01096 bool TeOverlaps(const TePolygon& redPol, const TePolygon& bluePol)
01097 {
01098
01099 if(TeDisjointOrTouches(redPol.box(), bluePol.box()))
01100 return false;
01101 else
01102 return TeRelation(redPol, bluePol) == TeOVERLAPS;
01103 }
01104
01105 bool TeOverlaps(const TeCell& cell1, const TeCell& cell2)
01106 {
01107 return TeOverlaps(TeMakePolygon(cell1.box()), TeMakePolygon(cell2.box()));
01108 }
01109
01110 bool TeOverlaps(const TeCell& cell, const TePolygon& poly)
01111 {
01112 return TeOverlaps(TeMakePolygon(cell.box()), poly);
01113 }
01114
01115
01116
01117 bool TeCoveredBy(const TeLine2D& redLine, const TeLine2D& blueLine)
01118 {
01119 if(TeWithinOrCoveredByOrEquals(redLine.box(), blueLine.box()))
01120 return TeRelation(redLine, blueLine, TeCOVEREDBY) == TeCOVEREDBY;
01121 else
01122 return false;
01123 }
01124
01125 bool TeCoveredBy(const TeLine2D& l, const TePolygon& pol)
01126 {
01127 if(TeWithinOrCoveredByOrEquals(l.box(), pol.box()))
01128 return TeRelation(l, pol) == TeCOVEREDBY;
01129 else
01130 return false;
01131 }
01132
01133 bool TeCoveredBy(const TePolygon& redPol, const TePolygon& bluePol)
01134 {
01135 if(TeWithinOrCoveredByOrEquals(redPol.box(), bluePol.box()))
01136 return TeRelation(redPol, bluePol) == TeCOVEREDBY;
01137 else
01138 return false;
01139 }
01140
01141 bool TeCoveredBy(const TeCell& cell1, const TeCell& cell2)
01142 {
01143 return TeCoveredBy(TeMakePolygon(cell1.box()), TeMakePolygon(cell2.box()));
01144 }
01145
01146 bool TeCoveredBy(const TePolygon& poly, const TeCell& cell)
01147 {
01148 return TeCoveredBy(poly, TeMakePolygon(cell.box()));
01149 }
01150
01151 bool TeCoveredBy(const TeLine2D& line, const TeCell& cell)
01152 {
01153 return TeCoveredBy(line, TeMakePolygon(cell.box()));
01154 }
01155
01156
01157
01158 bool TeDisjointOrTouches(const TeBox& bx1, const TeBox& bx2)
01159 {
01160
01161 if(TeGeometryAlgorithmsPrecision::IsGreaterEqual(bx1.x1(), bx2.x2()))
01162 return true;
01163
01164
01165 if(TeGeometryAlgorithmsPrecision::IsGreaterEqual(bx2.x1(), bx1.x2()))
01166 return true;
01167
01168
01169 if(TeGeometryAlgorithmsPrecision::IsGreaterEqual(bx2.y1(), bx1.y2()))
01170 return true;
01171
01172
01173 if(TeGeometryAlgorithmsPrecision::IsGreaterEqual(bx1.y1(), bx2.y2()))
01174 return true;
01175
01176 return false;
01177 }
01178
01179 template<>
01180 bool TeWithinOrCoveredByOrEquals(const TeBox& bx1, const TeBox& bx2)
01181 {
01182
01183 if(TeGeometryAlgorithmsPrecision::IsGreater(bx2.x1(), bx1.x1()))
01184 return false;
01185
01186
01187 if(TeGeometryAlgorithmsPrecision::IsGreater(bx1.x2(), bx2.x2()))
01188 return false;
01189
01190
01191 if(TeGeometryAlgorithmsPrecision::IsGreater(bx2.y1(), bx1.y1()))
01192 return false;
01193
01194
01195 if(TeGeometryAlgorithmsPrecision::IsGreater(bx1.y2(), bx2.y2()))
01196 return false;
01197
01198 return true;
01199 }
01200
01201 template<>
01202 bool TeWithinOrCoveredByOrEquals(const TeLine2D& line1, const TeLine2D& line2)
01203 {
01204 if(TeWithinOrCoveredByOrEquals(line1.box(), line2.box()))
01205 {
01206 short r;
01207 short rel = TeRelation(line1, line1, r);
01208
01209 if((rel&TeWITHIN) || (rel&TeCOVEREDBY) || (rel&TeEQUALS))
01210 return true;
01211
01212 return false;
01213 }
01214 return false;
01215 }
01216
01217 template<>
01218 bool TeWithinOrCoveredByOrEquals(const TeLine2D& line1, const TePolygon& pol)
01219 {
01220 if(TeWithinOrCoveredByOrEquals(line1.box(), pol.box()))
01221 {
01222 short rel = TeRelation(line1, pol);
01223
01224 if((rel&TeWITHIN) || (rel&TeCOVEREDBY))
01225 return true;
01226
01227 return false;
01228 }
01229 return false;
01230 }
01231
01232 template<>
01233 bool TeWithinOrCoveredByOrEquals(const TePolygon& pol1, const TePolygon& pol2)
01234 {
01235 if(TeWithinOrCoveredByOrEquals(pol1.box(), pol2.box()))
01236 {
01237 short rel = TeRelation(pol1, pol2);
01238
01239 if((rel&TeWITHIN) || (rel&TeCOVEREDBY) || (rel&TeEQUALS))
01240 return true;
01241
01242 return false;
01243 }
01244 return false;
01245 }
01246
01247
01248 bool TeWithinOrTouches(const TeCoord2D& c, const TeCoord2D& c1, const TeCoord2D& c2)
01249 {
01250
01251 if(TeGeometryAlgorithmsPrecision::IsGreater(c.x(), c1.x()) && TeGeometryAlgorithmsPrecision::IsGreater(c.x(), c2.x()))
01252 return false;
01253
01254
01255 if(TeGeometryAlgorithmsPrecision::IsGreater(c.y(), c1.y()) && TeGeometryAlgorithmsPrecision::IsGreater(c.y(), c2.y()))
01256 return false;
01257
01258
01259 if(TeGeometryAlgorithmsPrecision::IsSmaller(c.x(), c1.x()) && TeGeometryAlgorithmsPrecision::IsSmaller(c.x(), c2.x()))
01260 return false;
01261
01262
01263 if(TeGeometryAlgorithmsPrecision::IsSmaller(c.y(), c1.y()) && TeGeometryAlgorithmsPrecision::IsSmaller(c.y(), c2.y()))
01264 return false;
01265
01266 return true;
01267 }
01268
01269
01270
01271
01272 bool TeIntersection(const TeBox& bx1, const TeBox& bx2, TeBox& bout)
01273 {
01274 if(TeDisjoint(bx1, bx2))
01275 return false;
01276
01277 double x1 = MAX(bx1.x1(),bx2.x1());
01278 double x2 = MIN(bx1.x2(),bx2.x2());
01279 double y1 = MAX(bx1.y1(),bx2.y1());
01280 double y2 = MIN(bx1.y2(),bx2.y2());
01281
01282 bout = TeBox(x1, y1, x2, y2);
01283
01284 return true;
01285 }
01286
01287 TeCoordPairVect TeGetIntersections(const TePolygon &poly, const double& y)
01288 {
01289 TeCoordPairVect Segments;
01290 vector<double> crossList, segListInY;
01291 unsigned int nholes = poly.size();
01292
01293
01294 for (unsigned int count=0; count<nholes; count++ )
01295 {
01296 TeLinearRing coords = poly[count];
01297
01298 for (unsigned int j=0; j < (coords.size() - 1); j++ )
01299 {
01300
01301 TeCoord2D coord0 = coords[j];
01302 TeCoord2D coord1 = coords[j+1];
01303
01304 bool yflag0 = ( coord0.y() > y );
01305 bool yflag1 = ( coord1.y() > y );
01306
01307
01308
01309
01310 if((coord0.y()!=y) && (coord1.y()==y))
01311 {
01312 bool pointsInY = true;
01313 bool lowerY1 = coord0.y()<y;
01314 unsigned int i = j+2;
01315
01316 TeCoord2D lastPointInY;
01317 TeCoord2D firstPointOutY = coord1;
01318
01319 while(pointsInY)
01320 {
01321 lastPointInY = firstPointOutY;
01322
01323
01324 if(i>=coords.size())
01325 i=1;
01326 firstPointOutY = coords[i];
01327 ++i;
01328
01329
01330 pointsInY = firstPointOutY.y()==y;
01331 }
01332
01333 bool lowerY2 = firstPointOutY.y()<y;
01334
01335 if((lastPointInY==coord1) && (lowerY1!=lowerY2))
01336 crossList.push_back(coord1.x());
01337 else
01338 {
01339 segListInY.push_back (coord1.x());
01340 segListInY.push_back (lastPointInY.x());
01341 }
01342 }
01343 else if(coord0.y()==y)
01344 continue;
01345
01346 else if ( yflag0 != yflag1 )
01347 {
01348 double slope = ( coord1.x() - coord0.x() ) / ( coord1.y() - coord0.y());
01349 double xcross = ( y - coord0.y() )* slope + coord0.x();
01350 crossList.push_back (xcross);
01351 }
01352 }
01353 }
01354
01355 if(crossList.empty())
01356 crossList = segListInY;
01357 else if(!segListInY.empty())
01358 {
01359
01360 for(unsigned i=0; i<segListInY.size(); ++i)
01361 crossList.push_back (segListInY[i]);
01362
01363 sort (crossList.begin(), crossList.end());
01364
01365 vector<double> aux;
01366
01367 for(unsigned i=1; i<crossList.size(); ++i)
01368 {
01369
01370 double x0 = crossList[i-1];
01371 double x1 = crossList[i];
01372 double x = x0 + (x1-x0)/2;
01373
01374 TeCoord2D pt (x, y);
01375 if (!TeDisjoint(pt, poly))
01376 {
01377 aux.push_back (x0);
01378 aux.push_back (x1);
01379 }
01380 }
01381 crossList.clear();
01382 crossList = aux;
01383 }
01384
01385
01386 sort (crossList.begin(), crossList.end());
01387
01388
01389 vector<double>::iterator it = crossList.begin();
01390 while ( it != crossList.end())
01391 {
01392 TeCoordPair cp;
01393
01394 cp.pt1 = TeCoord2D ( (*it), y);
01395 ++it;
01396 if ( it == crossList.end() )
01397 break;
01398
01399 cp.pt2 = TeCoord2D ( (*it), y);
01400 ++it;
01401
01402 Segments.push_back ( cp );
01403 }
01404 return Segments;
01405 }
01406
01407
01408
01409 TeBox TeUnion(const TeBox& bx1, const TeBox& bx2)
01410 {
01411 double x1 = MIN(bx1.x1(), bx2.x1());
01412 double y1 = MIN(bx1.y1(), bx2.y1());
01413
01414 double x2 = MAX(bx1.x2(), bx2.x2());
01415 double y2 = MAX(bx1.y2(), bx2.y2());
01416
01417 return TeBox(x1, y1, x2, y2);
01418 }
01419
01420
01421
01422
01423 bool TePointInPoly(const TeCoord2D& c, const TeLinearRing& r)
01424 {
01425 if(r.size() < 4)
01426 return false;
01427
01428 register double ty, tx;
01429
01430 register const unsigned int nVertices = r.size();
01431
01432 register bool inside_flag = false;
01433
01434 register int j, yflag0, yflag1;
01435
01436 TeLinearRing::iterator vtx0, vtx1;
01437
01438 tx = c.x();
01439 ty = c.y();
01440
01441 vtx0 = r.end() - 2;
01442
01443 yflag0 = (vtx0->y() >= ty);
01444
01445 vtx1 = r.begin();
01446
01447 for(j = nVertices; --j; )
01448 {
01449 yflag1 = (vtx1->y() >= ty);
01450
01451 if(yflag0 != yflag1)
01452 {
01453 if(((vtx1->y() - ty) * (vtx0->x() - vtx1->x()) >=
01454 (vtx1->x() - tx) * (vtx0->y() - vtx1->y())) == yflag1)
01455 {
01456 inside_flag = !inside_flag ;
01457 }
01458 }
01459
01460 yflag0 = yflag1 ;
01461 vtx0 = vtx1 ;
01462 vtx1++;
01463 }
01464
01465 return inside_flag;
01466 }
01467
01468 bool TeIsOnSegment(const TeCoord2D& c, const TeCoord2D& c1, const TeCoord2D& c2)
01469 {
01470 if(TeWithinOrTouches(c, c1, c2))
01471 {
01472 bool aux = false;
01473
01474 return TeINTERSECTOR2::TeCCW(c1, c2, c, aux) == TeNOTURN;
01475 }
01476
01477 return false;
01478 }
01479
01480 bool TeIsOnLine(const TeCoord2D& c, const TeLine2D& l)
01481 {
01482 if(l.size() < 2)
01483 return false;
01484
01485 if(TeDisjoint(c, l.box()))
01486 return false;
01487
01488 TeLine2D::iterator it = l.begin();
01489
01490 unsigned int nstep = l.size() - 1;
01491
01492 for(unsigned int i = 0; i < nstep; ++i)
01493 {
01494 if(TeIsOnSegment(c, *(it), *(it + 1)))
01495 return true;
01496
01497 ++it;
01498 }
01499
01500 return false;
01501 }
01502
01503 bool TeLocateLineSegment (TeCoord2D& pin, TeLine2D& line, int& segment, double )
01504 {
01505 if (line.size() < 2)
01506 return false;
01507
01508 TeCoord2D pout;
01509
01510 segment = 0;
01511 double min_dist = TeMinimumDistance(line[0], line[1], pin, pout);
01512
01513 for (unsigned int i = 2; i < line.size(); i++)
01514 {
01515 double dist;
01516 if ((dist = TeMinimumDistance (line[i-1],line[i], pin, pout)) < min_dist)
01517 {
01518 min_dist = dist;
01519 segment = i - 1;
01520 }
01521 }
01522
01523 return true;
01524 }
01525
01526
01527
01528
01529 template<> double TeGeometryArea(const TePolygon& p)
01530 {
01531 if(p.size() > 0)
01532 {
01533 TePolygon::iterator it = p.begin();
01534
01535 double area = fabs(Te2Area(*it));
01536
01537 ++it;
01538
01539
01540 while(it != p.end())
01541 {
01542 area -= fabs(Te2Area(*it));
01543 ++it;
01544 }
01545
01546 return (area / 2.0);
01547 }
01548
01549 return 0.0;
01550 }
01551
01552 template<> double TeGeometryArea(const TePolygonSet& ps)
01553 {
01554 TePolygonSet::iterator it = ps.begin();
01555
01556 double area = 0.0;
01557
01558 while(it != ps.end())
01559 {
01560 area += TeGeometryArea(*it);
01561 ++it;
01562 }
01563
01564 return (area);
01565 }
01566
01567 template<> double TeGeometryArea(const TeBox& b)
01568 {
01569 return ((b.x2() - b.x1()) * (b.y2() - b.y1()));
01570 }
01571
01572 template<> double TeGeometryArea(const TeMultiGeometry& mGeom)
01573 {
01574 if(mGeom.hasPolygons())
01575 {
01576 TePolygonSet pSet;
01577 mGeom.getGeometry(pSet);
01578 return TeGeometryArea(pSet);
01579 }
01580 else if(mGeom.hasCells())
01581 {
01582 TeCellSet cSet;
01583 mGeom.getGeometry(cSet);
01584 return TeGeometryArea(cSet);
01585 }
01586 return 0.;
01587 }
01588
01589
01590
01591
01592 void removeDuplicatedCoords(vector<TeCoord2D>& coordSet)
01593 {
01594 if(coordSet[0] == coordSet[coordSet.size() - 1])
01595 coordSet.erase(coordSet.end() - 1);
01596
01597 return;
01598 }
01599
01600
01601 TePolygon TeConvexHull(std::vector<TeCoord2D>& coordSet)
01602 {
01603
01604 sort(coordSet.begin(), coordSet.end(), xOrder<TeCoord2D>());
01605
01606 register unsigned int i = 0;
01607 register unsigned int n = coordSet.size();
01608
01609 TeLine2D upperHull;
01610 TeLine2D lowerHull;
01611
01612 lowerHull.add(coordSet[0]);
01613 lowerHull.add(coordSet[1]);
01614
01615 unsigned int count = 2;
01616
01617 bool aux = false;
01618
01619 for(i = 2; i < n; ++i)
01620 {
01621 lowerHull.add(coordSet[i]);
01622
01623 ++count;
01624
01625 while(count > 2 && TeINTERSECTOR2::TeCCW(lowerHull[count - 3], lowerHull[count - 2], lowerHull[count - 1], aux) <= TeNOTURN)
01626 {
01627 lowerHull.erase(count - 2);
01628 --count;
01629 }
01630 }
01631
01632 upperHull.add(coordSet[n - 1]);
01633 upperHull.add(coordSet[n - 2]);
01634
01635 count = 2;
01636
01637 for(i = n - 2; i > 0; --i)
01638 {
01639 upperHull.add(coordSet[i - 1]);
01640 ++count;
01641
01642 while(count > 2 && TeINTERSECTOR2::TeCCW(upperHull[count - 3], upperHull[count - 2], upperHull[count - 1], aux) <= TeNOTURN)
01643 {
01644 upperHull.erase(count - 2);
01645 --count;
01646 }
01647 }
01648
01649
01650 upperHull.erase(0);
01651 upperHull.erase(upperHull.size() - 1);
01652
01653 lowerHull.copyElements(upperHull);
01654 lowerHull.add(lowerHull[0]);
01655
01656 TeLinearRing aux_ring(lowerHull);
01657 TePolygon p;
01658 p.add(aux_ring);
01659 return p;
01660 }
01661
01662 TePolygon TeConvexHull(const TePolygon& p)
01663 {
01664 vector<TeCoord2D> coords;
01665 back_insert_iterator<vector<TeCoord2D> > it(coords);
01666
01667
01668 copy(p[0].begin(), p[0].end() - 1, it);
01669
01670 return TeConvexHull(coords);
01671 }
01672
01673 TePolygon TeConvexHull(const TePolygonSet& ps)
01674 {
01675 vector<TeCoord2D> coords;
01676 back_insert_iterator<vector<TeCoord2D> > it(coords);
01677
01678
01679 TePolygonSet::iterator it_ps = ps.begin();
01680 while(it_ps != ps.end())
01681 {
01682 TeLinearRing r = (*it_ps)[0];
01683 copy(r.begin(), r.end() - 1, it);
01684 ++it_ps;
01685 }
01686
01687 return TeConvexHull(coords);
01688 }
01689
01690 TePolygon TeConvexHull(const TePointSet& ps)
01691 {
01692 vector<TeCoord2D> coords;
01693
01694
01695 TePointSet::iterator itr = ps.begin();
01696
01697 while(itr != ps.end())
01698 {
01699 coords.push_back(itr->location());
01700
01701 ++itr;
01702 }
01703
01704 return TeConvexHull(coords);
01705 }
01706
01707
01708
01709
01710
01711
01712
01713 bool TeIsConvex(const TeLinearRing& ring)
01714 {
01715 bool aux = false;
01716
01717 short orientation = TeINTERSECTOR2::TeCCW(*(ring.end() - 2), ring[0], ring[1], aux);
01718
01719 const unsigned int nStep = ring.size() - 1;
01720
01721 for(unsigned int i = 1; i < nStep; ++i)
01722 {
01723 short this_orientation = TeINTERSECTOR2::TeCCW(ring[i-1], ring[i], ring[i+1], aux);
01724
01725 if(this_orientation == TeNOTURN)
01726 continue;
01727
01728 if((orientation != TeNOTURN) && (orientation != this_orientation))
01729 return false;
01730
01731 orientation = this_orientation;
01732 }
01733
01734 return true;
01735 }
01736
01737 short TeOrientation(const TeLinearRing& r)
01738 {
01739 double area = Te2Area(r);
01740
01741 if(area > 0.0)
01742 return TeCOUNTERCLOCKWISE;
01743
01744 if(area < 0.0)
01745 return TeCLOCKWISE;
01746
01747 return TeNOTURN;
01748 }
01749
01750 void TeGetMiddlePoint(const TeCoord2D &first, const TeCoord2D &last, TeCoord2D &middle)
01751 {
01752 double lenght,parts,curlenght,incx,incy,
01753 deltax,deltay,dx,dy;
01754 short i,nparts;
01755
01756 lenght = TeDistance(first,last);
01757 if(lenght == 0.)
01758 {
01759 middle = first;
01760 return;
01761 }
01762
01763 nparts = 2;
01764 parts = lenght/2.;
01765
01766 if(first.x() < last.x())
01767 incx = 1.;
01768 else
01769 incx = -1.;
01770
01771 if(first.y() < last.y())
01772 incy = 1.;
01773 else
01774 incy = -1.;
01775
01776 curlenght = 0.;
01777 deltax = fabs(first.x()-last.x());
01778 deltay = fabs(first.y()-last.y());
01779 for(i=0;i<(nparts-1);i++)
01780 {
01781 curlenght = curlenght + parts;
01782
01783 if(first.x() == last.x())
01784 {
01785 middle = TeCoord2D(first.x(),first.y()+(curlenght*incy));
01786 continue;
01787 }
01788
01789
01790 if(first.y() == last.y())
01791 {
01792 middle = TeCoord2D(first.x()+(curlenght*incx),first.y());
01793 continue;
01794 }
01795
01796
01797
01798
01799 dx = curlenght*deltax/lenght;
01800
01801
01802 dy = curlenght*deltay/lenght;
01803 middle = TeCoord2D(first.x()+(dx*incx),first.y()+(dy*incy));
01804 }
01805 }
01806
01807
01808
01809 double TeDistance(const TeCoord2D& c1, const TeCoord2D& c2)
01810 {
01811 return sqrt(((c2.x() - c1.x()) * (c2.x() - c1.x())) + ((c2.y()-c1.y()) * (c2.y() - c1.y())));
01812 }
01813
01814 double TeLength(const TeLine2D& l)
01815 {
01816 double len = 0.0;
01817
01818 unsigned int nStep = l.size() - 1;
01819
01820 for(unsigned int i = 0 ; i < nStep; ++i)
01821 len += TeDistance(l[i], l[i+1]);
01822
01823 return len;
01824 }
01825
01826 double TePerpendicularDistance(const TeCoord2D& first, const TeCoord2D& last, const TeCoord2D& pin, TeCoord2D &pinter)
01827 {
01828 double d12,xmin,ymin;
01829
01830 double xi = first.x();
01831 double xf = last.x();
01832 double yi = first.y();
01833 double yf = last.y();
01834 double x = pin.x();
01835 double y = pin.y();
01836
01837 double dx = xf - xi;
01838 double dy = yf - yi;
01839 double a2 = (y - yi) * dx - (x - xi)*dy;
01840
01841 if(dx==0. && dy==0.)
01842 {
01843 d12= sqrt(((x - xi) * (x - xi)) + ((y - yi) * (y - yi)));
01844 d12 *= d12;
01845 }
01846 else
01847 d12= a2 * a2 / (dx * dx + dy * dy);
01848
01849 if (dx == 0.)
01850 {
01851 xmin = xi;
01852 ymin = y;
01853 }
01854 else if (dy == 0.)
01855 {
01856 xmin = x;
01857 ymin = yi;
01858 }
01859 else
01860 {
01861 double alfa = dy / dx;
01862 xmin = (x + alfa * (y - yi) + alfa * alfa * xi) / (1. + alfa * alfa);
01863 ymin = (x - xmin) / alfa + y;
01864 }
01865
01866 pinter = TeCoord2D(xmin, ymin);
01867 return (sqrt(d12));
01868 }
01869
01870 double TeMinimumDistance (const TeCoord2D& first, const TeCoord2D& last, const TeCoord2D& pin, TeCoord2D& pout, double )
01871 {
01872 TeCoord2D pinter;
01873 TeBox sbox(MIN(first.x(),last.x()),
01874 MIN(first.y(),last.y()),
01875 MAX(first.x(),last.x()),
01876 MAX(first.y(),last.y()));
01877
01878 double d = TePerpendicularDistance (first, last, pin, pinter);
01879 double dmin = TeMAXFLOAT;
01880
01881
01882 if (TeIntersects (pinter, sbox))
01883 {
01884 dmin = d;
01885 pout = pinter;
01886 }
01887 else
01888 {
01889
01890
01891 double d1 = TeDistance (first, pin);
01892 double d2 = TeDistance (last, pin);
01893 if (d1 <= d2)
01894 {
01895 dmin = d1;
01896 pout = first;
01897 }
01898 else if (d2 < dmin)
01899 {
01900 dmin = d2;
01901 pout = last;
01902 }
01903 }
01904
01905 return dmin;
01906 }
01907
01908
01909
01910
01911 short TeRelation(const TeCoord2D& c, const TeLine2D& l)
01912 {
01913 if(TeEquals(c, l[0]) || TeEquals(c, l[l.size() - 1]))
01914 {
01915
01916 if(l.isRing())
01917 return TeINSIDE;
01918
01919 return TeBOUNDARY;
01920 }
01921
01922 if(TeIsOnLine(c, l))
01923 return TeINSIDE;
01924
01925 return TeOUTSIDE;
01926 }
01927
01928 short TeRelation(const TeCoord2D& c, const TeLinearRing& r)
01929 {
01930 if(TeDisjoint(c, r.box()))
01931 return TeOUTSIDE;
01932
01933 if(TeIsOnLine(c, r))
01934 return TeBOUNDARY;
01935
01936 if(TePointInPoly(c, r))
01937 return TeINSIDE;
01938 else
01939 return TeOUTSIDE;
01940 }
01941
01942 short TeRelation(const TeCoord2D& c, const TePolygon& pol)
01943 {
01944 short rel = TeRelation(c, pol[0]);
01945
01946 if(rel != TeINSIDE)
01947 return rel;
01948 else
01949 {
01950 unsigned int size = pol.size();
01951
01952 for(unsigned int i = 1; i < size; ++i)
01953 {
01954 rel = TeRelation(c, pol[i]);
01955
01956 switch(rel)
01957 {
01958
01959 case TeINSIDE : return TeOUTSIDE;
01960
01961
01962 case TeBOUNDARY : return TeBOUNDARY;
01963 }
01964 }
01965 }
01966
01967
01968 return TeINSIDE;
01969 }
01970
01971 short TeRelation(const TePoint& p, const TePolygon& pol)
01972 {
01973 return (TeRelation(p.location(), pol));
01974 }
01975
01976 short TeRelation(const TeCoord2D& c, const TePolygonSet& pSet)
01977 {
01978 if(TeDisjoint(c, pSet.box()))
01979 return TeOUTSIDE;
01980
01981 unsigned int size = pSet.size();
01982
01983 for(unsigned int i = 0; i < size; ++i)
01984 {
01985 short rel = TeRelation(c, pSet[i]);
01986
01987 if(rel & TeINSIDE)
01988 return TeINSIDE;
01989
01990 if(rel & TeBOUNDARY)
01991 return TeBOUNDARY;
01992 }
01993
01994 return TeOUTSIDE;
01995 }
01996
01997 short TeRelation(const TeLine2D& lRed, const TeLine2D& lBlue, const short& relation)
01998 {
01999 TeINTERSECTOR2::TeVectorBoundaryIP report;
02000
02001 if(TeINTERSECTOR2::TeSafeIntersections(lRed, lBlue, report))
02002 {
02003 short rel = Relation(lRed, lBlue, report, relation);
02004
02005
02006 if((relation == TeTOUCHES || relation == TeCROSSES) && rel != relation)
02007 return TeUNDEFINEDREL;
02008
02009 if(rel != TeUNDEFINEDREL)
02010 return rel;
02011
02012 TeINTERSECTOR2::TeVectorBoundaryIP::iterator it = report.begin();
02013 TeINTERSECTOR2::TeVectorBoundaryIP::iterator it_end = report.end();
02014
02015 for(unsigned int i = 0; i < report.size(); ++i)
02016 {
02017 swap(report[i].redPartNum_, report[i].bluePartNum_);
02018 swap(report[i].redSegNum_, report[i].blueSegNum_);
02019 }
02020
02021 rel = Relation(lBlue, lRed, report, relation);
02022
02023 if(rel != TeUNDEFINEDREL)
02024 return ConverseRelation(rel);
02025 else
02026 return TeOVERLAPS;
02027 }
02028 else
02029 return TeDISJOINT;
02030 }
02031
02032 short TeRelation(const TeLine2D& line, const TePolygon& pol)
02033 {
02034 short rel = TopologicRelation(line, pol[0]);
02035
02036 if(rel & TeTOUCHES || rel & TeCROSSES || rel & TeDISJOINT)
02037 return rel;
02038
02039
02040 register unsigned int i = 1;
02041 register unsigned int nRings = pol.size();
02042
02043 for(; i < nRings; ++i)
02044 {
02045 short rel_aux = TopologicRelation(line, pol[i]);
02046
02047 switch(rel_aux)
02048 {
02049 case TeCROSSES : return TeCROSSES;
02050
02051 case TeCOVEREDBY : return TeTOUCHES;
02052
02053 case TeTOUCHES : rel = TeCOVEREDBY;
02054 break;
02055
02056 case TeWITHIN : return TeDISJOINT;
02057
02058 case TeDISJOINT : break;
02059 }
02060 }
02061
02062 return rel;
02063 }
02064
02065 short TeRelation(const TePolygon& pRed, const TePolygon& pBlue)
02066 {
02067
02068 short rel = TopologicRelation(pRed[0], pBlue[0]);
02069
02070 if(rel & TeTOUCHES || rel & TeOVERLAPS || rel & TeDISJOINT)
02071 return rel;
02072
02073
02074 short rel_external_ring = TeUNDEFINEDREL;
02075
02076 bool converse = false;
02077
02078 vector<TeLinearRing> innerRingsToTest;
02079
02080 switch(rel)
02081 {
02082 case TeWITHIN :
02083 case TeCOVEREDBY :
02084
02085 if(pBlue.size() > 1)
02086 {
02087 rel_external_ring = LookAtInnerRings(pRed[0], pBlue, innerRingsToTest, rel);
02088 }
02089 else
02090 {
02091 return rel;
02092 }
02093 break;
02094
02095 case TeCONTAINS :
02096 case TeCOVERS :
02097
02098 if(pRed.size() > 1)
02099 {
02100 rel_external_ring = LookAtInnerRings(pBlue[0], pRed, innerRingsToTest, rel);
02101 }
02102 else
02103 {
02104 return rel;
02105 }
02106
02107 converse = true;
02108 break;
02109
02110 case TeEQUALS :
02111 if(pRed.size() != pBlue.size())
02112 return TeOVERLAPS;
02113
02114 if(pRed.size() == 1 && pBlue.size() == 1)
02115 return rel;
02116
02117 for(unsigned int k = 1; k < pBlue.size(); k++)
02118 innerRingsToTest.push_back(pBlue[k]);
02119
02120 rel_external_ring = TeUNDEFINEDREL;
02121 }
02122
02123 if(rel_external_ring != TeUNDEFINEDREL)
02124 return rel_external_ring;
02125
02126
02127 if(converse)
02128 {
02129 if(pBlue.size() == 1 && innerRingsToTest.size() == 0)
02130 {
02131 TeSpatialRelation spatialRel = (TeSpatialRelation)rel;
02132 if (spatialRel == TeCOVEREDBY)
02133 return TeCOVERS;
02134 else
02135 return rel;
02136
02137
02138 }
02139
02140 short rel_aux = TestInnerRings(pBlue, innerRingsToTest);
02141
02142 if(rel_aux & TeOVERLAPS)
02143 return TeOVERLAPS;
02144
02145 if(rel_aux & TeCOVERS || rel_aux & TeEQUALS)
02146 return TeCOVERS;
02147
02148 if(rel_aux & TeCONTAINS)
02149 return TeCONTAINS;
02150 }
02151 else
02152 {
02153 if(pRed.size() == 1 && innerRingsToTest.size() == 0)
02154 return rel;
02155
02156 short rel_aux = TestInnerRings(pRed, innerRingsToTest);
02157
02158 if(rel_aux & TeOVERLAPS)
02159 return TeOVERLAPS;
02160
02161 if((rel_aux == TeEQUALS) && (rel == TeEQUALS))
02162 return TeEQUALS;
02163
02164 if((rel_aux & TeCOVERS) || (rel_aux & TeEQUALS))
02165 return TeCOVEREDBY;
02166
02167 if(rel_aux & TeCONTAINS)
02168 {
02169 if((rel == TeEQUALS) || (rel == TeCOVEREDBY))
02170 return TeCOVEREDBY;
02171
02172 return TeWITHIN;
02173 }
02174 }
02175
02176 return TeUNDEFINEDREL;
02177 }
02178
02179
02180
02181
02182 TePolygon TeMakePolygon(const TeBox& b)
02183 {
02184 TeLine2D l;
02185
02186 l.add(b.lowerLeft());
02187 l.add(TeCoord2D(b.x2(), b.y1()));
02188 l.add(b.upperRight());
02189 l.add(TeCoord2D(b.x1(), b.y2()));
02190 l.add(b.lowerLeft());
02191 l.setBox(b);
02192
02193 TePolygon p;
02194 p.add(TeLinearRing(l));
02195 p.setBox(b);
02196
02197 return p;
02198 }
02199
02200 TeLinearRing TeSimpleClosedPath(const TePointSet& pSet)
02201 {
02202 TeLine2D l;
02203
02204 for(register unsigned int i = 0; i < pSet.size(); ++i)
02205 l.add(pSet[i].location());
02206
02207 ThetaOrder tr(pSet[0].location());
02208
02209 sort(l.begin(), l.end(), tr);
02210
02211 l.add(l[0]);
02212
02213 return TeLinearRing(l);
02214 }
02215
02216
02217
02218
02219 bool TeNearest ( TeCoord2D& pt, TeNodeSet& ns , int& k, const double& tol)
02220 {
02221 double d,dmin = TeMAXFLOAT;
02222 bool flag = false;
02223
02224 k = -1;
02225 for (unsigned int i=0; i < ns.size() ; i++)
02226 {
02227 d = TeDistance (pt, ns[i].location());
02228 if ( d <= tol && d < dmin)
02229 {
02230 dmin = d;
02231 k = i;
02232 flag = true;
02233 }
02234 }
02235 return flag;
02236 }
02237
02238 bool TeNearest ( TeCoord2D& pt, TePointSet& ps , int& k, const double& tol)
02239 {
02240 double d,dmin = TeMAXFLOAT;
02241 bool flag = false;
02242
02243 k = -1;
02244 for (unsigned int i=0; i < ps.size() ; i++)
02245 {
02246 d = TeDistance (pt, ps[i].location());
02247 if ( d <= tol && d < dmin)
02248 {
02249 dmin = d;
02250 k = i;
02251 flag = true;
02252 }
02253 }
02254 return flag;
02255 }
02256
02257 bool TeNearest ( TeCoord2D& pt, TeTextSet& ts , int& k, const double& tol)
02258 {
02259 double d,dmin = TeMAXFLOAT;
02260 bool flag = false;
02261
02262 k = -1;
02263 for (unsigned int i=0; i < ts.size() ; i++)
02264 {
02265 d = TeDistance (pt, ts[i].location());
02266 if ( d <= tol && d < dmin)
02267 {
02268 dmin = d;
02269 k = i;
02270 flag = true;
02271 }
02272 }
02273 return flag;
02274 }
02275
02276 bool TeNearest(TeCoord2D& pt, TeLineSet& ls , int& k, TeCoord2D& pi, const double& tol)
02277 {
02278 double d,dmin = TeMAXFLOAT;
02279 bool flag = false;
02280
02281 k = -1;
02282 for (unsigned int i=0 ; i<ls.size() ; i++)
02283 {
02284 TeLine2D line = ls[i];
02285 TeBox lb = line.box();
02286 TeBox box(lb.x1()-tol,lb.y1()-tol,lb.x2()+tol,lb.y2()+tol);
02287 if (TeIntersects(pt, box))
02288 {
02289 for (unsigned int j=0 ; j<line.size()-1 ; j++)
02290 {
02291 TeCoord2D pinter;
02292 TeBox sbox(MIN(line[j].x(),line[j+1].x()),
02293 MIN(line[j].y(),line[j+1].y()),
02294 MAX(line[j].x(),line[j+1].x()),
02295 MAX(line[j].y(),line[j+1].y()));
02296 d = TePerpendicularDistance (line[j],line[j+1],pt, pinter);
02297 if((d <= tol) && (d < dmin) && TeIntersects(pinter, sbox))
02298 {
02299 dmin = d;
02300 k = i;
02301 pi = pinter;
02302 flag = true;
02303 }
02304 }
02305 }
02306 }
02307 return flag;
02308 }
02309
02310
02311 bool TeNearest (TeCoord2D& pt,TeLineSet& ls, int& lindex, TeCoord2D& pout, double& dmin, const double& tol)
02312 {
02313 bool flag = false;
02314 TeCoord2D pinter;
02315
02316 dmin = TeMAXFLOAT;
02317 lindex = -1;
02318
02319 for (unsigned int i = 0 ; i < ls.size(); i++)
02320 {
02321 TeLine2D line = ls[i];
02322
02323 for (unsigned int j = 0 ; j < line.size() - 1 ; j++)
02324 {
02325 double d = TeMinimumDistance (line[j], line[j + 1], pt, pinter, tol);
02326 if (d < dmin)
02327 {
02328 lindex = i;
02329 pout = pinter;
02330 dmin = d;
02331 flag = true;
02332 }
02333 }
02334 }
02335 return flag;
02336 }
02337
02338 bool TeNearest(TeCoord2D& pt, TePolygonSet& ps , int& k, const double& )
02339 {
02340 bool flag = false;
02341
02342 k = -1;
02343
02344 TePoint ptaux(pt);
02345
02346 for (unsigned int i=0; i < ps.size() ; i++)
02347 {
02348 if (TeIntersects(ptaux,ps[i]))
02349 {
02350 k = i;
02351 flag = true;
02352 }
02353 }
02354 return flag;
02355 }
02356
02357 bool TeNearestByPoints ( TeCoord2D& pt, TeLineSet& ls , int& k, double& dist, const double& tol)
02358 {
02359 double d,dmin = TeMAXFLOAT;
02360 bool flag = false;
02361
02362 k = -1;
02363 for (unsigned int i=0 ; i<ls.size() ; i++)
02364 {
02365 TeLine2D line = ls[i];
02366 TeBox lb = line.box();
02367 TeBox box(lb.x1()-tol,lb.y1()-tol,lb.x2()+tol,lb.y2()+tol);
02368 if (TeIntersects (pt,box))
02369 {
02370 for (unsigned int j=0 ; j<line.size()-1 ; j++)
02371 {
02372 d = TeDistance (line[j],pt);
02373 if ( d <= tol && d < dmin )
02374 {
02375 dmin = d;
02376 dist = dmin;
02377 k = i;
02378 flag = true;
02379 }
02380 }
02381 }
02382 }
02383 return flag;
02384 }
02385
02386
02387
02388
02389 bool TeFindTriangleCenter(const TeCoord2D& vert0, const TeCoord2D& vert1, const TeCoord2D& vert2, TeCoord2D& pc )
02390 {
02391 if ( vert0 == vert1 || vert0 == vert2 )
02392 return false;
02393
02394
02395 bool perpvert1 = false,
02396 perpvert2 = false;
02397 double m1 = 10., m2 =10.;
02398 double prcsion = 1.0e-10;
02399 double oldPrcsion = TePrecision::instance().precision();
02400 TePrecision::instance().setPrecision(prcsion);
02401
02402 if ( TeCoord2D( 0., vert0.y() ) == TeCoord2D( 0., vert1.y() ) )
02403 perpvert1 = true;
02404 else
02405 m1 = -(vert1.x() - vert0.x()) / (vert1.y() - vert0.y());
02406
02407
02408 if ( TeCoord2D( 0., vert1.y() ) == TeCoord2D( 0., vert2.y() ) )
02409 perpvert2 = true;
02410 else
02411 m2 = -(vert2.x() - vert1.x()) / (vert2.y() - vert1.y());
02412
02413 TePrecision::instance().setPrecision(oldPrcsion);
02414
02415
02416 if (fabs( m1 - m2 ) > prcsion)
02417 {
02418
02419
02420
02421 TeCoord2D ptm1 = vert0;
02422 ptm1 += vert1;
02423 ptm1.scale ( 0.5, 0.5);
02424
02425
02426 TeCoord2D ptm2 = vert1;
02427 ptm2 += vert2;
02428 ptm2.scale ( 0.5, 0.5);
02429
02430
02431
02432 if (perpvert1 == true)
02433 {
02434 pc.x( ptm1.x() );
02435 pc.y( ptm2.y() + m2 * ( pc.x() - ptm2.x() ) );
02436 }
02437 else if (perpvert2 == true)
02438 {
02439 pc.x( ptm2.x() );
02440 pc.y( ptm1.y() + m1 * ( pc.x() - ptm1.x() ) );
02441 }
02442 else
02443 {
02444 pc.x( (m1*ptm1.x() - m2*ptm2.x() - ptm1.y() + ptm2.y())/(m1-m2) );
02445 pc.y( ptm1.y() + m1 * ( pc.x() - ptm1.x() ) );
02446 }
02447 return true;
02448 }
02449 return false;
02450 }
02451
02452 bool TeLineSimplify(TeLine2D& ptlist, double snap, double maxdist)
02453 {
02454
02455 if (snap == 0.0)
02456 return true;
02457
02458 int npts = ptlist.size();
02459 if ( npts <= 3 )
02460 return true;
02461 int npte = npts;
02462
02463 double snap2 = maxdist*maxdist;
02464 TeLine2D vxy;
02465 vxy.copyElements(ptlist);
02466
02467
02468 int npt;
02469 if ( ptlist.last() == vxy.first() )
02470 npt = npte - 1;
02471 else
02472 npt = npte;
02473 ptlist.clear();
02474
02475
02476 int i = 0;
02477 int numa = 0;
02478 int numpf = npt - 1;
02479
02480
02481 TeCoord2D axy = vxy[numa];
02482
02483
02484 TeCoord2D pfxy = vxy[numpf];
02485
02486 while (numa < (npt-1))
02487 {
02488 bool retv (false);
02489 double aa1 = 0.;
02490 double a = 0.;
02491 double b = 0.;
02492
02493 if (pfxy.x() == axy.x())
02494 retv = true;
02495 else
02496 {
02497 a = (pfxy.y() - axy.y())/(pfxy.x() - axy.x());
02498 b = pfxy.y() - a * pfxy.x();
02499 aa1 = sqrt(a * a + 1.);
02500 }
02501
02502 double d = 0;
02503 double dmax = 0;
02504 int numdmax = numpf;
02505
02506 int k;
02507 for (k = numa + 1; k <= numpf; k++)
02508 {
02509
02510 if (retv)
02511 d = fabs(axy.x() - vxy[k].x());
02512 else
02513 d = fabs(vxy[k].y() - a*vxy[k].x() - b)/aa1;
02514
02515 if (d > dmax)
02516 {
02517 dmax = d;
02518 numdmax = k;
02519 }
02520 }
02521
02522 if (dmax <= snap)
02523 {
02524
02525 if (i > (npt-1))
02526 return false;
02527 vxy[i++] = axy;
02528
02529 double axbx = pfxy.x()-axy.x();
02530 double ayby = pfxy.y()-axy.y();
02531 double dist2 = axbx*axbx + ayby*ayby;
02532 if (dist2 > snap2)
02533 {
02534 for (k = numpf; k > numa+1; k--)
02535 {
02536 axbx = vxy[k].x()-axy.x();
02537 ayby = vxy[k].y()-axy.y();
02538 dist2 = axbx*axbx + ayby*ayby;
02539 if (dist2 < snap2)
02540 break;
02541 }
02542
02543 numa = k;
02544 axy = vxy[k];
02545 }
02546 else
02547 {
02548
02549 numa = numpf;
02550 axy = vxy[numpf];
02551 }
02552 numpf = npt - 1;
02553 }
02554 else
02555 {
02556
02557 numpf = numdmax;
02558 }
02559
02560 pfxy = vxy[numpf];
02561 }
02562
02563
02564 vxy[i] = vxy[numa];
02565 npts = i+1;
02566
02567 if ( vxy[i] == vxy[i-1] )
02568 npts = i;
02569
02570 for (i = 0; i < npts; i++)
02571 ptlist.add( vxy[i] );
02572
02573
02574 if (vxy[0] == vxy[npte-1])
02575 ptlist.add( vxy[0] );
02576
02577 return true;
02578 }
02579
02580 bool TeSegmentsIntersectPoint(const TeCoord2D& fr0, const TeCoord2D& to0, const TeCoord2D& fr1, const TeCoord2D& to1, TeCoord2D& pi)
02581 {
02582
02583
02584
02585
02586 double a, b, c,
02587 px, py, lx, ly, lpx, lpy,
02588 s;
02589
02590 px = to0.x() - fr0.x();
02591 py = to0.y() - fr0.y();
02592 lx = to1.x() - fr1.x();
02593 ly = to1.y() - fr1.y();
02594 lpx = fr0.x() - fr1.x();
02595 lpy = fr0.y() - fr1.y();
02596
02597 a = py * lx - px * ly;
02598 b = lpx * ly - lpy * lx;
02599 c = lpx * py - lpy * px;
02600
02601 if (a == 0)
02602 return false;
02603 else
02604 {
02605 if (a > 0)
02606 {
02607 if ((b < 0) || (b > a) || (c < 0) || (c > a))
02608 return false;
02609 }
02610 else
02611 {
02612 if ((b > 0) || (b < a) || (c > 0) || (c < a))
02613 return false;
02614 }
02615 s = b/a;
02616 pi.x(fr0.x() + (px*s));
02617 pi.y(fr0.y() + (py*s));
02618 }
02619 return true;
02620 }
02621
02622
02623
02624
02625
02626
02627
02628
02629 void TeSwap(TePoint& p1, TePoint& p2)
02630 {
02631 TePoint temp;
02632
02633 temp = p1;
02634 p1 = p2;
02635 p2 = temp;
02636
02637 return;
02638 }
02639
02640 bool TeGetCenter(TePoint p1, TePoint p2, TePoint p3, TePoint& center)
02641 {
02642 double x, y;
02643 double ma=0., mb= 0.;
02644 bool result = true;
02645
02646
02647 if ((p1.location().x()==p2.location().x()) || (p1.location().y()==p2.location().y()))
02648 TeSwap(p2,p3);
02649
02650 if (p2.location().x()==p3.location().x())
02651 TeSwap(p1,p2);
02652
02653 if (p1.location().x()!=p2.location().x())
02654 ma=(p2.location().y()-p1.location().y())/(p2.location().x()-p1.location().x());
02655 else
02656 result=false;
02657
02658 if (p2.location().x()!=p3.location().x())
02659 mb=(p3.location().y()-p2.location().y())/(p3.location().x()-p2.location().x());
02660 else
02661 result=false;
02662
02663 if ((ma==0) && (mb==0))
02664 result=false;
02665
02666 if (result)
02667 {
02668 x=(ma*mb*(p1.location().y()-p3.location().y())+mb*(p1.location().x()+p2.location().x())-ma*(p2.location().x()+p3.location().x()))/(2*(mb-ma));
02669 y=-(x-(p1.location().x()+p2.location().x())/2)/ma + (p1.location().y()+p2.location().y())/2;
02670
02671 double w= x;
02672 double z= y;
02673 TeCoord2D coord(w,z);
02674 center.add(coord);
02675 }
02676 return result;
02677 }
02678
02679 double TeGetRadius(TePoint& p1, TePoint& p2, TePoint& p3)
02680 {
02681 double s,a,b,c, result;
02682 a=sqrt(pow(p1.location().x()-p2.location().x(),2)+pow(p1.location().y()-p2.location().y(),2));
02683 b=sqrt(pow(p2.location().x()-p3.location().x(),2)+pow(p2.location().y()-p3.location().y(),2));
02684 c=sqrt(pow(p3.location().x()-p1.location().x(),2)+pow(p3.location().y()-p1.location().y(),2));
02685 s=(a+b+c)/2;
02686 result=(a*b*c)/(4*sqrt(s*(s-a)*(s-b)*(s-c)));
02687 return result;
02688 }
02689
02690 bool TeGenerateArc(TePoint& p1, TePoint& p2, TePoint& p3, TeLine2D& arcOut, const short& NPoints)
02691 {
02692 TePoint center;
02693 double radius;
02694
02695 if(!TeGetCenter(p1, p2, p3, center))
02696 return false;
02697
02698 radius = TeGetRadius(p1, p2, p3);
02699
02700
02701 double length = TeDistance(p1.location(),p3.location());
02702
02703 double val = length/(2*radius);
02704 if(val>1)
02705 return false;
02706
02707
02708
02709
02710 double thetaR = 2 * asin(val);
02711
02712
02713 double deltaR = thetaR/(NPoints+1);
02714
02715
02716 TeLine2D line;
02717 line.add(p1.location());
02718 line.add(p2.location());
02719 line.add(p3.location());
02720 line.add(p1.location());
02721 TeLinearRing ring(line);
02722
02723 short orient = TeOrientation(ring);
02724
02725
02726
02727 double cosBeta = (p1.location().x()-center.location().x())/radius;
02728 double sinBeta = (p1.location().y()-center.location().y())/radius;
02729
02730
02731
02732
02733
02734
02735
02736 arcOut.add(p1.location());
02737 double angle = deltaR;
02738 for (int i=0; i<(NPoints+1); i++)
02739 {
02740 double x = 0.,y = 0.;
02741 if(orient==TeCOUNTERCLOCKWISE)
02742 {
02743
02744
02745 x = center.location().x() + radius * ((cosBeta*cos(angle))-(sinBeta*sin(angle)));
02746 y = center.location().y() + radius * ((sinBeta*cos(angle))+(cosBeta*sin(angle)));
02747 }
02748 else if (orient==TeCLOCKWISE)
02749 {
02750
02751
02752 x = center.location().x() + radius * ((cosBeta*cos(angle))+(sinBeta*sin(angle)));
02753 y = center.location().y() + radius * ((sinBeta*cos(angle))-(cosBeta*sin(angle)));
02754 }
02755
02756 TeCoord2D coord(x,y);
02757 arcOut.add(coord);
02758 angle += deltaR;
02759 }
02760 arcOut.add(p3.location());
02761 return true;
02762 }
02763
02764 bool TeGenerateCircle(const TePoint& center, const double& radius, TeLine2D& circle, const short& NPoints)
02765 {
02766
02767 double thetaR = 2 * 3.14159;
02768
02769
02770 double deltaR = thetaR/(NPoints+1);
02771
02772
02773 TePoint p1(center.location().x()+radius, center.location().y());
02774
02775
02776
02777 double cosBeta = 1;
02778 double sinBeta = 0;
02779
02780
02781
02782
02783
02784
02785
02786 circle.add(p1.location());
02787 double angle = deltaR;
02788 for (int i=0; i<(NPoints+1); i++)
02789 {
02790 double x,y;
02791
02792
02793
02794
02795
02796 x = center.location().x() + radius * ((cosBeta*cos(angle))-(sinBeta*sin(angle)));
02797 y = center.location().y() + radius * ((sinBeta*cos(angle))+(cosBeta*sin(angle)));
02798
02799 TeCoord2D coord(x,y);
02800 circle.add(coord);
02801 angle += deltaR;
02802 }
02803 circle.add(p1.location());
02804 return true;
02805 }
02806
02807 double TeGetPrecision(TeProjection* proj)
02808 {
02809 if(!proj)
02810 return 0.000000001;
02811
02812 if(proj->units() == "Meters")
02813 {
02814 return 0.001;
02815 }
02816
02817 return 0.000000001;
02818 }
02819
02820
02821
02822 bool TeAdjustSegment(TeCoord2D P0, TeCoord2D P1, double d0, TeCoord2D &P0out, TeCoord2D &P1out)
02823 {
02824 double vL_norm1;
02825 double vL_norm2;
02826
02827 try
02828 {
02829 if( P0 == P1 ) return false;
02830
02831 TeCoord2D vL1( (P1.x() - P0.x()), (P1.y() - P0.y()) );
02832 TeCoord2D vL2( -1 * (P1.x() - P0.x()), -1 * (P1.y() - P0.y()) );
02833 vL_norm1 = sqrt( vL1.x() * vL1.x() + vL1.y() * vL1.y() );
02834 vL_norm2 = sqrt( vL2.x() * vL2.x() + vL2.y() * vL2.y() );
02835
02836
02837 TeCoord2D uL1( ( vL1.x() / vL_norm1 ), ( vL1.y() / vL_norm1 ) );
02838 TeCoord2D uL2( ( vL2.x() / vL_norm2 ), ( vL2.y() / vL_norm2 ) );
02839 TeCoord2D pFim1 (P0.x() + uL1.x() * d0, P0.y() + uL1.y() * d0);
02840 TeCoord2D pFim2 (P0.x() + uL2.x() * d0, P0.y() + uL2.y() * d0);
02841
02842 if ( TeDistance(pFim1, P1) <= TeDistance(pFim2, P1) )
02843 {
02844 P0out = P0;
02845 P1out = pFim1;
02846 }
02847 else
02848 {
02849 P0out = P0;
02850 P1out = pFim2;
02851 }
02852 }
02853 catch(...)
02854 {
02855 return (false);
02856 }
02857 return (true);
02858 }
02859
02860 bool TeFindCentroid(const TeLine2D &line, TeCoord2D &p)
02861 {
02862
02863 double iDistance;
02864 float fMiddle=0.;
02865 float fSize=0.;
02866 int iCont=0;
02867 TeLine2D lneResult;
02868
02869
02870 iDistance=TeLength(line);
02871 if(iDistance<=0)
02872 {
02873 p=line[0];
02874 return false;
02875 }
02876
02877 fMiddle=(float)(((float) iDistance)/2.);
02878
02879 while(fSize<fMiddle)
02880 {
02881 lneResult.add(line[iCont]);
02882 iCont++;
02883 if(lneResult.size()>1)
02884 fSize=(float)TeLength(lneResult);
02885 }
02886
02887 if(fSize>fMiddle)
02888 {
02889 double dDistance=0;
02890 TeCoord2D coorP1,coorP2;
02891
02892 dDistance=TeDistance(lneResult[lneResult.size()-2],lneResult[lneResult.size()-1]);
02893
02894 dDistance-=(fSize-fMiddle);
02895
02896 TeAdjustSegment(lneResult[lneResult.size()-2],lneResult[lneResult.size()-1],dDistance,coorP1,coorP2);
02897 p=coorP2;
02898
02899 }
02900 else
02901 p=lneResult[lneResult.size()-1];
02902
02903 return true;
02904 }
02905
02906