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 #ifndef _TTL_H_
00027 #define _TTL_H_
00028
00029
00030 #include <list>
00031 #include <iterator>
00032
00033
00034 #ifdef DEBUG_TTL
00035 static void errorAndExit(char* message) {
00036 cout << "\n!!! ERROR: " << message << " !!!\n" << endl;
00037 exit(-1);
00038 }
00039 #endif
00040
00041
00042 using namespace std;
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00103 namespace ttl {
00104
00105
00106 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00107
00108
00109
00110
00111 #if ((_MSC_VER > 0) && (_MSC_VER < 1300))
00112 #else
00113
00114
00115
00116 template<class TraitsType, class DartType, class PointType>
00117 bool insertNode(DartType& dart, PointType& point);
00118
00119 template<class TraitsType, class DartType>
00120 void removeRectangularBoundary(DartType& dart);
00121
00122 template<class TraitsType, class DartType>
00123 void removeNode(DartType& dart);
00124
00125 template<class TraitsType, class DartType>
00126 void removeBoundaryNode(DartType& dart);
00127
00128 template<class TraitsType, class DartType>
00129 void removeInteriorNode(DartType& dart);
00130
00131
00132
00133
00134 template<class TraitsType, class PointType, class DartType>
00135 bool locateFaceSimplest(const PointType& point, DartType& dart);
00136
00137 template<class TraitsType, class PointType, class DartType>
00138 bool locateTriangle(const PointType& point, DartType& dart);
00139
00140 template<class TraitsType, class PointType, class DartType>
00141 bool inTriangleSimplest(const PointType& point, const DartType& dart);
00142
00143 template<class TraitsType, class PointType, class DartType>
00144 bool inTriangle(const PointType& point, const DartType& dart);
00145
00146 template<class DartType, class DartListType>
00147 void getBoundary(const DartType& dart, DartListType& boundary);
00148
00149 template<class DartType>
00150 bool isBoundaryEdge(const DartType& dart);
00151
00152 template<class DartType>
00153 bool isBoundaryFace(const DartType& dart);
00154
00155 template<class DartType>
00156 bool isBoundaryNode(const DartType& dart);
00157
00158 template<class DartType>
00159 int getDegreeOfNode(const DartType& dart);
00160
00161 template<class DartType, class DartListType>
00162 void get_0_orbit_interior(const DartType& dart, DartListType& orbit);
00163
00164 template<class DartType, class DartListType>
00165 void get_0_orbit_boundary(const DartType& dart, DartListType& orbit);
00166
00167 template<class DartType>
00168 bool same_0_orbit(const DartType& d1, const DartType& d2);
00169
00170 template<class DartType>
00171 bool same_1_orbit(const DartType& d1, const DartType& d2);
00172
00173 template<class DartType>
00174 bool same_2_orbit(const DartType& d1, const DartType& d2);
00175
00176 template <class TraitsType, class DartType>
00177 bool swappableEdge(const DartType& dart, bool allowDegeneracy = false);
00178
00179 template<class DartType>
00180 void positionAtNextBoundaryEdge(DartType& dart);
00181
00182 template<class TraitsType, class DartType>
00183 bool convexBoundary(const DartType& dart);
00184
00185
00186
00187
00188 template<class TraitsType, class DartType, class DartListType>
00189 void optimizeDelaunay(DartListType& elist);
00190
00191 template <class TraitsType, class DartType, class DartListType>
00192 void optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end);
00193
00194 template<class TraitsType, class DartType>
00195 bool swapTestDelaunay(const DartType& dart, bool cycling_check = false);
00196
00197 template<class TraitsType, class DartType>
00198 void recSwapDelaunay(DartType& diagonal);
00199
00200 template<class TraitsType, class DartType, class ListType>
00201 void swapEdgesAwayFromInteriorNode(DartType& dart, ListType& swapped_edges);
00202
00203 template<class TraitsType, class DartType, class ListType>
00204 void swapEdgesAwayFromBoundaryNode(DartType& dart, ListType& swapped_edges);
00205
00206 template<class TraitsType, class DartType, class DartListType>
00207 void swapEdgeInList(const typename DartListType::iterator& it, DartListType& elist);
00208
00209
00210
00211
00212 template<class TraitsType, class DartType>
00213 DartType insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay);
00214
00215 #endif
00216
00217 #endif // DOXYGEN_SHOULD_SKIP_THIS
00218
00219
00220
00221
00222
00223
00226
00227
00267 template <class TraitsType, class DartType, class PointType>
00268 bool insertNode(DartType& dart, PointType& point) {
00269
00270 bool found = ttl::locateTriangle<TraitsType>(point, dart);
00271 if (!found) {
00272 #ifdef DEBUG_TTL
00273 cout << "ERROR: Triangulation::insertNode: NO triangle found. /n";
00274 #endif
00275 return false;
00276 }
00277
00278
00279 TraitsType::splitTriangle(dart, point);
00280
00281 DartType d1 = dart;
00282 d1.alpha2().alpha1().alpha2().alpha0().alpha1();
00283
00284 DartType d2 = dart;
00285 d2.alpha1().alpha0().alpha1();
00286
00287
00288 DartType d3 = dart;
00289 d3.alpha2();
00290 dart = d3;
00291
00292 d3.alpha0().alpha1();
00293
00294
00295 if (!ttl::isBoundaryEdge(d1)) {
00296 d1.alpha2();
00297 recSwapDelaunay<TraitsType>(d1);
00298 }
00299
00300
00301 if (!ttl::isBoundaryEdge(d2)) {
00302 d2.alpha2();
00303 recSwapDelaunay<TraitsType>(d2);
00304 }
00305
00306
00307
00308 dart.alpha2();
00309
00310 if (!ttl::isBoundaryEdge(d3)) {
00311 d3.alpha2();
00312 recSwapDelaunay<TraitsType>(d3);
00313 }
00314
00315 return true;
00316 }
00317
00318
00319
00320
00321 template <class TraitsType, class ForwardIterator, class DartType>
00322 void insertNodes(ForwardIterator first, ForwardIterator last, DartType& dart) {
00323
00324
00325
00326
00327 ForwardIterator it;
00328 for (it = first; it != last; ++it) {
00329 bool status = insertNode<TraitsType>(dart, **it);
00330 }
00331 }
00332
00333
00334
00351 template <class TraitsType, class DartType>
00352 void removeRectangularBoundary(DartType& dart) {
00353
00354 DartType d_next = dart;
00355 DartType d_iter;
00356
00357 for (int i = 0; i < 4; i++) {
00358 d_iter = d_next;
00359 d_next.alpha0();
00360 ttl::positionAtNextBoundaryEdge(d_next);
00361 ttl::removeBoundaryNode<TraitsType>(d_iter);
00362 }
00363
00364 dart = d_next;
00365 }
00366
00367
00368
00380 template <class TraitsType, class DartType>
00381 void removeNode(DartType& dart) {
00382
00383 if (ttl::isBoundaryNode(dart))
00384 ttl::removeBoundaryNode<TraitsType>(dart);
00385 else
00386 ttl::removeInteriorNode<TraitsType>(dart);
00387 }
00388
00389
00390
00401 template <class TraitsType, class DartType>
00402 void removeBoundaryNode(DartType& dart) {
00403
00404
00405
00406
00407
00408
00409
00410 if (!ttl::isBoundaryEdge(dart)) {
00411 dart.alpha1();
00412 ttl::positionAtNextBoundaryEdge(dart);
00413 }
00414
00415 list<DartType> swapped_edges;
00416 ttl::swapEdgesAwayFromBoundaryNode<TraitsType>(dart, swapped_edges);
00417
00418
00419
00420 DartType d_iter = dart;
00421 DartType dnext = dart;
00422 bool bend = false;
00423 while (bend == false) {
00424 dnext.alpha1().alpha2();
00425 if (ttl::isBoundaryEdge(dnext))
00426 bend = true;
00427
00428
00429 DartType n_bedge = d_iter;
00430 n_bedge.alpha1().alpha0().alpha1().alpha2();
00431
00432
00433 typename list<DartType>::iterator it;
00434 it = find(swapped_edges.begin(), swapped_edges.end(), n_bedge);
00435
00436 if (it != swapped_edges.end())
00437 swapped_edges.erase(it);
00438
00439
00440 TraitsType::removeBoundaryTriangle(d_iter);
00441 d_iter = dnext;
00442 }
00443
00444
00445 typedef list<DartType> DartListType;
00446 ttl::optimizeDelaunay<TraitsType, DartType, DartListType>(swapped_edges);
00447 }
00448
00449
00450
00465 template <class TraitsType, class DartType>
00466 void removeInteriorNode(DartType& dart) {
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 list<DartType> swapped_edges;
00483 ttl::swapEdgesAwayFromInteriorNode<TraitsType>(dart, swapped_edges);
00484
00485
00486
00487
00488 TraitsType::reverse_splitTriangle(dart);
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 ttl::optimizeDelaunay<TraitsType, DartType>(swapped_edges);
00502 }
00503
00505
00506
00507
00508
00509
00510
00513
00514
00515
00516 template <class TopologyElementType, class DartType>
00517 bool isMemberOfFace(const TopologyElementType& topologyElement, const DartType& dart) {
00518
00519
00520
00521
00522
00523 DartType dart_iter = dart;
00524 do {
00525 if (dart_iter.isMember(topologyElement))
00526 return true;
00527 dart_iter.alpha0().alpha1();
00528 } while (dart_iter != dart);
00529
00530 return false;
00531 }
00532
00533
00534
00535
00536 template <class TraitsType, class NodeType, class DartType>
00537 bool locateFaceWithNode(const NodeType& node, DartType& dart_iter) {
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 bool status = locateFaceSimplest<TraitsType>(node, dart_iter);
00548 if (status == false)
00549 return status;
00550
00551
00552
00553
00554
00555
00556
00557 return isMemberOfFace(node, dart_iter);
00558 }
00559
00560
00561
00586 template <class TraitsType, class PointType, class DartType>
00587 bool locateFaceSimplest(const PointType& point, DartType& dart) {
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 DartType dart_start;
00603 dart_start = dart;
00604 DartType dart_prev;
00605
00606 DartType d0;
00607 for (;;) {
00608 d0 = dart;
00609 d0.alpha0();
00610 if (TraitsType::orient2d(dart, d0, point) >= 0) {
00611 dart.alpha0().alpha1();
00612 if (dart == dart_start)
00613 return true;
00614 }
00615 else {
00616 dart_prev = dart;
00617 dart.alpha2();
00618 if (dart == dart_prev)
00619 return false;
00620
00621 dart_start = dart;
00622 dart_start.alpha0();
00623
00624 dart.alpha1();
00625 }
00626 }
00627 }
00628
00629
00630
00653 template <class TraitsType, class PointType, class DartType>
00654 bool locateTriangle(const PointType& point, DartType& dart) {
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 bool status = locateFaceSimplest<TraitsType>(point, dart);
00679 if (status == false)
00680 return status;
00681
00682
00683
00684
00685
00686
00687
00688 return inTriangle<TraitsType>(point, dart);
00689 }
00690
00691
00692
00705 template <class TraitsType, class PointType, class DartType>
00706 bool inTriangleSimplest(const PointType& point, const DartType& dart) {
00707
00708
00709
00710
00711
00712 DartType d_iter = dart;
00713 DartType d0 = d_iter;
00714 d0.alpha0();
00715 if (!TraitsType::orient2d(d_iter, d0, point) >= 0)
00716 return false;
00717
00718 d_iter.alpha0().alpha1();
00719 d0 = d_iter;
00720 d0.alpha0();
00721 if (!TraitsType::orient2d(d_iter, d0, point) >= 0)
00722 return false;
00723
00724 d_iter.alpha0().alpha1();
00725 d0 = d_iter;
00726 d0.alpha0();
00727 if (!TraitsType::orient2d(d_iter, d0, point) >= 0)
00728 return false;
00729
00730 return true;
00731 }
00732
00733
00734
00749 template <class TraitsType, class PointType, class DartType>
00750 bool inTriangle(const PointType& point, const DartType& dart) {
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762 typedef typename TraitsType::real_type real_type;
00763
00764 DartType dart_iter = dart;
00765
00766 real_type cr1 = TraitsType::crossProduct2d(dart_iter, point);
00767 if (cr1 < 0)
00768 return false;
00769
00770 dart_iter.alpha0().alpha1();
00771 real_type cr2 = TraitsType::crossProduct2d(dart_iter, point);
00772
00773 if (cr2 < 0)
00774 return false;
00775
00776 dart_iter.alpha0().alpha1();
00777 real_type cr3 = TraitsType::crossProduct2d(dart_iter, point);
00778 if (cr3 < 0)
00779 return false;
00780
00781
00782
00783
00784 if (cr1 != 0 || cr2 != 0 || cr3 != 0)
00785 return true;
00786
00787
00788
00789
00790
00791
00792 DartType dart_tmp = dart_iter;
00793 real_type sc1 = TraitsType::scalarProduct2d(dart_tmp,point);
00794 real_type sc2 = TraitsType::scalarProduct2d(dart_tmp.alpha0(), point);
00795
00796 if (sc1 >= 0 && sc2 >= 0) {
00797
00798 if (sc1 != 0 || sc2 != 0)
00799 return true;
00800 }
00801
00802 dart_tmp = dart_iter.alpha0().alpha1();
00803 sc1 = TraitsType::scalarProduct2d(dart_tmp,point);
00804 sc2 = TraitsType::scalarProduct2d(dart_tmp.alpha0(),point);
00805 if (sc1 >= 0 && sc2 >= 0) {
00806
00807 if (sc1 != 0 || sc2 != 0)
00808 return true;
00809 }
00810
00811 dart_tmp = dart_iter.alpha1();
00812 sc1 = TraitsType::scalarProduct2d(dart_tmp,point);
00813 sc2 = TraitsType::scalarProduct2d(dart_tmp.alpha0(),point);
00814 if (sc1 >= 0 && sc2 >= 0) {
00815
00816 if (sc1 != 0 || sc2 != 0)
00817 return true;
00818 }
00819
00820
00821
00822
00823
00824 return false;
00825 }
00826
00827
00828
00829
00830 template <class DartType>
00831 void getAdjacentTriangles(const DartType& dart, DartType& t1, DartType& t2, DartType& t3) {
00832
00833 DartType dart_iter = dart;
00834
00835
00836 if (dart_iter.alpha2() != dart) {
00837 t1 = dart_iter;
00838 dart_iter = dart;
00839 }
00840
00841
00842 dart_iter.alpha0();
00843 dart_iter.alpha1();
00844 DartType dart_prev = dart_iter;
00845 if ((dart_iter.alpha2()) != dart_prev) {
00846 t2 = dart_iter;
00847 dart_iter = dart_prev;
00848 }
00849
00850
00851 dart_iter.alpha0();
00852 dart_iter.alpha1();
00853 dart_prev = dart_iter;
00854 if ((dart_iter.alpha2()) != dart_prev)
00855 t3 = dart_iter;
00856 }
00857
00858
00859
00875 template <class DartType, class DartListType>
00876 void getBoundary(const DartType& dart, DartListType& boundary) {
00877
00878
00879 DartType dart_iter(dart);
00880 boundary.push_back(dart_iter);
00881 dart_iter.alpha0();
00882 positionAtNextBoundaryEdge(dart_iter);
00883
00884 while (dart_iter != dart) {
00885 boundary.push_back(dart_iter);
00886 dart_iter.alpha0();
00887 positionAtNextBoundaryEdge(dart_iter);
00888 }
00889 }
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00921 template <class DartType>
00922 bool isBoundaryEdge(const DartType& dart) {
00923
00924 DartType dart_iter = dart;
00925 if (dart_iter.alpha2() == dart)
00926 return true;
00927 else
00928 return false;
00929 }
00930
00931
00932
00936 template <class DartType>
00937 bool isBoundaryFace(const DartType& dart) {
00938
00939
00940
00941 DartType dart_iter(dart);
00942 DartType dart_prev;
00943
00944 do {
00945 dart_prev = dart_iter;
00946
00947 if (dart_iter.alpha2() == dart_prev)
00948 return true;
00949 else
00950 dart_iter = dart_prev;
00951
00952 dart_iter.alpha0();
00953 dart_iter.alpha1();
00954
00955 } while (dart_iter != dart);
00956
00957 return false;
00958 }
00959
00960
00961
00965 template <class DartType>
00966 bool isBoundaryNode(const DartType& dart) {
00967
00968
00969
00970 DartType dart_iter(dart);
00971 DartType dart_prev;
00972
00973
00974
00975
00976 do {
00977 dart_iter.alpha1();
00978 dart_prev = dart_iter;
00979 dart_iter.alpha2();
00980
00981 if (dart_iter == dart_prev)
00982 return true;
00983
00984 } while (dart_iter != dart);
00985
00986 return false;
00987 }
00988
00989
00990
00998 template <class DartType>
00999 int getDegreeOfNode(const DartType& dart) {
01000
01001 DartType dart_iter(dart);
01002 DartType dart_prev;
01003
01004
01005
01006
01007 int degree = 0;
01008 bool boundaryVisited = false;
01009 do {
01010 dart_iter.alpha1();
01011 degree++;
01012 dart_prev = dart_iter;
01013
01014 dart_iter.alpha2();
01015
01016 if (dart_iter == dart_prev) {
01017 if (!boundaryVisited) {
01018 boundaryVisited = true;
01019
01020 degree++;
01021 dart_iter = dart;
01022 dart_iter.alpha2();
01023 }
01024 else
01025 return degree;
01026 }
01027
01028 } while (dart_iter != dart);
01029
01030 return degree;
01031 }
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058 template <class DartType>
01059 void getNeighborNodes(const DartType& dart, list<DartType>& node_list, bool& boundary) {
01060
01061 DartType dart_iter(dart);
01062
01063 dart_iter.alpha0();
01064
01065 DartType dart_prev = dart_iter;
01066
01067 bool start_at_boundary = false;
01068 dart_iter.alpha2();
01069 if (dart_iter == dart_prev)
01070 start_at_boundary = true;
01071 else
01072 dart_iter = dart_prev;
01073
01074 DartType dart_start = dart_iter;
01075
01076 do {
01077 node_list.push_back(dart_iter);
01078 dart_iter.alpha1();
01079 dart_iter.alpha0();
01080 dart_iter.alpha1();
01081 dart_prev = dart_iter;
01082 dart_iter.alpha2();
01083 if (dart_iter == dart_prev) {
01084
01085 boundary = true;
01086 if (start_at_boundary == true) {
01087
01088 node_list.push_back(dart_iter);
01089 return;
01090 }
01091 else {
01092
01093
01094 dart_iter.alpha0();
01095 node_list.clear();
01096 getNeighborNodes(dart_iter, node_list, boundary);
01097 return;
01098 }
01099 }
01100 } while (dart_iter != dart_start);
01101
01102 boundary = false;
01103 }
01104
01105
01106
01123 template <class DartType, class DartListType>
01124 void get_0_orbit_interior(const DartType& dart, DartListType& orbit) {
01125
01126 DartType d_iter = dart;
01127 orbit.push_back(d_iter);
01128 d_iter.alpha1().alpha2();
01129
01130 while (d_iter != dart) {
01131 orbit.push_back(d_iter);
01132 d_iter.alpha1().alpha2();
01133 }
01134 }
01135
01136
01137
01157 template <class DartType, class DartListType>
01158 void get_0_orbit_boundary(const DartType& dart, DartListType& orbit) {
01159
01160 DartType dart_prev;
01161 DartType d_iter = dart;
01162 do {
01163 orbit.push_back(d_iter);
01164 d_iter.alpha1();
01165 dart_prev = d_iter;
01166 d_iter.alpha2();
01167 } while (d_iter != dart_prev);
01168
01169 orbit.push_back(d_iter);
01170 }
01171
01172
01173
01184 template <class DartType>
01185 bool same_0_orbit(const DartType& d1, const DartType& d2) {
01186
01187
01188 DartType d_iter = d2;
01189 DartType d_end = d2;
01190
01191 if (ttl::isBoundaryNode(d_iter)) {
01192
01193 ttl::positionAtNextBoundaryEdge(d_iter);
01194 d_end.alpha1();
01195 ttl::positionAtNextBoundaryEdge(d_end);
01196 }
01197
01198 for (;;) {
01199 if (d_iter == d1)
01200 return true;
01201 d_iter.alpha1();
01202 if (d_iter == d1)
01203 return true;
01204 d_iter.alpha2();
01205 if (d_iter == d_end)
01206 break;
01207 }
01208
01209 return false;
01210 }
01211
01212
01213
01218 template <class DartType>
01219 bool same_1_orbit(const DartType& d1, const DartType& d2) {
01220
01221 DartType d_iter = d2;
01222
01223 if (d_iter == d1 || d_iter.alpha0() == d1 || d_iter.alpha2() == d1 || d_iter.alpha0() == d1)
01224 return true;
01225 return false;
01226 }
01227
01228
01229
01234 template <class DartType>
01235 bool same_2_orbit(const DartType& d1, const DartType& d2) {
01236
01237 DartType d_iter = d2;
01238 if (d_iter == d1 || d_iter.alpha0() == d1 ||
01239 d_iter.alpha1() == d1 || d_iter.alpha0() == d1 ||
01240 d_iter.alpha1() == d1 || d_iter.alpha0() == d1)
01241 return true;
01242 return false;
01243 }
01244
01245
01246
01247
01248 template <class TraitsType, class DartType>
01249 bool degenerateTriangle(const DartType& dart) {
01250
01251
01252
01253
01254 DartType d1 = dart;
01255 DartType d2 = d1;
01256 d2.alpha1();
01257 if (TraitsType::crossProduct2d(d1,d2) == 0)
01258 return true;
01259
01260 return false;
01261 }
01262
01263
01264
01276 template <class TraitsType, class DartType>
01277 bool swappableEdge(const DartType& dart, bool allowDegeneracy) {
01278
01279
01280
01281 if (isBoundaryEdge(dart))
01282 return false;
01283
01284
01285 DartType d1 = dart;
01286 d1.alpha2().alpha1();
01287 DartType d2 = dart;
01288 d2.alpha1();
01289 if (allowDegeneracy) {
01290 if (TraitsType::crossProduct2d(d1,d2) < 0.0)
01291 return false;
01292 }
01293 else {
01294 if (TraitsType::crossProduct2d(d1,d2) <= 0.0)
01295 return false;
01296 }
01297
01298
01299 d1 = dart;
01300 d1.alpha0();
01301 d2 = d1;
01302 d1.alpha1();
01303 d2.alpha2().alpha1();
01304
01305 if (allowDegeneracy) {
01306 if (TraitsType::crossProduct2d(d1,d2) < 0.0)
01307 return false;
01308 }
01309 else {
01310 if (TraitsType::crossProduct2d(d1,d2) <= 0.0)
01311 return false;
01312 }
01313 return true;
01314 }
01315
01316
01317
01329 template <class DartType>
01330 void positionAtNextBoundaryEdge(DartType& dart) {
01331
01332 DartType dart_prev;
01333
01334
01335
01336
01337 do {
01338 dart.alpha1();
01339 dart_prev = dart;
01340 dart.alpha2();
01341 } while (dart != dart_prev);
01342 }
01343
01344
01345
01354 template <class TraitsType, class DartType>
01355 bool convexBoundary(const DartType& dart) {
01356
01357 list<DartType> blist;
01358 ttl::getBoundary(dart, blist);
01359
01360 int no;
01361 no = blist.size();
01362 typename list<DartType>::const_iterator bit = blist.begin();
01363 DartType d1 = *bit;
01364 ++bit;
01365 DartType d2;
01366 bool convex = true;
01367 for (; bit != blist.end(); ++bit) {
01368 d2 = *bit;
01369 double crossProd = TraitsType::crossProduct2d(d1, d2);
01370 if (crossProd < 0.0) {
01371
01372 convex = false;
01373 return convex;
01374 }
01375 d1 = d2;
01376 }
01377
01378
01379 d2 = *blist.begin();
01380 double crossProd = TraitsType::crossProduct2d(d1, d2);
01381 if (crossProd < 0.0) {
01382
01383 convex = false;
01384 }
01385
01386
01387
01388
01389 return convex;
01390 }
01391
01393
01394
01395
01396
01397
01398
01401
01402
01420 template <class TraitsType, class DartType, class DartListType>
01421 void optimizeDelaunay(DartListType& elist) {
01422 optimizeDelaunay<TraitsType, DartType, DartListType>(elist, elist.end());
01423 }
01424
01425
01426
01427 template <class TraitsType, class DartType, class DartListType>
01428 void optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end) {
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446 if (elist.empty())
01447 return;
01448
01449
01450 bool cycling_check = true;
01451 bool optimal = false;
01452 typename DartListType::iterator it;
01453
01454 typename DartListType::iterator end_opt = end;
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468 while(!optimal) {
01469 optimal = true;
01470 for (it = elist.begin(); it != end_opt; ++it) {
01471 if (ttl::swapTestDelaunay<TraitsType>(*it, cycling_check)) {
01472
01473
01474
01475
01476
01477
01478 ttl::swapEdgeInList<TraitsType, DartType>(it, elist);
01479
01480 optimal = false;
01481 }
01482 }
01483 }
01484 }
01485
01486
01487
01501 template <class TraitsType, class DartType>
01502 #if ((_MSC_VER > 0) && (_MSC_VER < 1300))//#ifdef _MSC_VER
01503 bool swapTestDelaunay(const DartType& dart, bool cycling_check = false) {
01504 #else
01505 bool swapTestDelaunay(const DartType& dart, bool cycling_check) {
01506 #endif
01507
01508
01509
01510
01511
01512
01513
01514
01515 typedef typename TraitsType::real_type real_type;
01516
01517 if (isBoundaryEdge(dart))
01518 return false;
01519
01520 DartType v11 = dart;
01521 v11.alpha1().alpha0();
01522 DartType v12 = v11;
01523 v12.alpha1();
01524
01525 DartType v22 = dart;
01526 v22.alpha2().alpha1().alpha0();
01527 DartType v21 = v22;
01528 v21.alpha1();
01529
01530 real_type cos1 = TraitsType::scalarProduct2d(v11,v12);
01531 real_type cos2 = TraitsType::scalarProduct2d(v21,v22);
01532
01533
01534
01535
01536
01537
01538 if (cos1 >= 0 && cos2 >= 0)
01539 return false;
01540 if (cos1 < 0 && cos2 < 0)
01541 return true;
01542
01543 real_type sin1 = TraitsType::crossProduct2d(v11,v12);
01544 real_type sin2 = TraitsType::crossProduct2d(v21,v22);
01545 real_type sin12 = sin1*cos2 + cos1*sin2;
01546 if (sin12 >= 0)
01547 return false;
01548
01549 if (cycling_check) {
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570 v11.alpha0();
01571 v12.alpha0();
01572 v21.alpha0();
01573 v22.alpha0();
01574
01575 cos1 = TraitsType::scalarProduct2d(v22,v11);
01576 cos2 = TraitsType::scalarProduct2d(v12,v21);
01577 sin1 = TraitsType::crossProduct2d(v22,v11);
01578 sin2 = TraitsType::crossProduct2d(v12,v21);
01579 sin12 = sin1*cos2 + cos1*sin2;
01580 if (sin12 < 0) {
01581
01582 return false;
01583 }
01584 }
01585
01586 return true;
01587 }
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01616 template <class TraitsType, class DartType>
01617 void recSwapDelaunay(DartType& diagonal) {
01618
01619 if (!ttl::swapTestDelaunay<TraitsType>(diagonal))
01620
01621 return;
01622
01623
01624 DartType oppEdge1 = diagonal;
01625 oppEdge1.alpha1();
01626 bool b1;
01627 if (ttl::isBoundaryEdge(oppEdge1))
01628 b1 = true;
01629 else {
01630 b1 = false;
01631 oppEdge1.alpha2();
01632 }
01633
01634
01635 DartType oppEdge2 = diagonal;
01636 oppEdge2.alpha0().alpha1().alpha0();
01637 bool b2;
01638 if (ttl::isBoundaryEdge(oppEdge2))
01639 b2 = true;
01640 else {
01641 b2 = false;
01642 oppEdge2.alpha2();
01643 }
01644
01645
01646 TraitsType::swapEdge(diagonal);
01647
01648 if (!b1)
01649 recSwapDelaunay<TraitsType>(oppEdge1);
01650 if (!b2)
01651 recSwapDelaunay<TraitsType>(oppEdge2);
01652 }
01653
01654
01655
01681 template <class TraitsType, class DartType, class ListType>
01682 void swapEdgesAwayFromInteriorNode(DartType& dart, ListType& swapped_edges) {
01683
01684
01685 DartType dnext = dart;
01686
01687
01688
01689
01690
01691
01692
01693
01694 bool allowDegeneracy = true;
01695
01696 int degree = ttl::getDegreeOfNode(dart);
01697 DartType d_iter;
01698 while (degree > 3) {
01699 d_iter = dnext;
01700 dnext.alpha1().alpha2();
01701
01702 if (ttl::swappableEdge<TraitsType>(d_iter, allowDegeneracy)) {
01703 TraitsType::swapEdge(d_iter);
01704
01705
01706
01707 DartType swapped_edge = d_iter;
01708 swapped_edge.alpha2().alpha0();
01709 swapped_edges.push_back(swapped_edge);
01710
01711 degree--;
01712 }
01713 }
01714
01715 dart = dnext;
01716 }
01717
01718
01719
01739 template <class TraitsType, class DartType, class ListType>
01740 void swapEdgesAwayFromBoundaryNode(DartType& dart, ListType& swapped_edges) {
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754 passes:
01755
01756
01757 DartType d_iter = dart;
01758 d_iter.alpha1().alpha2();
01759 DartType d_next = d_iter;
01760 bool bend = false;
01761 bool swapped_next_to_boundary = false;
01762 bool swapped_in_pass = false;
01763
01764 bool allowDegeneracy;
01765 DartType tmp1, tmp2;
01766
01767 while (!bend) {
01768
01769 d_next.alpha1().alpha2();
01770 if (ttl::isBoundaryEdge(d_next))
01771 bend = true;
01772
01773
01774
01775
01776 tmp1 = d_iter; tmp1.alpha1();
01777 tmp2 = d_iter; tmp2.alpha2().alpha1();
01778
01779 if (ttl::isBoundaryEdge(tmp1) && ttl::isBoundaryEdge(tmp2))
01780 allowDegeneracy = true;
01781 else
01782 allowDegeneracy = false;
01783
01784 if (ttl::swappableEdge<TraitsType>(d_iter, allowDegeneracy)) {
01785 TraitsType::swapEdge(d_iter);
01786
01787
01788
01789
01790 DartType swapped_edge = d_iter;
01791 swapped_edge.alpha2().alpha0();
01792 swapped_edges.push_back(swapped_edge);
01793
01794
01795 swapped_in_pass = true;
01796 if (bend)
01797 swapped_next_to_boundary = true;
01798 }
01799 if (!bend)
01800 d_iter = d_next;
01801 }
01802
01803
01804 if (swapped_next_to_boundary) {
01805
01806 d_iter.alpha1().alpha0().alpha1();
01807 }
01808 else {
01809 d_iter.alpha1();
01810 }
01811 ttl::positionAtNextBoundaryEdge(d_iter);
01812
01813 dart = d_iter;
01814
01815
01816 if (swapped_in_pass)
01817 goto passes;
01818 }
01819
01820
01821
01828 template <class TraitsType, class DartType, class DartListType>
01829 void swapEdgeInList(const typename DartListType::iterator& it, DartListType& elist) {
01830
01831 typename DartListType::iterator it1, it2, it3, it4;
01832 DartType dart(*it);
01833
01834
01835
01836
01837
01838 DartType d1 = dart; d1.alpha2().alpha1();
01839 DartType d2 = d1; d2.alpha0().alpha1();
01840 DartType d3 = dart; d3.alpha0().alpha1();
01841 DartType d4 = d3; d4.alpha0().alpha1();
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852 it1 = find(elist.begin(), elist.end(), d1);
01853 it2 = find(elist.begin(), elist.end(), d2);
01854 it3 = find(elist.begin(), elist.end(), d3);
01855 it4 = find(elist.begin(), elist.end(), d4);
01856
01857 TraitsType::swapEdge(dart);
01858
01859 *it = dart;
01860
01861
01862
01863 if (it1 != elist.end()) {
01864 d1 = dart; d1.alpha1().alpha0();
01865 *it1 = d1;
01866 }
01867 if (it2 != elist.end()) {
01868 d2 = dart; d2.alpha2().alpha1();
01869 *it2 = d2;
01870 }
01871 if (it3 != elist.end()) {
01872 d3 = dart; d3.alpha2().alpha1().alpha0().alpha1();
01873 *it3 = d3;
01874 }
01875 if (it4 != elist.end()) {
01876 d4 = dart; d4.alpha0().alpha1();
01877 *it4 = d4;
01878 }
01879 }
01880
01882
01883 };
01884
01885
01886
01887
01888
01889
01890
01891
01892 #include <ttl/ttl_constr.h>
01893
01894 #endif // _TTL_H_