42 for (
int i = 0; i <
mHalfEdge.count(); i++ )
51 QgsDebugMsg( QStringLiteral(
"performing consistency test" ) );
53 for (
int i = 0; i <
mHalfEdge.count(); i++ )
59 QgsDebugMsg( QStringLiteral(
"warning, first test failed" ) );
63 QgsDebugMsg( QStringLiteral(
"warning, second test failed" ) );
66 QgsDebugMsg( QStringLiteral(
"consistency test finished" ) );
72 int currentpoint = -10;
75 for (
const QgsPoint &point : points )
79 if ( actpoint != -100 )
85 if ( actpoint == -100 )
90 for ( ; i < points.size(); ++i )
93 if ( currentpoint != -100 && actpoint != -100 && currentpoint != actpoint )
97 actpoint = currentpoint;
125 unsigned int zedge =
insertEdge( -10, -10, -1,
false,
false );
126 unsigned int fedge =
insertEdge(
static_cast<int>( zedge ),
static_cast<int>( zedge ), 0,
false,
false );
127 (
mHalfEdge.at( zedge ) )->setDual(
static_cast<int>( fedge ) );
128 (
mHalfEdge.at( zedge ) )->setNext(
static_cast<int>( fedge ) );
137 QgsDebugMsg( QStringLiteral(
"second point is the same as the first point, it thus has not been inserted" ) );
144 unsigned int sedge =
insertEdge( -10, -10, 1,
false,
false );
145 unsigned int tedge =
insertEdge(
static_cast<int>( sedge ), 0, 0,
false,
false );
146 unsigned int foedge =
insertEdge( -10, 4, 1,
false,
false );
147 unsigned int fiedge =
insertEdge(
static_cast<int>( foedge ), 1, -1,
false,
false );
148 mHalfEdge.at( sedge )->setDual(
static_cast<int>( tedge ) );
149 mHalfEdge.at( sedge )->setNext(
static_cast<int>( fiedge ) );
150 mHalfEdge.at( foedge )->setDual(
static_cast<int>( fiedge ) );
151 mHalfEdge.at( foedge )->setNext(
static_cast<int>( tedge ) );
152 mHalfEdge.at( 0 )->setNext(
static_cast<int>( foedge ) );
153 mHalfEdge.at( 1 )->setNext(
static_cast<int>( sedge ) );
165 unsigned int edgea =
insertEdge( -10, -10, 2,
false,
false );
166 unsigned int edgeb =
insertEdge(
static_cast<int>( edgea ), 5, 1,
false,
false );
167 unsigned int edgec =
insertEdge( -10,
static_cast<int>( edgeb ), 2,
false,
false );
168 unsigned int edged =
insertEdge( -10, 2, 0,
false,
false );
169 unsigned int edgee =
insertEdge(
static_cast<int>( edged ), -10, 2,
false,
false );
170 unsigned int edgef =
insertEdge(
static_cast<int>( edgec ), 1, -1,
false,
false );
171 mHalfEdge.at( edgea )->setDual(
static_cast<int>( edgeb ) );
172 mHalfEdge.at( edgea )->setNext(
static_cast<int>( edged ) );
173 mHalfEdge.at( edgec )->setDual(
static_cast<int>( edgef ) );
174 mHalfEdge.at( edged )->setDual(
static_cast<int>( edgee ) );
175 mHalfEdge.at( edgee )->setNext(
static_cast<int>( edgef ) );
176 mHalfEdge.at( 5 )->setNext(
static_cast<int>( edgec ) );
177 mHalfEdge.at( 1 )->setNext(
static_cast<int>( edgee ) );
178 mHalfEdge.at( 2 )->setNext(
static_cast<int>( edgea ) );
184 unsigned int edgea =
insertEdge( -10, -10, 2,
false,
false );
185 unsigned int edgeb =
insertEdge(
static_cast<int>( edgea ), 0, 0,
false,
false );
186 unsigned int edgec =
insertEdge( -10,
static_cast<int>( edgeb ), 2,
false,
false );
187 unsigned int edged =
insertEdge( -10, 3, 1,
false,
false );
188 unsigned int edgee =
insertEdge(
static_cast<int>( edged ), -10, 2,
false,
false );
189 unsigned int edgef =
insertEdge(
static_cast<int>( edgec ), 4, -1,
false,
false );
190 mHalfEdge.at( edgea )->setDual(
static_cast<int>( edgeb ) );
191 mHalfEdge.at( edgea )->setNext(
static_cast<int>( edged ) );
192 mHalfEdge.at( edgec )->setDual(
static_cast<int>( edgef ) );
193 mHalfEdge.at( edged )->setDual(
static_cast<int>( edgee ) );
194 mHalfEdge.at( edgee )->setNext(
static_cast<int>( edgef ) );
195 mHalfEdge.at( 0 )->setNext(
static_cast<int>( edgec ) );
196 mHalfEdge.at( 4 )->setNext(
static_cast<int>( edgee ) );
197 mHalfEdge.at( 3 )->setNext(
static_cast<int>( edgea ) );
203 QgsDebugMsg( QStringLiteral(
"error: third point is on the same line as the first and the second point. It thus has not been inserted into the triangulation" ) );
254 unsigned int edge5 =
insertEdge( edge3, -10, -1,
false,
false );
267 unsigned int index = ccwedge;
274 if ( toswap == cwedge )
284 else if ( number >= 0 )
286 int nextnumber =
mHalfEdge[number]->getNext();
291 unsigned int edge2 =
insertEdge(
static_cast<int>( edge1 ), -10,
mPointVector.count() - 1,
false,
false );
293 unsigned int edge4 =
insertEdge(
static_cast<int>( edge3 ),
static_cast<int>( edge1 ),
mPointVector.count() - 1,
false,
false );
295 unsigned int edge6 =
insertEdge(
static_cast<int>( edge5 ),
static_cast<int>( edge3 ),
mPointVector.count() - 1,
false,
false );
298 mHalfEdge.at( edge1 )->setDual(
static_cast<int>( edge2 ) );
299 mHalfEdge.at( edge2 )->setNext(
static_cast<int>( edge5 ) );
300 mHalfEdge.at( edge3 )->setDual(
static_cast<int>( edge4 ) );
301 mHalfEdge.at( edge5 )->setDual(
static_cast<int>( edge6 ) );
302 mHalfEdge.at( number )->setNext(
static_cast<int>( edge2 ) );
303 mHalfEdge.at( nextnumber )->setNext(
static_cast<int>( edge4 ) );
304 mHalfEdge.at( nextnextnumber )->setNext(
static_cast<int>( edge6 ) );
313 else if ( number == -20 )
348 else if ( number == -100 || number == -5 )
356 else if ( number == -25 )
361 existingPoint->
setZ( std::max( newPoint->
z(), existingPoint->
z() ) );
379 for (
int i = 0; i <
mHalfEdge.count(); i++ )
393 if ( control > 1000000 )
399 for (
int i = 0; i <
mHalfEdge.count(); i++ )
409 int topoint =
mHalfEdge[actedge]->getPoint();
411 if ( frompoint == -1 || topoint == -1 )
413 for (
int i = 0; i <
mHalfEdge.count(); i++ )
432 else if ( leftofnumber <= 0.0 )
451 int firstendp = 0, secendp = 0, thendp = 0, fouendp = 0;
472 else if ( leftofvalue == 0 )
478 secendp =
mHalfEdge[actedge]->getPoint();
480 else if ( nulls == 1 )
484 fouendp =
mHalfEdge[actedge]->getPoint();
527 if ( numinstabs > 0 )
537 if ( firstendp == thendp || firstendp == fouendp )
543 else if ( secendp == thendp || secendp == fouendp )
572 if ( x1 < x2 && x1 < x3 )
576 else if ( x2 < x1 && x2 < x3 )
580 else if ( x3 < x1 && x3 < x2 )
629 QgsDebugMsg( QStringLiteral(
"warning, null pointer" ) );
642 QgsDebugMsg( QStringLiteral(
"warning, null pointer" ) );
657 doSwap( edge, recursiveDeep );
666 unsigned int edge1 = edge;
667 unsigned int edge2 =
mHalfEdge[edge]->getDual();
668 unsigned int edge3 =
mHalfEdge[edge]->getNext();
684 unsigned int edge1 = edge;
685 unsigned int edge2 =
mHalfEdge[edge]->getDual();
686 unsigned int edge3 =
mHalfEdge[edge]->getNext();
706 void DualEdgeTriangulation::draw( QPainter *p,
double xlowleft,
double ylowleft,
double xupright,
double yupright,
double width,
double height )
const
716 bool *control =
new bool[
mHalfEdge.count()];
717 bool *control2 =
new bool[
mHalfEdge.count()];
719 for (
unsigned int i = 0; i <=
mHalfEdge.count() - 1; i++ )
725 if ( ( ( xupright - xlowleft ) / width ) > ( ( yupright - ylowleft ) / height ) )
727 double lowerborder = -( height * ( xupright - xlowleft ) / width - yupright );
728 for (
unsigned int i = 0; i <
mHalfEdge.count() - 1; i++ )
742 if ( p1 == p2 && p2 == p3 &&
halfEdgeBBoxTest( i, xlowleft, lowerborder, xupright, yupright ) &&
halfEdgeBBoxTest(
mHalfEdge[i]->getNext(), xlowleft, lowerborder, xupright, yupright ) &&
halfEdgeBBoxTest(
mHalfEdge[
mHalfEdge[i]->getNext()]->getNext(), xlowleft, lowerborder, xupright, yupright ) )
748 QColor
c( 255, 0, 0 );
750 p->drawPolygon( pa );
755 control2[
mHalfEdge[i]->getNext()] =
true;
790 double rightborder = width * ( yupright - ylowleft ) / height + xlowleft;
791 for (
unsigned int i = 0; i <
mHalfEdge.count() - 1; i++ )
805 if ( p1 == p2 && p2 == p3 &&
halfEdgeBBoxTest( i, xlowleft, ylowleft, rightborder, yupright ) &&
halfEdgeBBoxTest(
mHalfEdge[i]->getNext(), xlowleft, ylowleft, rightborder, yupright ) &&
halfEdgeBBoxTest(
mHalfEdge[
mHalfEdge[i]->getNext()]->getNext(), xlowleft, ylowleft, rightborder, yupright ) )
811 QColor
c( 255, 0, 0 );
813 p->drawPolygon( pa );
818 control2[
mHalfEdge[i]->getNext()] =
true;
864 int nextnextedge = firstedge;
868 edge =
mHalfEdge[nextnextedge]->getDual();
871 theedge = nextnextedge;
875 nextnextedge =
mHalfEdge[nextedge]->getNext();
877 while ( nextnextedge != firstedge );
879 if ( theedge == -10 )
881 QgsDebugMsg( QStringLiteral(
"warning, error: the points are: %1 and %2" ).arg( p1 ).arg( p2 ) );
895 if ( firstedge == -1 )
900 int actedge = firstedge;
901 int edge, nextedge, nextnextedge;
908 nextnextedge =
mHalfEdge[nextedge]->getNext();
910 if (
mHalfEdge[nextnextedge]->getBreak() )
918 actedge = nextnextedge;
920 while ( nextnextedge != firstedge );
940 else if ( edge >= 0 )
959 else if ( edge == -20 )
964 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
982 else if ( edge == -25 )
987 int ptnr1 =
mHalfEdge[edge1]->getPoint();
988 int ptnr2 =
mHalfEdge[edge2]->getPoint();
989 int ptnr3 =
mHalfEdge[edge3]->getPoint();
1004 else if ( edge == -5 )
1009 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1029 QgsDebugMsg( QStringLiteral(
"problem: the edge is: %1" ).arg( edge ) );
1047 else if ( edge >= 0 )
1049 int ptnr1 =
mHalfEdge[edge]->getPoint();
1063 else if ( edge == -20 )
1068 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1083 else if ( edge == -25 )
1086 int edge2 =
mHalfEdge[edge1]->getNext();
1087 int edge3 =
mHalfEdge[edge2]->getNext();
1088 int ptnr1 =
mHalfEdge[edge1]->getPoint();
1089 int ptnr2 =
mHalfEdge[edge2]->getPoint();
1090 int ptnr3 =
mHalfEdge[edge3]->getPoint();
1091 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1106 else if ( edge == -5 )
1111 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1148 QList<int> crossedEdges;
1151 int pointingedge = 0;
1155 if ( pointingedge == -1 )
1161 int actedge =
mHalfEdge[pointingedge]->getDual();
1168 if ( control > 17000 )
1170 QgsDebugMsg( QStringLiteral(
"warning, endless loop" ) );
1219 if ( dista <= distb )
1225 else if ( distb <= dista )
1241 float frac = distpart / disttot;
1243 if ( frac == 0 || frac == 1 )
1255 else if ( frac == 1 )
1286 crossedEdges.append(
mHalfEdge[actedge]->getNext() );
1307 if ( dista <= distb )
1313 else if ( distb <= dista )
1329 float frac = distpart / disttot;
1330 if ( frac == 0 || frac == 1 )
1340 crossedEdges.append(
mHalfEdge[
mHalfEdge[crossedEdges.last()]->getDual()]->getNext() );
1354 if ( dista <= distb )
1360 else if ( distb <= dista )
1376 float frac = distpart / disttot;
1377 if ( frac == 0 || frac == 1 )
1397 QList<int>::const_iterator iter;
1398 for ( iter = crossedEdges.constBegin(); iter != crossedEdges.constEnd(); ++iter )
1400 mHalfEdge[( *( iter ) )]->setForced(
false );
1401 mHalfEdge[( *( iter ) )]->setBreak(
false );
1409 QList<int> freelist = crossedEdges;
1412 QList<int> leftPolygon;
1413 QList<int> rightPolygon;
1416 int firstedge = freelist.first();
1417 mHalfEdge[firstedge]->setForced(
true );
1419 leftPolygon.append( firstedge );
1420 int dualfirstedge =
mHalfEdge[freelist.first()]->getDual();
1421 mHalfEdge[dualfirstedge]->setForced(
true );
1423 rightPolygon.append( dualfirstedge );
1424 freelist.pop_front();
1428 QList<int>::const_iterator leftiter;
1429 leftiter = crossedEdges.constEnd();
1434 if ( newpoint != actpointl )
1437 actpointl = newpoint;
1439 leftPolygon.append( theedge );
1441 if ( leftiter == crossedEdges.constBegin() )
1447 leftPolygon.append(
mHalfEdge[crossedEdges.first()]->getNext() );
1450 QList<int>::const_iterator rightiter;
1452 for ( rightiter = crossedEdges.constBegin(); rightiter != crossedEdges.constEnd(); ++rightiter )
1455 if ( newpoint != actpointr )
1458 actpointr = newpoint;
1460 rightPolygon.append( theedge );
1466 rightPolygon.append(
mHalfEdge[
mHalfEdge[crossedEdges.last()]->getDual()]->getNext() );
1467 mHalfEdge[rightPolygon.last()]->setNext( dualfirstedge );
1470 int actedgel = leftPolygon[1];
1471 leftiter = leftPolygon.constBegin();
1473 for ( ; leftiter != leftPolygon.constEnd(); ++leftiter )
1475 mHalfEdge[actedgel]->setNext( ( *leftiter ) );
1476 actedgel = ( *leftiter );
1480 int actedger = rightPolygon[1];
1481 rightiter = rightPolygon.constBegin();
1483 for ( ; rightiter != rightPolygon.constEnd(); ++rightiter )
1485 mHalfEdge[actedger]->setNext( ( *rightiter ) );
1486 actedger = ( *( rightiter ) );
1491 mHalfEdge[leftPolygon.first()]->setNext( ( *( ++( leftiter = leftPolygon.constBegin() ) ) ) );
1492 mHalfEdge[leftPolygon.first()]->setPoint( p2 );
1493 mHalfEdge[leftPolygon.last()]->setNext( firstedge );
1494 mHalfEdge[rightPolygon.first()]->setNext( ( *( ++( rightiter = rightPolygon.constBegin() ) ) ) );
1495 mHalfEdge[rightPolygon.first()]->setPoint( p1 );
1496 mHalfEdge[rightPolygon.last()]->setNext( dualfirstedge );
1502 for ( iter = crossedEdges.constBegin(); iter != crossedEdges.constEnd(); ++iter )
1507 return leftPolygon.first();
1537 QgsDebugMsg( QStringLiteral(
"am in eliminateHorizontalTriangles" ) );
1538 double minangle = 0;
1542 bool swapped =
false;
1543 bool *control =
new bool[
mHalfEdge.count()];
1545 for (
int i = 0; i <=
mHalfEdge.count() - 1; i++ )
1551 for (
int i = 0; i <=
mHalfEdge.count() - 1; i++ )
1569 if ( p1 == -1 || p2 == -1 || p3 == -1 )
1577 double el1, el2, el3;
1582 if ( el1 == el2 && el2 == el3 )
1630 std::map<int, double> edge_angle;
1631 std::multimap<double, int> angle_edge;
1632 QSet<int> dontexamine;
1643 for (
int i = 0; i < nhalfedges - 1; i++ )
1646 int nextnext =
mHalfEdge[next]->getNext();
1668 for (
int i = 0; i <
mHalfEdge.count() - 1; i++ )
1674 if ( p1 == -1 || p2 == -1 || p3 == -1 )
1680 bool twoforcededges;
1685 if (
angle < mintol && !twoforcededges )
1687 edge_angle.insert( std::make_pair( i,
angle ) );
1688 angle_edge.insert( std::make_pair(
angle, i ) );
1693 for ( std::multimap<double, int>::const_iterator it = angle_edge.begin(); it != angle_edge.end(); ++it )
1695 QgsDebugMsg( QStringLiteral(
"angle: %1" ).arg( it->first ) );
1699 double minangle = 0;
1702 int minedgenextnext;
1706 while ( !edge_angle.empty() )
1708 minangle = angle_edge.begin()->first;
1709 QgsDebugMsg( QStringLiteral(
"minangle: %1" ).arg( minangle ) );
1710 minedge = angle_edge.begin()->second;
1711 minedgenext =
mHalfEdge[minedge]->getNext();
1712 minedgenextnext =
mHalfEdge[minedgenext]->getNext();
1717 QgsDebugMsg( QStringLiteral(
"warning, calculation of circumcenter failed" ) );
1719 dontexamine.insert( minedge );
1720 edge_angle.erase( minedge );
1721 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
1722 while ( minedgeiter->second != minedge )
1726 angle_edge.erase( minedgeiter );
1733 QgsDebugMsg( QStringLiteral(
"put circumcenter %1//%2 on dontexamine list because it is outside the convex hull" )
1735 dontexamine.insert( minedge );
1736 edge_angle.erase( minedge );
1737 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
1738 while ( minedgeiter->second != minedge )
1742 angle_edge.erase( minedgeiter );
1748 bool encroached =
false;
1750 #if 0 //slow version
1752 for (
int i = 0; i < numhalfedges; i++ )
1766 int actedge = pointingedge;
1769 double angle1, angle2, angle3;
1781 if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
1791 bool twoforcededges1, twoforcededges2, twoforcededges3;
1795 twoforcededges1 =
true;
1799 twoforcededges1 =
false;
1804 twoforcededges2 =
true;
1808 twoforcededges2 =
false;
1813 twoforcededges3 =
true;
1817 twoforcededges3 =
false;
1821 QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
1822 if ( ed1iter != dontexamine.end() )
1825 dontexamine.erase( ed1iter );
1830 std::map<int, double>::iterator tempit1;
1831 tempit1 = edge_angle.find( ed1 );
1832 if ( tempit1 != edge_angle.end() )
1835 double angle = tempit1->second;
1836 edge_angle.erase( ed1 );
1837 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound(
angle );
1838 while ( tempit2->second != ed1 )
1842 angle_edge.erase( tempit2 );
1846 if ( angle1 < mintol && !twoforcededges1 )
1848 edge_angle.insert( std::make_pair( ed1, angle1 ) );
1849 angle_edge.insert( std::make_pair( angle1, ed1 ) );
1853 QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
1854 if ( ed2iter != dontexamine.end() )
1857 dontexamine.erase( ed2iter );
1862 std::map<int, double>::iterator tempit1;
1863 tempit1 = edge_angle.find( ed2 );
1864 if ( tempit1 != edge_angle.end() )
1867 double angle = tempit1->second;
1868 edge_angle.erase( ed2 );
1869 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound(
angle );
1870 while ( tempit2->second != ed2 )
1874 angle_edge.erase( tempit2 );
1878 if ( angle2 < mintol && !twoforcededges2 )
1880 edge_angle.insert( std::make_pair( ed2, angle2 ) );
1881 angle_edge.insert( std::make_pair( angle2, ed2 ) );
1885 QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
1886 if ( ed3iter != dontexamine.end() )
1889 dontexamine.erase( ed3iter );
1894 std::map<int, double>::iterator tempit1;
1895 tempit1 = edge_angle.find( ed3 );
1896 if ( tempit1 != edge_angle.end() )
1899 double angle = tempit1->second;
1900 edge_angle.erase( ed3 );
1901 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound(
angle );
1902 while ( tempit2->second != ed3 )
1906 angle_edge.erase( tempit2 );
1910 if ( angle3 < mintol && !twoforcededges3 )
1912 edge_angle.insert( std::make_pair( ed3, angle3 ) );
1913 angle_edge.insert( std::make_pair( angle3, ed3 ) );
1918 while ( actedge != pointingedge );
1922 #endif //end slow version
1926 QSet<int> influenceedges;
1928 if ( baseedge == -5 )
1931 edge_angle.erase( minedge );
1932 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
1933 while ( minedgeiter->second != minedge )
1937 angle_edge.erase( minedgeiter );
1940 else if ( baseedge == -25 )
1943 edge_angle.erase( minedge );
1944 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
1945 while ( minedgeiter->second != minedge )
1949 angle_edge.erase( minedgeiter );
1952 else if ( baseedge == -20 )
1961 for ( QSet<int>::iterator it = influenceedges.begin(); it != influenceedges.end(); ++it )
1973 int actedge = pointingedge;
1976 double angle1, angle2, angle3;
1988 if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
1998 bool twoforcededges1, twoforcededges2, twoforcededges3;
2010 QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
2011 if ( ed1iter != dontexamine.end() )
2014 dontexamine.erase( ed1iter );
2019 std::map<int, double>::iterator tempit1;
2020 tempit1 = edge_angle.find( ed1 );
2021 if ( tempit1 != edge_angle.end() )
2024 double angle = tempit1->second;
2025 edge_angle.erase( ed1 );
2026 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound(
angle );
2027 while ( tempit2->second != ed1 )
2031 angle_edge.erase( tempit2 );
2035 if ( angle1 < mintol && !twoforcededges1 )
2037 edge_angle.insert( std::make_pair( ed1, angle1 ) );
2038 angle_edge.insert( std::make_pair( angle1, ed1 ) );
2042 QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
2043 if ( ed2iter != dontexamine.end() )
2046 dontexamine.erase( ed2iter );
2051 std::map<int, double>::iterator tempit1;
2052 tempit1 = edge_angle.find( ed2 );
2053 if ( tempit1 != edge_angle.end() )
2056 double angle = tempit1->second;
2057 edge_angle.erase( ed2 );
2058 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound(
angle );
2059 while ( tempit2->second != ed2 )
2063 angle_edge.erase( tempit2 );
2067 if ( angle2 < mintol && !twoforcededges2 )
2069 edge_angle.insert( std::make_pair( ed2, angle2 ) );
2070 angle_edge.insert( std::make_pair( angle2, ed2 ) );
2074 QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
2075 if ( ed3iter != dontexamine.end() )
2078 dontexamine.erase( ed3iter );
2083 std::map<int, double>::iterator tempit1;
2084 tempit1 = edge_angle.find( ed3 );
2085 if ( tempit1 != edge_angle.end() )
2088 double angle = tempit1->second;
2089 edge_angle.erase( ed3 );
2090 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound(
angle );
2091 while ( tempit2->second != ed3 )
2095 angle_edge.erase( tempit2 );
2099 if ( angle3 < mintol && !twoforcededges3 )
2101 edge_angle.insert( std::make_pair( ed3, angle3 ) );
2102 angle_edge.insert( std::make_pair( angle3, ed3 ) );
2107 while ( actedge != pointingedge );
2125 if ( pointno == -100 )
2127 QgsDebugMsg( QStringLiteral(
"put circumcenter %1//%2 on dontexamine list because of numerical instabilities" )
2132 QgsDebugMsg( QStringLiteral(
"put circumcenter %1//%2 on dontexamine list because it is already inserted" )
2145 QgsDebugMsg( QStringLiteral(
"point is not present in the triangulation" ) );
2149 dontexamine.insert( minedge );
2150 edge_angle.erase( minedge );
2151 std::multimap<double, int>::iterator minedgeiter = angle_edge.lower_bound( minangle );
2152 while ( minedgeiter->second != minedge )
2156 angle_edge.erase( minedgeiter );
2161 QgsDebugMsg( QStringLiteral(
"circumcenter added" ) );
2167 int actedge = pointingedge;
2170 double angle1, angle2, angle3;
2182 if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
2192 bool twoforcededges1, twoforcededges2, twoforcededges3;
2202 QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
2203 if ( ed1iter != dontexamine.end() )
2206 dontexamine.erase( ed1iter );
2211 std::map<int, double>::iterator tempit1;
2212 tempit1 = edge_angle.find( ed1 );
2213 if ( tempit1 != edge_angle.end() )
2216 double angle = tempit1->second;
2217 edge_angle.erase( ed1 );
2218 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound(
angle );
2219 while ( tempit2->second != ed1 )
2223 angle_edge.erase( tempit2 );
2227 if ( angle1 < mintol && !twoforcededges1 )
2229 edge_angle.insert( std::make_pair( ed1, angle1 ) );
2230 angle_edge.insert( std::make_pair( angle1, ed1 ) );
2235 QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
2236 if ( ed2iter != dontexamine.end() )
2239 dontexamine.erase( ed2iter );
2244 std::map<int, double>::iterator tempit1;
2245 tempit1 = edge_angle.find( ed2 );
2246 if ( tempit1 != edge_angle.end() )
2249 double angle = tempit1->second;
2250 edge_angle.erase( ed2 );
2251 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound(
angle );
2252 while ( tempit2->second != ed2 )
2256 angle_edge.erase( tempit2 );
2260 if ( angle2 < mintol && !twoforcededges2 )
2262 edge_angle.insert( std::make_pair( ed2, angle2 ) );
2263 angle_edge.insert( std::make_pair( angle2, ed2 ) );
2267 QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
2268 if ( ed3iter != dontexamine.end() )
2271 dontexamine.erase( ed3iter );
2276 std::map<int, double>::iterator tempit1;
2277 tempit1 = edge_angle.find( ed3 );
2278 if ( tempit1 != edge_angle.end() )
2281 double angle = tempit1->second;
2282 edge_angle.erase( ed3 );
2283 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound(
angle );
2284 while ( tempit2->second != ed3 )
2288 angle_edge.erase( tempit2 );
2292 if ( angle3 < mintol && !twoforcededges3 )
2294 edge_angle.insert( std::make_pair( ed3, angle3 ) );
2295 angle_edge.insert( std::make_pair( angle3, ed3 ) );
2300 while ( actedge != pointingedge );
2306 for ( QSet<int>::iterator it = dontexamine.begin(); it != dontexamine.end(); ++it )
2308 QgsDebugMsg( QStringLiteral(
"edge nr. %1 is in dontexamine" ).arg( *it ) );
2355 if ( poly->count() == 3 )
2361 QList<int>::const_iterator iterator = ++( poly->constBegin() );
2363 int distedge = ( *iterator );
2364 int nextdistedge =
mHalfEdge[( *iterator )]->getNext();
2367 while ( iterator != --( poly->constEnd() ) )
2371 distedge = ( *iterator );
2372 nextdistedge =
mHalfEdge[( *iterator )]->getNext();
2378 if ( nextdistedge == ( *( --poly->end() ) ) )
2380 int inserta = free->first();
2381 int insertb =
mHalfEdge[inserta]->getDual();
2384 mHalfEdge[inserta]->setNext( ( poly->at( 1 ) ) );
2386 mHalfEdge[insertb]->setNext( nextdistedge );
2388 mHalfEdge[distedge]->setNext( inserta );
2389 mHalfEdge[mainedge]->setNext( insertb );
2392 for ( iterator = ( ++( poly->constBegin() ) ); ( *iterator ) != nextdistedge; ++iterator )
2394 polya.append( ( *iterator ) );
2396 polya.prepend( inserta );
2400 for ( iterator = polya.begin(); iterator != polya.end(); ++iterator )
2409 else if ( distedge == ( *( ++poly->begin() ) ) )
2411 int inserta = free->first();
2412 int insertb =
mHalfEdge[inserta]->getDual();
2415 mHalfEdge[inserta]->setNext( ( poly->at( 2 ) ) );
2417 mHalfEdge[insertb]->setNext( mainedge );
2419 mHalfEdge[distedge]->setNext( insertb );
2420 mHalfEdge[( *( --poly->end() ) )]->setNext( inserta );
2423 iterator = poly->constBegin();
2425 while ( iterator != poly->constEnd() )
2427 polya.append( ( *iterator ) );
2430 polya.prepend( inserta );
2437 int inserta = free->first();
2438 int insertb =
mHalfEdge[inserta]->getDual();
2441 int insertc = free->first();
2442 int insertd =
mHalfEdge[insertc]->getDual();
2445 mHalfEdge[inserta]->setNext( ( poly->at( 1 ) ) );
2449 mHalfEdge[insertc]->setNext( nextdistedge );
2451 mHalfEdge[insertd]->setNext( mainedge );
2454 mHalfEdge[distedge]->setNext( inserta );
2455 mHalfEdge[mainedge]->setNext( insertb );
2456 mHalfEdge[( *( --poly->end() ) )]->setNext( insertc );
2462 for ( iterator = ++( poly->constBegin() ); ( *iterator ) != nextdistedge; ++iterator )
2464 polya.append( ( *iterator ) );
2466 polya.prepend( inserta );
2469 while ( iterator != poly->constEnd() )
2471 polyb.append( ( *iterator ) );
2474 polyb.prepend( insertc );
2483 QgsDebugMsg( QStringLiteral(
"warning, null pointer" ) );
2501 QgsDebugMsg( QStringLiteral(
"warning, instability detected: Point coordinates: %1//%2" ).arg( x ).arg( y ) );
2535 actedge =
mHalfEdge[actedge]->getDual();
2541 actedge =
mHalfEdge[actedge]->getNext();
2558 if ( numinstabs > 0 )
2560 QgsDebugMsg( QStringLiteral(
"numerical instabilities" ) );
2573 bool DualEdgeTriangulation::readFromTAFF( QString filename )
2575 QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
2577 QFile file( filename );
2578 file.open( IO_Raw | IO_ReadOnly );
2579 QBuffer buffer( file.readAll() );
2582 QTextStream textstream( &buffer );
2583 buffer.open( IO_ReadOnly );
2586 int numberofhalfedges;
2590 while ( buff.mid( 0, 4 ) !=
"TRIA" )
2592 buff = textstream.readLine();
2594 while ( buff.mid( 0, 4 ) !=
"NEDG" )
2596 buff = textstream.readLine();
2598 numberofhalfedges = buff.section(
' ', 1, 1 ).toInt();
2602 while ( buff.mid( 0, 4 ) !=
"DATA" )
2607 int nr1, nr2, dual1, dual2, point1, point2, next1, next2, fo1, fo2, b1, b2;
2608 bool forced1, forced2, break1, break2;
2612 QProgressBar *edgebar =
new QProgressBar();
2613 edgebar->setCaption( tr(
"Reading edges…" ) );
2614 edgebar->setTotalSteps( numberofhalfedges / 2 );
2615 edgebar->setMinimumWidth( 400 );
2616 edgebar->move( 500, 500 );
2619 for (
int i = 0; i < numberofhalfedges / 2; i++ )
2621 if ( i % 1000 == 0 )
2623 edgebar->setProgress( i );
2627 textstream >> point1;
2628 textstream >> next1;
2652 textstream >> point2;
2653 textstream >> next2;
2696 edgebar->setProgress( numberofhalfedges / 2 );
2700 for (
int i = 0; i < numberofhalfedges; i++ )
2707 if ( a != -1 && b != -1 &&
c != -1 && d != -1 )
2715 while ( buff.mid( 0, 4 ) !=
"POIN" )
2717 buff = textstream.readLine();
2720 while ( buff.mid( 0, 4 ) !=
"NPTS" )
2722 buff = textstream.readLine();
2725 numberofpoints = buff.section(
' ', 1, 1 ).toInt();
2728 while ( buff.mid( 0, 4 ) !=
"DATA" )
2733 QProgressBar *pointbar =
new QProgressBar();
2734 pointbar->setCaption( tr(
"Reading points…" ) );
2735 pointbar->setTotalSteps( numberofpoints );
2736 pointbar->setMinimumWidth( 400 );
2737 pointbar->move( 500, 500 );
2742 for (
int i = 0; i < numberofpoints; i++ )
2744 if ( i % 1000 == 0 )
2746 pointbar->setProgress( i );
2772 else if ( x >
xMax )
2781 else if ( y >
yMax )
2788 pointbar->setProgress( numberofpoints );
2790 QApplication::restoreOverrideCursor();
2794 bool DualEdgeTriangulation::saveToTAFF( QString filename )
const
2796 QFile outputfile( filename );
2797 if ( !outputfile.open( IO_WriteOnly ) )
2799 QMessageBox::warning( 0, tr(
"Warning" ), tr(
"File could not be written." ), QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton );
2803 QTextStream outstream( &outputfile );
2804 outstream.precision( 9 );
2807 outstream <<
"TRIA" << std::endl << std::flush;
2808 outstream <<
"NEDG " <<
mHalfEdge.count() << std::endl << std::flush;
2809 outstream <<
"PANO 1" << std::endl << std::flush;
2810 outstream <<
"DATA ";
2812 bool *cont =
new bool[
mHalfEdge.count()];
2813 for (
unsigned int i = 0; i <=
mHalfEdge.count() - 1; i++ )
2818 for (
unsigned int i = 0; i <
mHalfEdge.count(); i++ )
2827 outstream << dual <<
" " <<
mHalfEdge[dual]->getPoint() <<
" " <<
mHalfEdge[dual]->getNext() <<
" " <<
mHalfEdge[dual]->getForced() <<
" " <<
mHalfEdge[dual]->getBreak() <<
" ";
2831 outstream << std::endl << std::flush;
2832 outstream << std::endl << std::flush;
2837 outstream <<
"POIN" << std::endl << std::flush;
2839 outstream <<
"PATT 3" << std::endl << std::flush;
2840 outstream <<
"DATA ";
2845 outstream << p->getX() <<
" " << p->getY() <<
" " << p->getZ() <<
" ";
2847 outstream << std::endl << std::flush;
2848 outstream << std::endl << std::flush;
2869 if ( point1 && point2 && point3 )
2872 double dist1, dist2, dist3;
2876 if ( dist1 <= dist2 && dist1 <= dist3 )
2884 else if ( dist2 <= dist1 && dist2 <= dist3 )
2892 else if ( dist3 <= dist1 && dist3 <= dist2 )
2921 const int edge2 =
mHalfEdge[edge1]->getNext();
2922 const int edge3 =
mHalfEdge[edge2]->getNext();
2926 if ( point1 && point2 && point3 )
2932 if ( dist1 <= dist2 && dist1 <= dist3 )
2939 else if ( dist2 <= dist1 && dist2 <= dist3 )
2953 QList<int> *list =
new QList<int>();
2962 QgsDebugMsg( QStringLiteral(
"warning: null pointer" ) );
2968 QgsDebugMsg( QStringLiteral(
"Edge number negative" ) );
2980 bool *alreadyVisitedEdges =
new bool[
mHalfEdge.size()];
2981 if ( !alreadyVisitedEdges )
2987 for (
int i = 0; i <
mHalfEdge.size(); ++i )
2989 alreadyVisitedEdges[i] =
false;
2992 for (
int i = 0; i <
mHalfEdge.size(); ++i )
3012 QString attributeString;
3017 attributeString = QStringLiteral(
"break line" );
3021 attributeString = QStringLiteral(
"structure line" );
3028 alreadyVisitedEdges[i] =
true;
3031 delete [] alreadyVisitedEdges;
3048 if ( angle2 < minangle )
3053 if ( angle3 < minangle )
3058 if ( angle4 < minangle )
3063 if ( angle5 < minangle )
3068 if ( angle6 < minangle )
3079 if ( position < 0 || position > 1 )
3081 QgsDebugMsg( QStringLiteral(
"warning, position is not between 0 and 1" ) );
3090 p->
setZ( zvaluepoint.
z() );
3097 QgsDebugMsg( QStringLiteral(
"inserting point nr. %1, %2//%3//%4" ).arg(
mPointVector.count() ).arg( p->
x() ).arg( p->
y() ).arg( p->
z() ) );
3101 int dualedge =
mHalfEdge[edge]->getDual();
3138 if ( set.find( edge ) == set.end() )