1 #include "PolygonTriangulator.h" 110 #define sqr(t) (t)*(t) 113 enum Type { UNKNOWN, INPUT, INSERT, START, END, MERGE, SPLIT, REGULAR_UP, REGULAR_DOWN};
119 typedef std::map<unsigned int, Pointbase*> PointbaseMap;
120 typedef std::map<unsigned int, Linebase*> LineMap;
121 typedef std::priority_queue<Pointbase> PQueue;
123 typedef std::list<unsigned int> Monopoly;
124 typedef std::list<Monopoly> Monopolys;
125 typedef std::vector<unsigned int> Triangle;
126 typedef std::list<Triangle> Triangles;
127 typedef std::map<unsigned int, std::set<unsigned int> > AdjEdgeMap;
271 #define Absolute(a) ((a) >= 0.0 ? (a) : -(a)) 287 #define Fast_Two_Sum_Tail(a, b, x, y) \ 291 #define Fast_Two_Sum(a, b, x, y) \ 292 x = (REAL) (a + b); \ 293 Fast_Two_Sum_Tail(a, b, x, y) 295 #define Two_Sum_Tail(a, b, x, y) \ 296 bvirt = (REAL) (x - a); \ 298 bround = b - bvirt; \ 299 around = a - avirt; \ 302 #define Two_Sum(a, b, x, y) \ 303 x = (REAL) (a + b); \ 304 Two_Sum_Tail(a, b, x, y) 306 #define Two_Diff_Tail(a, b, x, y) \ 307 bvirt = (REAL) (a - x); \ 309 bround = bvirt - b; \ 310 around = a - avirt; \ 313 #define Two_Diff(a, b, x, y) \ 314 x = (REAL) (a - b); \ 315 Two_Diff_Tail(a, b, x, y) 320 #define Split(a, ahi, alo) \ 321 c = (REAL) (1.0 * a); \ 322 abig = (REAL) (c - a); \ 326 #define Two_Product_Tail(a, b, x, y) \ 327 Split(a, ahi, alo); \ 328 Split(b, bhi, blo); \ 329 err1 = x - (ahi * bhi); \ 330 err2 = err1 - (alo * bhi); \ 331 err3 = err2 - (ahi * blo); \ 332 y = (alo * blo) - err3 334 #define Two_Product(a, b, x, y) \ 335 x = (REAL) (a * b); \ 336 Two_Product_Tail(a, b, x, y) 341 #define Two_One_Diff(a1, a0, b, x2, x1, x0) \ 342 Two_Diff(a0, b , i, x0); \ 343 Two_Sum( a1, i, x2, x1) 345 #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \ 346 Two_One_Diff(a1, a0, b0, j, zero, x0); \ 347 Two_One_Diff(j, zero, b1, x3, x2, x1) 373 int fast_expansion_sum_zeroelim(
const int& elen, REAL* e,
const int& flen, REAL* f, REAL* h)
380 REAL avirt, bround, around;
381 int eindex, findex, hindex;
387 if ((fnow > enow) == (fnow > -enow)) {
395 if ((eindex < elen) && (findex < flen)) {
396 if ((fnow > enow) == (fnow > -enow)) {
397 Fast_Two_Sum(enow, Q, Qnew, hh);
400 Fast_Two_Sum(fnow, Q, Qnew, hh);
407 while ((eindex < elen) && (findex < flen)) {
408 if ((fnow > enow) == (fnow > -enow)) {
409 Two_Sum(Q, enow, Qnew, hh);
412 Two_Sum(Q, fnow, Qnew, hh);
421 while (eindex < elen) {
422 Two_Sum(Q, enow, Qnew, hh);
429 while (findex < flen) {
430 Two_Sum(Q, fnow, Qnew, hh);
437 if ((Q != 0.0) || (hindex == 0)) {
452 REAL estimate(
const int& elen, REAL* e)
458 for (eindex = 1; eindex < elen; ++eindex) {
490 REAL orient2dadapt(REAL* pa, REAL* pb, REAL* pc,
const REAL& detsum)
492 INEXACT REAL acx, acy, bcx, bcy;
493 REAL acxtail, acytail, bcxtail, bcytail;
494 INEXACT REAL detleft, detright;
495 REAL detlefttail, detrighttail;
497 REAL B[4], C1[8], C2[12], D[16];
499 int C1length, C2length, Dlength;
506 REAL avirt, bround, around;
509 REAL ahi, alo, bhi, blo;
510 REAL err1, err2, err3;
514 acx = (REAL) (pa[0] - pc[0]);
515 bcx = (REAL) (pb[0] - pc[0]);
516 acy = (REAL) (pa[1] - pc[1]);
517 bcy = (REAL) (pb[1] - pc[1]);
519 Two_Product(acx, bcy, detleft, detlefttail);
520 Two_Product(acy, bcx, detright, detrighttail);
522 Two_Two_Diff(detleft, detlefttail, detright, detrighttail,
523 B3, B[2], B[1], B[0]);
526 det = estimate(4, B);
529 if ((det >= errbound) || (-det >= errbound)) {
533 Two_Diff_Tail(pa[0], pc[0], acx, acxtail);
534 Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail);
535 Two_Diff_Tail(pa[1], pc[1], acy, acytail);
536 Two_Diff_Tail(pb[1], pc[1], bcy, bcytail);
538 if ((acxtail == 0.0) && (acytail == 0.0)
539 && (bcxtail == 0.0) && (bcytail == 0.0)) {
544 errbound = detsum + Absolute(det);
545 det += (acx * bcytail + bcy * acxtail)
546 - (acy * bcxtail + bcx * acytail);
547 if ((det >= errbound) || (-det >= errbound)) {
551 Two_Product(acxtail, bcy, s1, s0);
552 Two_Product(acytail, bcx, t1, t0);
553 Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
555 C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1);
557 Two_Product(acx, bcytail, s1, s0);
558 Two_Product(acy, bcxtail, t1, t0);
559 Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
561 C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2);
563 Two_Product(acxtail, bcytail, s1, s0);
564 Two_Product(acytail, bcxtail, t1, t0);
565 Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
567 Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D);
569 return(D[Dlength - 1]);
572 REAL orient2d(REAL* pa, REAL* pb, REAL* pc)
574 REAL detleft, detright, det;
575 REAL detsum, errbound;
577 detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]);
578 detright = (pa[1] - pc[1]) * (pb[0] - pc[0]);
579 det = detleft - detright;
582 if (detright <= 0.0) {
585 detsum = detleft + detright;
587 }
else if (detleft < 0.0) {
588 if (detright >= 0.0) {
591 detsum = -detleft - detright;
599 if ((det >= errbound) || (-det >= errbound)) {
603 return orient2dadapt(pa, pb, pc, detsum);
632 template <
class T,
class KeyType>
635 template <
class T,
class KeyType>
640 BTreeNode( ) : m_data(), m_left(
nullptr ), m_right(
nullptr ), m_visited(
false) { }
641 BTreeNode(
const T & data, BTreeNode *lt, BTreeNode *rt )
642 : m_data(data),m_left( lt ), m_right( rt ), m_visited(
false) { }
644 T& data() {
return m_data; }
645 BTreeNode* Left() {
return m_left; }
646 BTreeNode* Right() {
return m_right; }
647 void SetVisited(
const bool& visited) { m_visited=visited; }
648 bool GetVisited() {
return m_visited; }
649 KeyType keyValue() {
return m_data->keyValue(); }
660 template <
class T,
class KeyType>
664 explicit SplayTree( ):m_root(
nullptr),m_size(0) { }
669 bool IsEmpty( )
const;
670 long int Size() {
return m_size; }
684 void Insert(
const T & x );
685 void Delete(
const KeyType& keys);
692 { PreOrder(Visit, m_root); }
694 { InOrder(Visit, m_root); }
697 { InOrder(Visit, m_root, y); }
700 { PostOrder(Visit, m_root); }
702 int Height( )
const {
return Height(m_root); }
733 template <
class T,
class KeyType>
742 template <
class T,
class KeyType>
751 template <
class T,
class KeyType>
758 if( m_root ==
nullptr )
760 newNode->m_left = newNode->m_right =
nullptr;
761 m_root = newNode; ++m_size;
765 KeyType keys=x->keyValue();
766 splay( keys, m_root );
767 KeyType rootk=m_root->keyValue();
770 newNode->m_left = m_root->m_left;
771 newNode->m_right = m_root;
772 m_root->m_left =
nullptr;
776 else if( keys > rootk )
779 newNode->m_right = m_root->m_right;
780 newNode->m_left = m_root;
781 m_root->m_right =
nullptr;
788 x->increaseKeyValue(1.0e-10);
798 template <
class T,
class KeyType>
803 splay( keys, m_root );
804 if( m_root->keyValue() != keys ) { res=
nullptr;
return; }
808 if( m_root->m_left ==
nullptr )
809 newTree = m_root->m_right;
814 newTree = m_root->m_left;
815 splay( keys, newTree );
816 newTree->m_right = m_root->m_right;
826 template <
class T,
class KeyType>
831 splay( keys, m_root );
832 KeyType rootk=m_root->keyValue();
833 if( rootk != keys ) {
return; }
835 if( m_root->m_left ==
nullptr ) newTree = m_root->m_right;
840 newTree = m_root->m_left;
841 splay( keys, newTree );
842 newTree->m_right = m_root->m_right;
855 template <
class T,
class KeyType>
858 if( IsEmpty( ) ) { min=
nullptr;
return; }
861 splay( keys, m_root );
866 if( m_root->m_left ==
nullptr ) newTree = m_root->m_right;
869 newTree = m_root->m_left;
870 splay( keys, newTree );
871 newTree->m_right = m_root->m_right;
882 template <
class T,
class KeyType>
885 if( IsEmpty( ) ) { max=
nullptr;
return; }
888 splay( keys, m_root );
893 if( m_root->m_left ==
nullptr ) newTree = m_root->m_right;
896 newTree = m_root->m_left;
897 splay( keys, newTree );
898 newTree->m_right = m_root->m_right;
908 template <
class T,
class KeyType>
911 if( IsEmpty( ) ) { min=
nullptr;
return; }
914 while( ptr->m_left !=
nullptr ) ptr = ptr->m_left;
915 splay( ptr->keyValue(), m_root );
922 template <
class T,
class KeyType>
925 if( IsEmpty( ) ) { max=
nullptr;
return; }
928 while( ptr->m_right !=
nullptr ) ptr = ptr->m_right;
929 splay( ptr->keyValue(), m_root );
937 template <
class T,
class KeyType>
940 if( IsEmpty( ) ) { res=
nullptr;
return; }
941 splay( keys, m_root );
942 if( m_root->keyValue() != keys ) { res=
nullptr;
return; }
951 template <
class T,
class KeyType>
954 if( IsEmpty( ) ) { res=
nullptr;
return; }
955 splay( keys, m_root );
957 if( m_root->data()->keyValue() < keys) res=m_root;
958 else if(m_root->m_left)
961 while(res->m_right) res=res->m_right;
972 template <
class T,
class KeyType>
986 template <
class T,
class KeyType>
989 return m_root ==
nullptr;
995 template <
class T,
class KeyType>
1001 m_root = clone( rhs.m_root );
1012 template <
class T,
class KeyType>
1019 header.m_left = header.m_right =
nullptr;
1020 leftTreeMax = rightTreeMin = &header;
1024 KeyType rkey=t->keyValue();
1027 if(t->m_left ==
nullptr)
break;
1028 if( keys < t->m_left->keyValue() ) rotateWithLeftChild( t );
1029 if( t->m_left ==
nullptr )
break;
1032 rightTreeMin->m_left = t;
1036 else if( keys > rkey )
1038 if( t->m_right ==
nullptr )
break;
1039 if( keys > t->m_right->keyValue() ) rotateWithRightChild( t );
1040 if( t->m_right ==
nullptr )
break;
1043 leftTreeMax->m_right = t;
1050 leftTreeMax->m_right = t->m_left;
1051 rightTreeMin->m_left = t->m_right;
1052 t->m_left = header.m_right;
1053 t->m_right = header.m_left;
1060 template <
class T,
class KeyType>
1064 k2->m_left = k1->m_right;
1072 template <
class T,
class KeyType>
1076 k1->m_right = k2->m_left;
1085 template <
class T,
class KeyType>
1088 if( t != t->m_left )
1090 reclaimMemory( t->m_left );
1091 reclaimMemory( t->m_right );
1100 template <
class T,
class KeyType>
1103 if( t == t->m_left )
1112 template<
class T,
class KeyType>
1118 PreOrder(Visit,t->m_left);
1119 PreOrder(Visit,t->m_right);
1127 template<
class T,
class KeyType>
1132 InOrder(Visit,t->m_left);
1134 InOrder(Visit,t->m_right);
1142 template<
class T,
class KeyType>
1148 InOrder(Visit,t->m_left, y);
1150 InOrder(Visit,t->m_right, y);
1159 template<
class T,
class KeyType>
1164 PostOrder(Visit,t->m_left);
1165 PostOrder(Visit,t->m_right);
1173 template<
class T,
class KeyType>
1176 if(subtree==
nullptr)
return 0;
1177 int lh=Height(subtree->m_left);
1178 int rh=Height(subtree->m_right);
1180 return (lh>rh)?(++lh):(++rh);
1213 Pointbase(): id(0), x(0.), y(0.), type(UNKNOWN), left(
false){}
1216 Pointbase(
const double& xx,
const double& yy)
1217 :id(0), x(xx), y(yy), type(UNKNOWN), left(
false) { }
1219 Pointbase(
const int& idd,
const double& xx,
const double& yy)
1220 :id(idd), x(xx), y(yy), type(UNKNOWN), left(
false) { }
1222 Pointbase(
const double& xx,
const double& yy,
const Type& ttype)
1223 :id(0), x(xx), y(yy), type(ttype), left(
false) { }
1225 Pointbase(
const int& idd,
const double& xx,
const double& yy,
const Type& ttype)
1226 :id(idd),x(xx), y(yy), type(ttype), left(
false) { }
1264 unsigned int id()
const {
return m_id; }
1267 Pointbase* endPoint(
const int& i)
const {
return m_endp[i]; }
1268 Type type()
const {
return m_type; }
1269 double keyValue()
const {
return m_key; }
1270 void setKeyValue(
const double& y);
1272 void increaseKeyValue(
const double& diff) { m_key+=diff; }
1277 void setHelper(
const unsigned int& i) { m_helper=i; }
1278 unsigned int helper() {
return m_helper; }
1286 unsigned int m_helper;
1290 if (
this != &line) {
1291 this->m_id=line.m_id;
1292 this->m_endp[0]=line.m_endp[0];
1293 this->m_endp[1]=line.m_endp[1];
1294 this->m_type=line.m_type;
1295 this->m_key=line.m_key;
1296 this->m_helper=line.m_helper;
1327 extern double orient2d(
double* pa,
double* pb,
double* pc);
1334 return sqr(sp.x-ep.x)+sqr(sp.y-ep.y);
1340 double dist_sqr(
double *pa,
double *pb)
1342 return sqr(pa[0]-pb[0])+sqr(pa[1]-pb[1]);
1347 node->data()->setKeyValue(y);
1353 Pointbase::Pointbase(
const Pointbase& pb)
1367 return (pa.x==pb.x && pa.y==pb.y);
1373 return( (pa.y > pb.y) || ( (pa.y==pb.y) && (pa.x < pb.x)) );
1379 return( (pa.y < pb.y) || ( (pa.y==pb.y) && (pa.x > pb.x)) );
1385 return !(pa.x==pb.x && pa.y==pb.y);
1391 Linebase::Linebase():m_type(UNKNOWN),m_key(0.),m_helper(0)
1393 for(
int i=0; i<2; ++i) m_endp[i]=0;
1400 Linebase::Linebase(
Pointbase* sp,
Pointbase* ep,
const Type& type,
long int & l_id):m_type(type),m_key(0.),m_helper(0)
1410 Linebase::Linebase(
const Linebase& line)
1412 this->m_id=line.m_id;
1413 this->m_endp[0]=line.m_endp[0];
1414 this->m_endp[1]=line.m_endp[1];
1415 this->m_type=line.m_type;
1416 this->m_key=line.m_key;
1417 this->m_helper=line.m_helper;
1424 void Linebase::reverse()
1426 assert(m_type==INSERT);
1428 m_endp[0]=m_endp[1];
1432 void Linebase::setKeyValue(
const double& y)
1434 if( m_endp[1]->y==m_endp[0]->y )
1435 m_key=m_endp[0]->x < m_endp[1]->x ? m_endp[0]->x:m_endp[1]->x;
1436 else m_key=( y - m_endp[0]->y ) * ( m_endp[1]->x - m_endp[0]->x ) / (m_endp[1]->y - m_endp[0]->y ) + m_endp[0]->x;
1445 Polygon(
const std::vector<double>& x,
const std::vector<double>& y);
1449 void partition2Monotone();
1450 void searchMonotones();
1451 void triangulation();
1454 const Triangles* triangles() {
return &m_triangles; }
1456 internal_poltrig::PointbaseMap& points() {
return m_points; }
1457 internal_poltrig::LineMap& edges() {
return m_edges; }
1463 void set_contour (
const std::vector<double>& x,
const std::vector<double>& y);
1464 void initializate();
1467 unsigned int prev(
const unsigned int& i);
1468 unsigned int next(
const unsigned int& i);
1471 void handleStartVertex(
const unsigned int& );
1472 void handleEndVertex(
const unsigned int& );
1473 void handleSplitVertex(
const unsigned int& );
1474 void handleMergeVertex(
const unsigned int& );
1475 void handleRegularVertexUp(
const unsigned int& );
1476 void handleRegularVertexDown(
const unsigned int& );
1479 void addDiagonal(
const unsigned int& i,
const unsigned int& j);
1483 double angleCosb(
double *A,
double *B,
double *C);
1488 void triangulateMonotone(internal_poltrig::Monopoly& mpoly);
1491 internal_poltrig::PQueue m_qpoints;
1493 internal_poltrig::Monopolys m_mpolys;
1494 Triangles m_triangles;
1497 internal_poltrig::AdjEdgeMap m_startAdjEdgeMap;
1498 internal_poltrig::LineMap m_diagonals;
1501 void init_vertices_and_lines();
1502 unsigned int m_ncontours;
1503 std::vector<unsigned int> m_nVertices;
1504 internal_poltrig::PointbaseMap m_points;
1505 internal_poltrig::LineMap m_edges;
1506 double m_xmin,m_xmax, m_ymin,m_ymax;
1511 void PolygonTriangulator::Polygon::init_vertices_and_lines()
1516 internal_poltrig::Type type;
1518 for(
unsigned j=0; j<m_ncontours; ++j)
1520 for(
unsigned i=1; i<=m_nVertices[j]; ++i)
1523 eid=(i==m_nVertices[j])?num+1:num+i+1;
1524 type = internal_poltrig::INPUT;
1526 m_edges[m_l_id]=line;
1528 num+=m_nVertices[j];
1532 for(
unsigned int i=0; i<m_ncontours; ++i)
1534 sum+= m_nVertices[i];
1544 void PolygonTriangulator::Polygon::set_contour(
const std::vector<double>& x,
const std::vector<double>& y)
1546 assert(x.size()==y.size());
1548 m_nVertices.push_back( x.size() );
1549 unsigned int i = m_points.size()+1;
1551 internal_poltrig::Type type;
1552 for (
unsigned int j = 0; j < m_nVertices[m_ncontours]; ++j, ++i)
1556 type=internal_poltrig::INPUT;
1558 if(xx > m_xmax ) m_xmax=xx;
1559 if(xx < m_xmin ) m_xmin=xx;
1560 if(yy > m_ymax ) m_ymax=yy;
1561 if(yy < m_ymin ) m_ymin=yy;
1575 PolygonTriangulator::Polygon::Polygon(
const std::vector<double>& x,
const std::vector<double>& y)
1580 m_xmin = m_ymin = std::numeric_limits<double>::infinity();
1581 m_xmax = m_ymax = - std::numeric_limits<double>::infinity();
1585 init_vertices_and_lines();
1592 PolygonTriangulator::Polygon::~Polygon()
1595 internal_poltrig::PointbaseMap::iterator itp=m_points.begin();
1596 for(; itp!=m_points.end(); ++itp)
1601 internal_poltrig::LineMap::iterator itl=m_edges.begin();
1602 for(; itl!=m_edges.end(); ++itl)
1612 unsigned int PolygonTriangulator::Polygon::prev(
const unsigned int& i)
1614 unsigned int j(0),prevLoop(0),currentLoop(0);
1616 while ( i > m_nVertices[currentLoop] )
1618 prevLoop=currentLoop;
1622 if( i==1 || (i==m_nVertices[prevLoop]+1) ) j=m_nVertices[currentLoop];
1623 else if( i <= m_nVertices[currentLoop] ) j=i-1;
1631 unsigned int PolygonTriangulator::Polygon::next(
const unsigned int& i)
1633 unsigned int j(0),prevLoop(0),currentLoop(0);
1635 while ( i > m_nVertices[currentLoop] )
1637 prevLoop=currentLoop;
1641 if( i < m_nVertices[currentLoop] ) j=i+1;
1642 else if ( i==m_nVertices[currentLoop] )
1644 if( currentLoop==0) j=1;
1645 else j=m_nVertices[prevLoop]+1;
1658 void PolygonTriangulator::Polygon::initializate()
1660 internal_poltrig::PointbaseMap::iterator it=m_points.begin();
1661 for(; it!=m_points.end(); ++it)
1668 if( p > pnext && pprev > p )
1669 m_points[id]->type=internal_poltrig::REGULAR_DOWN;
1670 else if (p > pprev && pnext > p)
1671 m_points[id]->type=internal_poltrig::REGULAR_UP;
1674 double pa[2], pb[2], pc[2];
1676 pa[0]=m_points[idp]->x;
1677 pa[1]=m_points[idp]->y;
1679 pb[0]=m_points[id]->x;
1680 pb[1]=m_points[id]->y;
1682 pc[0]=m_points[idn]->x;
1683 pc[1]=m_points[idn]->y;
1685 double area=internal_poltrig::orient2d(pa,pb,pc);
1687 if( pprev > p && pnext > p ) m_points[id]->type=(area >0) ? internal_poltrig::END: internal_poltrig::MERGE ;
1688 if( pprev < p && pnext < p ) m_points[id]->type=(area >0) ? internal_poltrig::START : internal_poltrig::SPLIT;
1692 m_qpoints.push(*(it->second));
1694 m_startAdjEdgeMap[id].insert(
id);
1702 void PolygonTriangulator::Polygon::addDiagonal(
const unsigned int& i,
const unsigned int& j)
1704 internal_poltrig::Type type=internal_poltrig::INSERT;
1706 m_edges[diag->id()]=diag;
1708 m_startAdjEdgeMap[i].insert(diag->id());
1709 m_startAdjEdgeMap[j].insert(diag->id());
1711 m_diagonals[diag->id()]=diag;
1718 void PolygonTriangulator::Polygon::handleStartVertex(
const unsigned int& i)
1720 double y=m_points[i]->y;
1721 m_edgebst.InOrder(internal_poltrig::UpdateKey, y);
1723 m_edges[i]->setHelper(i);
1724 m_edges[i]->setKeyValue(y);
1725 m_edgebst.Insert(m_edges[i]);
1732 void PolygonTriangulator::Polygon::handleEndVertex(
const unsigned int& i)
1734 double y=m_points[i]->y;
1735 m_edgebst.InOrder(internal_poltrig::UpdateKey, y);
1737 unsigned int previ=prev(i);
1739 unsigned int helper=m_edges[previ]->helper();
1742 if(m_points[helper]->type==internal_poltrig::MERGE) addDiagonal(i, helper);
1743 m_edgebst.Delete(edge->keyValue());
1750 void PolygonTriangulator::Polygon::handleSplitVertex(
const unsigned int& i)
1752 double x=m_points[i]->x, y=m_points[i]->y;
1753 m_edgebst.InOrder(internal_poltrig::UpdateKey, y);
1756 m_edgebst.FindMaxSmallerThan(x, leftnode);
1759 unsigned int helper=leftedge->helper();
1760 addDiagonal(i, helper);
1762 leftedge->setHelper(i);
1763 m_edges[i]->setHelper(i);
1764 m_edges[i]->setKeyValue(y);
1765 m_edgebst.Insert(m_edges[i]);
1771 void PolygonTriangulator::Polygon::handleMergeVertex(
const unsigned int& i)
1773 double x=m_points[i]->x, y=m_points[i]->y;
1774 m_edgebst.InOrder(internal_poltrig::UpdateKey, y);
1776 unsigned int previ=prev(i);
1777 unsigned int helper=m_edges[previ]->helper();
1778 if (m_points[helper]->type==internal_poltrig::MERGE) addDiagonal(i, helper);
1779 m_edgebst.Delete(m_edges[previ]->keyValue());
1782 m_edgebst.FindMaxSmallerThan(x, leftnode);
1785 helper=leftedge->helper();
1786 if(m_points[helper]->type==internal_poltrig::MERGE) addDiagonal(i, helper);
1788 leftedge->setHelper(i);
1794 void PolygonTriangulator::Polygon::handleRegularVertexDown(
const unsigned int& i)
1796 double y=m_points[i]->y;
1797 m_edgebst.InOrder(internal_poltrig::UpdateKey, y);
1799 unsigned int previ=prev(i);
1800 unsigned int helper=m_edges[previ]->helper();
1801 if(m_points[helper]->type==internal_poltrig::MERGE) addDiagonal(i, helper);
1803 m_edgebst.Delete(m_edges[previ]->keyValue());
1804 m_edges[i]->setHelper(i);
1805 m_edges[i]->setKeyValue(y);
1806 m_edgebst.Insert(m_edges[i]);
1813 void PolygonTriangulator::Polygon::handleRegularVertexUp(
const unsigned int& i)
1815 double x=m_points[i]->x, y=m_points[i]->y;
1816 m_edgebst.InOrder(internal_poltrig::UpdateKey, y);
1819 m_edgebst.FindMaxSmallerThan(x, leftnode);
1823 unsigned int helper=leftedge->helper();
1824 if(m_points[helper]->type==internal_poltrig::MERGE) addDiagonal(i, helper);
1825 leftedge->setHelper(i);
1832 void PolygonTriangulator::Polygon::partition2Monotone()
1835 if(m_qpoints.top().type!=internal_poltrig::START)
1837 std::cout<<
"Please check your input polygon:\n1)orientations?\n2)duplicated points?\n";
1841 while(!m_qpoints.empty())
1845 unsigned int id=vertex.id;
1849 case internal_poltrig::START: handleStartVertex(
id);
break;
1850 case internal_poltrig::END: handleEndVertex(
id);
break;
1851 case internal_poltrig::MERGE: handleMergeVertex(
id);
break;
1852 case internal_poltrig::SPLIT: handleSplitVertex(
id);
break;
1853 case internal_poltrig::REGULAR_UP: handleRegularVertexUp(
id);
break;
1854 case internal_poltrig::REGULAR_DOWN: handleRegularVertexDown(
id);
break;
1856 std::cout<<
"No duplicated points please!\n";
1870 double PolygonTriangulator::Polygon::angleCosb(
double *pa,
double *pb,
double *pc)
1872 double dxab = pa[0] - pb[0];
1873 double dyab = pa[1] - pb[1];
1875 double dxcb = pc[0] - pb[0];
1876 double dycb = pc[1] - pb[1];
1878 double dxab2 = dxab * dxab;
1879 double dyab2 = dyab * dyab;
1880 double dxcb2 = dxcb * dxcb;
1881 double dycb2 = dycb * dycb;
1882 double ab = dxab2 + dyab2;
1883 double cb = dxcb2 + dycb2;
1885 double cosb = dxab * dxcb + dyab * dycb;
1886 double denom = sqrt( ab * cb);
1900 unsigned int eid= edge->endPoint(1)->id;
1901 std::set<unsigned int> edges=m_startAdjEdgeMap[eid];
1902 assert(!edges.empty());
1904 unsigned int nexte=0;
1905 if( edges.size() == 1 ) nexte=*(edges.begin());
1906 else if( edges.size() > 1 )
1908 unsigned int nexte_ccw(0), nexte_cw(0);
1909 double max=-2.0,min=2.0;
1912 std::set<unsigned int>::iterator it=edges.begin();
1913 for(; it!=edges.end(); ++it)
1915 if(*it==edge->id())
continue;
1916 double A[2], B[2], C[2];
1917 A[0]=edge->endPoint(0)->x; A[1]=edge->endPoint(0)->y;
1918 B[0]=edge->endPoint(1)->x; B[1]=edge->endPoint(1)->y;
1920 if(edge->endPoint(1)!=m_edges[*it]->endPoint(0)) m_edges[*it]->reverse();
1921 C[0]=m_edges[*it]->endPoint(1)->x; C[1]=m_edges[*it]->endPoint(1)->y;
1923 double area=internal_poltrig::orient2d(A, B, C);
1924 double cosb=angleCosb(A, B, C);
1926 if( area > 0 && max < cosb ) { nexte_ccw=*it; max=cosb; }
1927 else if( min > cosb ) { nexte_cw=*it; min=cosb; }
1930 nexte = (nexte_ccw!=0) ? nexte_ccw : nexte_cw;
1939 void PolygonTriangulator::Polygon::searchMonotones()
1943 internal_poltrig::LineMap edges=m_edges;
1945 while( edges.size() > m_diagonals.size() )
1948 internal_poltrig::Monopoly poly;
1949 internal_poltrig::LineMap::iterator it=edges.begin();
1954 poly.push_back(startp->id);
1958 endp=next->endPoint(1);
1959 if(next->type()!=internal_poltrig::INSERT)
1961 edges.erase(next->id());
1962 m_startAdjEdgeMap[next->endPoint(0)->id].erase(next->id());
1964 if(endp==startp)
break;
1965 poly.push_back(endp->id);
1967 unsigned int nexte=selectNextEdge(next);
1971 std::cout<<
"Please check your input polygon:\n";
1972 std::cout<<
"1)orientations?\n2)with duplicated points?\n3)is a simple one?\n";
1977 if(next->endPoint(0) !=endp ) next->reverse();
1980 m_mpolys.push_back(poly);
1988 void PolygonTriangulator::Polygon::triangulateMonotone(internal_poltrig::Monopoly& mpoly)
1990 internal_poltrig::PQueue qvertex;
1991 internal_poltrig::Monopoly::iterator it=mpoly.begin(), itnext;
1992 for(; itnext=it, it!=mpoly.end(); ++it)
1995 if(itnext==mpoly.end()) itnext=mpoly.begin();
1997 point.left=(point > pointnext)?
true:
false;
1998 qvertex.push(point);
2001 std::stack<internal_poltrig::Pointbase> spoint;
2002 for(
int i=0; i<2; ++i) { spoint.push(qvertex.top()); qvertex.pop(); }
2004 while ( qvertex.size() > 1 )
2009 if(topQueuePoint.left!=topStackPoint.left)
2011 while ( spoint.size() > 1 )
2017 v[0]=topQueuePoint.id;
2020 sort(v.begin(),v.end());
2021 m_triangles.push_back(v);
2025 spoint.push(topStackPoint);
2026 spoint.push(topQueuePoint);
2030 while( spoint.size() > 1 )
2035 spoint.push(stack1Point);
2036 double pa[2], pb[2], pc[2];
2037 pa[0]=topQueuePoint.x; pa[1]=topQueuePoint.y;
2038 pb[0]=stack2Point.x; pb[1]=stack2Point.y;
2039 pc[0]=stack1Point.x; pc[1]=stack1Point.y;
2041 double area=internal_poltrig::orient2d(pa,pb,pc);
2042 bool left=stack1Point.left;
2043 if( (area > 0 && left) || (area < 0 && !left ) )
2046 v[0]=topQueuePoint.id;
2047 v[1]=stack2Point.id;
2048 v[2]=stack1Point.id;
2049 sort(v.begin(),v.end());
2050 m_triangles.push_back(v);
2055 spoint.push(topQueuePoint);
2064 while( spoint.size() !=1 )
2071 v[0]=lastQueuePoint.id;
2074 sort(v.begin(),v.end());
2075 m_triangles.push_back(v);
2082 void PolygonTriangulator::Polygon::triangulation()
2084 partition2Monotone();
2086 internal_poltrig::Monopolys::iterator it=m_mpolys.begin();
2087 for(; it!=m_mpolys.end(); ++it)
2088 triangulateMonotone(*it);
2098 PolygonTriangulator::PolygonTriangulator(
const std::vector<double>& polygon_xcoords,
2099 const std::vector<double>& polygon_ycoords)
2100 : m_polygon(
new Polygon(polygon_xcoords,polygon_ycoords))
2102 m_polygon->triangulation();
2105 PolygonTriangulator::~PolygonTriangulator() {
delete m_polygon; }
2107 const PolygonTriangulator::Triangles* PolygonTriangulator::triangles()
const 2109 return m_polygon->triangles();