30   double x2 = point2.
x() - point1.
x();
 
   31   double y2 = point2.
y() - point1.
y();
 
   32   double x3 = point3.
x() - point1.
x();
 
   33   double y3 = point3.
y() - point1.
y();
 
   35   double denom = x2 * y3 - y2 * x3;
 
   41   frac = ( x2 * ( x2 - x3 ) + y2 * ( y2 - y3 ) ) / denom;
 
   42   double cx = ( x3 + frac * y3 ) / 2;
 
   43   double cy = ( y3 - frac * x3 ) / 2;
 
   44   double squaredRadius = ( cx * cx + cy * cy );
 
   45   QgsPoint center( cx + point1.
x(), cy + point1.
y() );
 
   53   if ( !mPointVector.isEmpty() )
 
   55     for ( 
int i = 0; i < mPointVector.count(); i++ )
 
   57       delete mPointVector[i];
 
   62   if ( !mHalfEdge.isEmpty() )
 
   64     for ( 
int i = 0; i < mHalfEdge.count(); i++ )
 
   73   QgsDebugMsg( QStringLiteral( 
"performing consistency test" ) );
 
   75   for ( 
int i = 0; i < mHalfEdge.count(); i++ )
 
   77     int a = mHalfEdge[mHalfEdge[i]->getDual()]->getDual();
 
   78     int b = mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getNext();
 
   81       QgsDebugMsg( QStringLiteral( 
"warning, first test failed" ) );
 
   85       QgsDebugMsg( QStringLiteral( 
"warning, second test failed" ) );
 
   88   QgsDebugMsg( QStringLiteral( 
"consistency test finished" ) );
 
   94   int currentpoint = -10;
 
  101     if ( actpoint != -100 )
 
  107   if ( actpoint == -100 )
 
  112   for ( ; i < points.size(); ++i )
 
  114     currentpoint = 
addPoint( points.at( i ) );
 
  115     if ( currentpoint != -100 && actpoint != -100 && currentpoint != actpoint )
 
  117       insertForcedSegment( actpoint, currentpoint, lineType );
 
  119     actpoint = currentpoint;
 
  126   if ( mPointVector.isEmpty() )
 
  135     mXMin = std::min( p.
x(), mXMin );
 
  136     mXMax = std::max( p.
x(), mXMax );
 
  137     mYMin = std::min( p.
y(), mYMin );
 
  138     mYMax = std::max( p.
y(), mYMax );
 
  142   mPointVector.append( 
new QgsPoint( p ) );
 
  145   if ( mDimension == -1 )
 
  147     unsigned int zedge  = insertEdge( -10, -10, -1, 
false, 
false ); 
 
  148     unsigned int fedge  = insertEdge( 
static_cast<int>( zedge ), 
static_cast<int>( zedge ), 0, 
false, 
false ); 
 
  149     ( mHalfEdge.at( zedge ) )->setDual( 
static_cast<int>( fedge ) );
 
  150     ( mHalfEdge.at( zedge ) )->setNext( 
static_cast<int>( fedge ) );
 
  153   else if ( mDimension == 0 )
 
  156     if ( p.
x() == mPointVector[0]->x() && p.
y() == mPointVector[0]->y() )
 
  163     unsigned int edgeFromPoint0ToPoint1  = insertEdge( -10, -10, 1, 
false, 
false );
 
  164     unsigned int edgeFromPoint1ToPoint0  = insertEdge( edgeFromPoint0ToPoint1, -10, 0, 
false, 
false ); 
 
  165     unsigned int edgeFromVirtualToPoint1Side1  = insertEdge( -10, -10, 1, 
false, 
false ); 
 
  166     unsigned int edgeFromPoint1ToVirtualSide1  = insertEdge( edgeFromVirtualToPoint1Side1, 1, -1, 
false, 
false ); 
 
  167     unsigned int edgeFromVirtualToPoint1Side2  = insertEdge( -10, edgeFromPoint1ToPoint0, 1, 
false, 
false );
 
  168     unsigned int edgeFromPoint1ToVirtualSide2  = insertEdge( edgeFromVirtualToPoint1Side2, edgeFromVirtualToPoint1Side1, -1, 
false, 
false );
 
  169     unsigned int edgeFromVirtualToPoint0Side2  = insertEdge( -10, -10, 0, 
false, 
false );
 
  170     unsigned int edgeFromPoint0ToVirtualSide2  = insertEdge( edgeFromVirtualToPoint0Side2, edgeFromVirtualToPoint1Side2, -1, 
false, 
false );
 
  171     mHalfEdge.at( edgeFromPoint1ToPoint0 )->setNext( edgeFromPoint0ToVirtualSide2 );
 
  172     mHalfEdge.at( edgeFromPoint0ToPoint1 )->setDual( edgeFromPoint1ToPoint0 );
 
  173     mHalfEdge.at( edgeFromPoint0ToPoint1 )->setNext( edgeFromPoint1ToVirtualSide1 );
 
  174     mHalfEdge.at( edgeFromVirtualToPoint1Side1 )->setDual( edgeFromPoint1ToVirtualSide1 );
 
  175     mHalfEdge.at( edgeFromVirtualToPoint1Side1 )->setNext( edgeFromPoint1ToVirtualSide2 );
 
  176     mHalfEdge.at( 0 )->setNext( 
static_cast<int>( edgeFromVirtualToPoint0Side2 ) );
 
  177     mHalfEdge.at( 1 )->setNext( 
static_cast<int>( edgeFromPoint0ToPoint1 ) );
 
  178     mHalfEdge.at( edgeFromVirtualToPoint1Side2 )->setDual( edgeFromPoint1ToVirtualSide2 );
 
  179     mHalfEdge.at( edgeFromVirtualToPoint0Side2 )->setDual( edgeFromPoint0ToVirtualSide2 );
 
  180     mHalfEdge.at( edgeFromVirtualToPoint0Side2 )->setNext( 0 );
 
  182     mEdgeOutside = edgeFromPoint0ToPoint1;
 
  185   else if ( mDimension == 1 )
 
  187     if ( mEdgeOutside < 0 || mHalfEdge[mEdgeOutside]->getPoint() < 0 || mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint() < 0 )
 
  188       mEdgeOutside = firstEdgeOutSide();
 
  189     if ( mEdgeOutside < 0 || mHalfEdge[mEdgeOutside]->getPoint() < 0 || mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint() < 0 )
 
  192     double leftOfNumber = 
MathUtils::leftOf( p,  mPointVector[mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint()], mPointVector[mHalfEdge[mEdgeOutside]->getPoint()] );
 
  198       int closestEdge = -1;
 
  199       double distance = std::numeric_limits<double>::max();
 
  200       int firstEdge = mEdgeOutside;
 
  203         int point1 = mHalfEdge[mEdgeOutside]->getPoint();
 
  204         int point2 = mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint();
 
  205         double distance1 = p.
distance( *mPointVector[point1] );
 
  211         double distance2 = p.
distance( *mPointVector[point2] );
 
  218         double edgeLength = mPointVector[point1]->distance( *mPointVector[point2] );
 
  220         if ( distance1 < edgeLength && distance2 < edgeLength )
 
  223           int newPoint = mPointVector.count() - 1;
 
  226           int edgeFromNewPointToPoint1 = mEdgeOutside;
 
  227           int edgeFromNewPointToPoint2 = mHalfEdge[mEdgeOutside]->getDual();
 
  229           int edgeFromPoint1ToVirtualSide2 = mHalfEdge[edgeFromNewPointToPoint1]->getNext();
 
  230           int edgeFromVirtualToPoint1Side1 = mHalfEdge[mHalfEdge[edgeFromNewPointToPoint2]->getNext()]->getNext();
 
  231           int edgeFromPoint2ToVirtualSide1 = mHalfEdge[edgeFromNewPointToPoint2]->getNext();
 
  232           int edgeFromVirtualToPoint2Side2 = mHalfEdge[mHalfEdge[edgeFromNewPointToPoint1]->getNext()]->getNext();
 
  234           int edgeFromVirtualToNewPointSide1 = insertEdge( -10, edgeFromNewPointToPoint2, newPoint, 
false, 
false );
 
  235           int edgeFromNewPointToVirtualSide1 = insertEdge( edgeFromVirtualToNewPointSide1, edgeFromVirtualToPoint1Side1, -1, 
false, 
false );
 
  236           int edgeFromVirtualToNewPointSide2 = insertEdge( -10, edgeFromNewPointToPoint1, newPoint, 
false, 
false );
 
  237           int edgeFromNewPointToVirtualSide2 = insertEdge( edgeFromVirtualToNewPointSide2, edgeFromVirtualToPoint2Side2, -1, 
false, 
false );
 
  238           int edgeFromPoint1ToNewPoint = insertEdge( edgeFromNewPointToPoint1, edgeFromNewPointToVirtualSide1, newPoint, 
false, 
false );
 
  239           int edgeFromPoint2ToNewPoint = insertEdge( edgeFromNewPointToPoint2, edgeFromNewPointToVirtualSide2, newPoint, 
false, 
false );
 
  240           mHalfEdge.at( edgeFromVirtualToNewPointSide1 )->setDual( edgeFromNewPointToVirtualSide1 );
 
  241           mHalfEdge.at( edgeFromVirtualToNewPointSide2 )->setDual( edgeFromNewPointToVirtualSide2 );
 
  243           mHalfEdge.at( edgeFromPoint1ToVirtualSide2 )->setNext( edgeFromVirtualToNewPointSide2 );
 
  244           mHalfEdge.at( edgeFromVirtualToPoint1Side1 )->setNext( edgeFromPoint1ToNewPoint );
 
  245           mHalfEdge.at( edgeFromPoint2ToVirtualSide1 )->setNext( edgeFromVirtualToNewPointSide1 );
 
  246           mHalfEdge.at( edgeFromVirtualToPoint2Side2 )->setNext( edgeFromPoint2ToNewPoint );
 
  247           mHalfEdge.at( edgeFromNewPointToPoint1 )->setDual( edgeFromPoint1ToNewPoint );
 
  248           mHalfEdge.at( edgeFromNewPointToPoint2 )->setDual( edgeFromPoint2ToNewPoint );
 
  253           if ( distance1 < distance )
 
  255             closestEdge = mEdgeOutside;
 
  256             distance = distance1;
 
  258           else if ( distance2 < distance )
 
  260             closestEdge = mHalfEdge[mEdgeOutside]->getDual();
 
  261             distance = distance2;
 
  264         mEdgeOutside = mHalfEdge[mHalfEdge[mHalfEdge[mEdgeOutside]->getNext()]->getDual()]->getNext();
 
  266       while ( mEdgeOutside != firstEdge && mHalfEdge[mEdgeOutside]->getPoint() != -1 && mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint() != -1 );
 
  268       if ( closestEdge < 0 )
 
  272       int extremPoint = mHalfEdge[closestEdge]->getPoint();
 
  273       int newPoint = mPointVector.count() - 1;
 
  275       int edgeFromExtremeToOpposite = mHalfEdge[closestEdge]->getDual();
 
  277       int edgeFromVirtualToExtremeSide1 = mHalfEdge[mHalfEdge[closestEdge]->getNext()]->getDual();
 
  278       int edgeFromVirtualToExtremeSide2 = mHalfEdge[mHalfEdge[mHalfEdge[closestEdge]->getDual()]->getNext()]->getNext();
 
  279       int edgeFromExtremeToVirtualSide2 = mHalfEdge[edgeFromVirtualToExtremeSide2]->getDual();
 
  281       int edgeFromExtremeToNewPoint = insertEdge( -10, -10, newPoint, 
false, 
false );
 
  282       int edgeFromNewPointToExtrem = insertEdge( edgeFromExtremeToNewPoint, edgeFromExtremeToVirtualSide2, extremPoint, 
false, 
false );
 
  283       int edgeFromNewPointToVirtualSide1 = insertEdge( -10, edgeFromVirtualToExtremeSide1, -1, 
false, 
false );
 
  284       int edgeFromVirtualToNewPointSide1 = insertEdge( edgeFromNewPointToVirtualSide1, -10, newPoint, 
false, 
false );
 
  285       int edgeFromNewPointToVirtualSide2 = insertEdge( -10, edgeFromVirtualToNewPointSide1, -1, 
false, 
false );
 
  286       int edgeFromVirtualToNewPointSide2 = insertEdge( edgeFromNewPointToVirtualSide2, edgeFromNewPointToExtrem, newPoint, 
false, 
false );
 
  287       mHalfEdge.at( edgeFromExtremeToNewPoint )->setDual( edgeFromNewPointToExtrem );
 
  288       mHalfEdge.at( edgeFromExtremeToNewPoint )->setNext( edgeFromNewPointToVirtualSide1 );
 
  289       mHalfEdge.at( edgeFromNewPointToVirtualSide1 )->setDual( edgeFromVirtualToNewPointSide1 );
 
  290       mHalfEdge.at( edgeFromNewPointToVirtualSide2 )->setDual( edgeFromVirtualToNewPointSide2 );
 
  291       mHalfEdge.at( edgeFromVirtualToNewPointSide1 )->setNext( edgeFromNewPointToVirtualSide2 );
 
  293       mHalfEdge.at( edgeFromVirtualToExtremeSide1 )->setNext( edgeFromExtremeToNewPoint );
 
  294       mHalfEdge.at( edgeFromVirtualToExtremeSide2 )->setNext( edgeFromExtremeToOpposite );
 
  295       mHalfEdge.at( edgeFromExtremeToVirtualSide2 )->setNext( edgeFromVirtualToNewPointSide2 );
 
  302       mEdgeOutside = mHalfEdge[mEdgeOutside]->getDual();
 
  305     int newPoint = mPointVector.count() - 1;
 
  308     int cwEdge = mEdgeOutside;
 
  309     while ( mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext()]->getPoint() != -1 )
 
  311       mHalfEdge[mHalfEdge[ cwEdge ]->getNext()]->setPoint( newPoint );
 
  312       cwEdge = mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext();
 
  315     int edgeFromLastCwPointToVirtualPoint = mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext();
 
  316     int edgeFromLastCwPointToNewPointPoint = mHalfEdge[ cwEdge ]->getNext();
 
  317     int edgeFromNewPointPointToLastCwPoint = mHalfEdge[ edgeFromLastCwPointToNewPointPoint ]->getDual();
 
  319     int edgeFromNewPointtoVirtualPoint = insertEdge( -10, -10, -1, 
false, 
false );
 
  320     int edgeFromVirtualPointToNewPoint = insertEdge( edgeFromNewPointtoVirtualPoint, edgeFromNewPointPointToLastCwPoint, newPoint, 
false, 
false );
 
  321     mHalfEdge.at( edgeFromLastCwPointToNewPointPoint )->setPoint( newPoint );
 
  322     mHalfEdge.at( edgeFromNewPointtoVirtualPoint )->setDual( edgeFromVirtualPointToNewPoint );
 
  323     mHalfEdge.at( edgeFromLastCwPointToVirtualPoint )->setNext( edgeFromVirtualPointToNewPoint );
 
  326     int ccwEdge = mEdgeOutside;
 
  327     while ( mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getNext()]->getDual()]->getNext()]->getPoint() != -1 )
 
  329       mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ ccwEdge ]->getNext()]->getNext()]->getDual()]->setPoint( newPoint );
 
  330       ccwEdge = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getNext()]->getDual()]->getNext()]->getDual();
 
  333     int edgeToLastCcwPoint = mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getNext()]->getDual();
 
  334     int edgeFromLastCcwPointToNewPoint = mHalfEdge[edgeToLastCcwPoint]->getNext();
 
  335     mHalfEdge.at( edgeFromNewPointtoVirtualPoint )->setNext( edgeToLastCcwPoint );
 
  336     mHalfEdge.at( edgeFromLastCcwPointToNewPoint )->setNext( edgeFromNewPointtoVirtualPoint );
 
  337     mHalfEdge.at( edgeFromLastCcwPointToNewPoint )->setPoint( newPoint );
 
  341     int number = baseEdgeOfTriangle( p );
 
  346       unsigned int cwEdge = mEdgeOutside;
 
  347       unsigned int ccwEdge = mEdgeOutside;
 
  350       mHalfEdge[mHalfEdge[mEdgeOutside]->getNext()]->setPoint( mPointVector.count() - 1 );
 
  353       while ( 
MathUtils::leftOf( *mPointVector[ mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext()]->getPoint()],
 
  354                                  &p, mPointVector[ mHalfEdge[cwEdge]->getPoint()] ) < ( -
leftOfTresh ) )
 
  357         mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext()]->getNext()]->setPoint( mPointVector.count() - 1 );
 
  359         cwEdge = ( 
unsigned int )mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext();
 
  363       unsigned int edge1 = insertEdge( mHalfEdge[cwEdge]->getNext(), -10, mHalfEdge[cwEdge]->getPoint(), 
false, 
false );
 
  364       unsigned int edge2 = insertEdge( mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual(), -10, -1, 
false, 
false );
 
  365       unsigned int edge3 = insertEdge( -10, edge1, mPointVector.count() - 1, 
false, 
false );
 
  368       mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->setDual( edge2 );
 
  369       mHalfEdge[mHalfEdge[cwEdge]->getNext()]->setDual( edge1 );
 
  370       mHalfEdge[edge1]->setNext( edge2 );
 
  371       mHalfEdge[edge2]->setNext( edge3 );
 
  374       while ( 
MathUtils::leftOf( *mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getPoint()], mPointVector[mPointVector.count() - 1], mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->getNext()]->getPoint()] ) < ( -
leftOfTresh ) )
 
  377         mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->setPoint( mPointVector.count() - 1 );
 
  379         ccwEdge = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->getNext()]->getNext();
 
  383       unsigned int edge4 = insertEdge( mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext(), -10, mPointVector.count() - 1, 
false, 
false );
 
  384       unsigned int edge5 = insertEdge( edge3, -10, -1, 
false, 
false );
 
  385       unsigned int edge6 = insertEdge( mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual(), edge4, mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getPoint(), 
false, 
false );
 
  390       mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->setDual( edge6 );
 
  391       mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->setDual( edge4 );
 
  392       mHalfEdge[edge4]->setNext( edge5 );
 
  393       mHalfEdge[edge5]->setNext( edge6 );
 
  394       mHalfEdge[edge3]->setDual( edge5 );
 
  397       unsigned int index = ccwEdge;
 
  402         index = mHalfEdge[mHalfEdge[mHalfEdge[index]->getNext()]->getDual()]->getNext();
 
  403         checkSwapRecursively( toswap, 0 );
 
  404         if ( toswap == cwEdge )
 
  410     else if ( number >= 0 ) 
 
  412       int nextnumber = mHalfEdge[number]->getNext();
 
  413       int nextnextnumber = mHalfEdge[mHalfEdge[number]->getNext()]->getNext();
 
  416       unsigned int edge1 = insertEdge( -10, nextnumber, mHalfEdge[number]->getPoint(), 
false, 
false );
 
  417       unsigned int edge2 = insertEdge( 
static_cast<int>( edge1 ), -10, mPointVector.count() - 1, 
false, 
false );
 
  418       unsigned int edge3 = insertEdge( -10, nextnextnumber, mHalfEdge[nextnumber]->getPoint(), 
false, 
false );
 
  419       unsigned int edge4 = insertEdge( 
static_cast<int>( edge3 ), 
static_cast<int>( edge1 ), mPointVector.count() - 1, 
false, 
false );
 
  420       unsigned int edge5 = insertEdge( -10, number, mHalfEdge[nextnextnumber]->getPoint(), 
false, 
false );
 
  421       unsigned int edge6 = insertEdge( 
static_cast<int>( edge5 ), 
static_cast<int>( edge3 ), mPointVector.count() - 1, 
false, 
false );
 
  424       mHalfEdge.at( edge1 )->setDual( 
static_cast<int>( edge2 ) );
 
  425       mHalfEdge.at( edge2 )->setNext( 
static_cast<int>( edge5 ) );
 
  426       mHalfEdge.at( edge3 )->setDual( 
static_cast<int>( edge4 ) );
 
  427       mHalfEdge.at( edge5 )->setDual( 
static_cast<int>( edge6 ) );
 
  428       mHalfEdge.at( number )->setNext( 
static_cast<int>( edge2 ) );
 
  429       mHalfEdge.at( nextnumber )->setNext( 
static_cast<int>( edge4 ) );
 
  430       mHalfEdge.at( nextnextnumber )->setNext( 
static_cast<int>( edge6 ) );
 
  433       checkSwapRecursively( number, 0 );
 
  434       checkSwapRecursively( nextnumber, 0 );
 
  435       checkSwapRecursively( nextnextnumber, 0 );
 
  438     else if ( number == -20 )
 
  443       int point1 = mHalfEdge[mEdgeWithPoint]->getPoint();
 
  444       int point2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getDual()]->getPoint();
 
  445       double distance1 = p.
distance( *mPointVector[point1] );
 
  451       double distance2 = p.
distance( *mPointVector[point2] );
 
  458       int edgea = mEdgeWithPoint;
 
  459       int edgeb = mHalfEdge[mEdgeWithPoint]->getDual();
 
  460       int edgec = mHalfEdge[edgea]->getNext();
 
  461       int edged = mHalfEdge[edgec]->getNext();
 
  462       int edgee = mHalfEdge[edgeb]->getNext();
 
  463       int edgef = mHalfEdge[edgee]->getNext();
 
  466       int nedge1 = insertEdge( -10, mHalfEdge[edgea]->getNext(), mHalfEdge[edgea]->getPoint(), 
false, 
false );
 
  467       int nedge2 = insertEdge( nedge1, -10, mPointVector.count() - 1, 
false, 
false );
 
  468       int nedge3 = insertEdge( -10, edged, mHalfEdge[edgec]->getPoint(), 
false, 
false );
 
  469       int nedge4 = insertEdge( nedge3, nedge1, mPointVector.count() - 1, 
false, 
false );
 
  470       int nedge5 = insertEdge( -10, edgef, mHalfEdge[edgee]->getPoint(), 
false, 
false );
 
  471       int nedge6 = insertEdge( nedge5, edgeb, mPointVector.count() - 1, 
false, 
false );
 
  474       mHalfEdge[nedge1]->setDual( nedge2 );
 
  475       mHalfEdge[nedge2]->setNext( nedge5 );
 
  476       mHalfEdge[nedge3]->setDual( nedge4 );
 
  477       mHalfEdge[nedge5]->setDual( nedge6 );
 
  478       mHalfEdge[edgea]->setPoint( mPointVector.count() - 1 );
 
  479       mHalfEdge[edgea]->setNext( nedge3 );
 
  480       mHalfEdge[edgec]->setNext( nedge4 );
 
  481       mHalfEdge[edgee]->setNext( nedge6 );
 
  482       mHalfEdge[edgef]->setNext( nedge2 );
 
  485       checkSwapRecursively( edgec, 0 );
 
  486       checkSwapRecursively( edged, 0 );
 
  487       checkSwapRecursively( edgee, 0 );
 
  488       checkSwapRecursively( edgef, 0 );
 
  491     else if ( number == -100 || number == -5 )
 
  497     else if ( number == -25 )
 
  500       QgsPoint *newPoint = mPointVector[mPointVector.count() - 1];
 
  501       QgsPoint *existingPoint = mPointVector[mTwiceInsPoint];
 
  502       existingPoint->
setZ( std::max( newPoint->
z(), existingPoint->
z() ) );
 
  505       return mTwiceInsPoint;
 
  509   return ( mPointVector.count() - 1 );
 
  512 int QgsDualEdgeTriangulation::baseEdgeOfPoint( 
int point )
 
  514   unsigned int actedge = mEdgeInside;
 
  516   if ( mPointVector.count() < 4 || 
point == -1 || mDimension == 1 ) 
 
  518     int fromVirtualPoint = -1;
 
  520     for ( 
int i = 0; i < mHalfEdge.count(); i++ )
 
  522       if ( mHalfEdge[i]->getPoint() == 
point )
 
  524         if ( mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() != -1 )
 
  527           fromVirtualPoint = i;
 
  530     return fromVirtualPoint;
 
  538     if ( control > 1000000 )
 
  544       for ( 
int i = 0; i < mHalfEdge.count(); i++ )
 
  546         if ( mHalfEdge[i]->getPoint() == 
point && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 )
 
  553     int fromPoint = mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint();
 
  554     int toPoint = mHalfEdge[actedge]->getPoint();
 
  556     if ( fromPoint == -1 || toPoint == -1 )
 
  558       for ( 
int i = 0; i < mHalfEdge.count(); i++ )
 
  560         if ( mHalfEdge[i]->getPoint() == 
point && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 )
 
  568     double leftOfNumber = 
MathUtils::leftOf( *mPointVector[
point], mPointVector[mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[actedge]->getPoint()] );
 
  571     if ( mHalfEdge[actedge]->getPoint() == 
point && mHalfEdge[mHalfEdge[actedge]->getNext()]->getPoint() != -1 )
 
  573       mEdgeInside = actedge;
 
  576     else if ( leftOfNumber <= 0.0 )
 
  578       actedge = mHalfEdge[actedge]->getNext();
 
  582       actedge = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[actedge]->getDual()]->getNext()]->getNext()]->getDual();
 
  587 int QgsDualEdgeTriangulation::baseEdgeOfTriangle( 
const QgsPoint &point )
 
  589   unsigned int actEdge = mEdgeInside;
 
  590   if ( mHalfEdge.at( actEdge )->getPoint() < 0 )
 
  591     actEdge = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getNext() )->getDual(); 
 
  592   if ( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint() < 0 )
 
  593     actEdge = mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getDual();
 
  599   int firstEndPoint = 0, secEndPoint = 0, thEndPoint = 0, fouEndPoint = 0; 
 
  603     if ( runs > MAX_BASE_ITERATIONS )
 
  609     double leftOfValue = 
MathUtils::leftOf( 
point, mPointVector.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint() ), mPointVector.at( mHalfEdge.at( actEdge )->getPoint() ) );
 
  624         firstEndPoint = mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint();
 
  625         secEndPoint = mHalfEdge.at( actEdge )->getPoint();
 
  627       else if ( nulls == 1 )
 
  630         thEndPoint = mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint();
 
  631         fouEndPoint = mHalfEdge.at( actEdge )->getPoint();
 
  634       mEdgeWithPoint = actEdge;
 
  643       actEdge = mHalfEdge.at( actEdge )->getDual();
 
  648     actEdge = mHalfEdge.at( actEdge )->getNext();
 
  649     if ( mHalfEdge.at( actEdge )->getPoint() == -1 )
 
  655       mEdgeOutside = ( 
unsigned int )mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
 
  656       mEdgeInside = mHalfEdge.at( mHalfEdge.at( mEdgeOutside )->getDual() )->getNext();
 
  662   if ( numInstabs > 0 )
 
  665     mUnstableEdge = actEdge;
 
  672     if ( firstEndPoint == thEndPoint || firstEndPoint == fouEndPoint )
 
  675       mTwiceInsPoint = firstEndPoint;
 
  678     else if ( secEndPoint == thEndPoint || secEndPoint == fouEndPoint )
 
  681       mTwiceInsPoint = secEndPoint;
 
  693   mEdgeInside = actEdge;
 
  696   nr1 = mHalfEdge.at( actEdge )->getPoint();
 
  697   nr2 = mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getPoint();
 
  698   nr3 = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext() )->getPoint();
 
  699   double x1 = mPointVector.at( nr1 )->x();
 
  700   double y1 = mPointVector.at( nr1 )->y();
 
  701   double x2 = mPointVector.at( nr2 )->x();
 
  702   double y2 = mPointVector.at( nr2 )->y();
 
  703   double x3 = mPointVector.at( nr3 )->x();
 
  704   double y3 = mPointVector.at( nr3 )->y();
 
  707   if ( x1 < x2 && x1 < x3 )
 
  711   else if ( x2 < x1 && x2 < x3 )
 
  713     return mHalfEdge.at( actEdge )->getNext();
 
  715   else if ( x3 < x1 && x3 < x2 )
 
  717     return mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
 
  728       return mHalfEdge.at( actEdge )->getNext();
 
  735       return mHalfEdge.at( actEdge )->getNext();
 
  739       return mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
 
  750       return mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
 
  758   if ( mTriangleInterpolator )
 
  760     return mTriangleInterpolator->
calcNormVec( x, y, result );
 
  764     QgsDebugMsg( QStringLiteral( 
"warning, null pointer" ) );
 
  771   if ( mTriangleInterpolator )
 
  773     return mTriangleInterpolator->
calcPoint( x, y, result );
 
  777     QgsDebugMsg( QStringLiteral( 
"warning, null pointer" ) );
 
  782 bool QgsDualEdgeTriangulation::checkSwapRecursively( 
unsigned int edge, 
unsigned int recursiveDeep )
 
  784   if ( swapPossible( edge ) )
 
  786     QgsPoint *pta = mPointVector.at( mHalfEdge.at( edge )->getPoint() );
 
  787     QgsPoint *ptb = mPointVector.at( mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getPoint() );
 
  788     QgsPoint *ptc = mPointVector.at( mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getNext( ) )->getNext() )->getPoint() );
 
  789     QgsPoint *ptd = mPointVector.at( mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext() )->getPoint() );
 
  790     if ( inCircle( *ptd, *pta, *ptb, *ptc )  ) 
 
  792       doSwapRecursively( edge, recursiveDeep );
 
  799 bool QgsDualEdgeTriangulation::isEdgeNeedSwap( 
unsigned int edge )
 const 
  801   if ( swapPossible( edge ) )
 
  803     QgsPoint *pta = mPointVector[mHalfEdge[edge]->getPoint()];
 
  804     QgsPoint *ptb = mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()];
 
  805     QgsPoint *ptc = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint()];
 
  806     QgsPoint *ptd = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint()];
 
  807     return inCircle( *ptd, *pta, *ptb, *ptc );
 
  814 void QgsDualEdgeTriangulation::doOnlySwap( 
unsigned int edge )
 
  816   unsigned int edge1 = edge;
 
  817   unsigned int edge2 = mHalfEdge[edge]->getDual();
 
  818   unsigned int edge3 = mHalfEdge[edge]->getNext();
 
  819   unsigned int edge4 = mHalfEdge[mHalfEdge[edge]->getNext()]->getNext();
 
  820   unsigned int edge5 = mHalfEdge[mHalfEdge[edge]->getDual()]->getNext();
 
  821   unsigned int edge6 = mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getNext();
 
  822   mHalfEdge[edge1]->setNext( edge4 );
 
  823   mHalfEdge[edge2]->setNext( edge6 );
 
  824   mHalfEdge[edge3]->setNext( edge2 );
 
  825   mHalfEdge[edge4]->setNext( edge5 );
 
  826   mHalfEdge[edge5]->setNext( edge1 );
 
  827   mHalfEdge[edge6]->setNext( edge3 );
 
  828   mHalfEdge[edge1]->setPoint( mHalfEdge[edge3]->getPoint() );
 
  829   mHalfEdge[edge2]->setPoint( mHalfEdge[edge5]->getPoint() );
 
  832 void QgsDualEdgeTriangulation::doSwapRecursively( 
unsigned int edge, 
unsigned int recursiveDeep )
 
  834   unsigned int edge1 = edge;
 
  835   unsigned int edge2 = mHalfEdge.at( edge )->getDual();
 
  836   unsigned int edge3 = mHalfEdge.at( edge )->getNext();
 
  837   unsigned int edge4 = mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getNext();
 
  838   unsigned int edge5 = mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext();
 
  839   unsigned int edge6 = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext() )->getNext();
 
  840   mHalfEdge.at( edge1 )->setNext( edge4 );
 
  841   mHalfEdge.at( edge2 )->setNext( edge6 );
 
  842   mHalfEdge.at( edge3 )->setNext( edge2 );
 
  843   mHalfEdge.at( edge4 )->setNext( edge5 );
 
  844   mHalfEdge.at( edge5 )->setNext( edge1 );
 
  845   mHalfEdge.at( edge6 )->setNext( edge3 );
 
  846   mHalfEdge.at( edge1 )->setPoint( mHalfEdge.at( edge3 )->getPoint() );
 
  847   mHalfEdge.at( edge2 )->setPoint( mHalfEdge.at( edge5 )->getPoint() );
 
  850   if ( recursiveDeep < 100 )
 
  852     checkSwapRecursively( edge3, recursiveDeep );
 
  853     checkSwapRecursively( edge6, recursiveDeep );
 
  854     checkSwapRecursively( edge4, recursiveDeep );
 
  855     checkSwapRecursively( edge5, recursiveDeep );
 
  859     QStack<int> edgesToSwap;
 
  860     edgesToSwap.push( edge3 );
 
  861     edgesToSwap.push( edge6 );
 
  862     edgesToSwap.push( edge4 );
 
  863     edgesToSwap.push( edge5 );
 
  865     while ( !edgesToSwap.isEmpty() && loopCount < 10000 )
 
  868       unsigned int e1 = edgesToSwap.pop();
 
  869       if ( isEdgeNeedSwap( e1 ) )
 
  871         unsigned int e2 = mHalfEdge.at( e1 )->getDual();
 
  872         unsigned int e3 = mHalfEdge.at( e1 )->getNext();
 
  873         unsigned int e4 = mHalfEdge.at( mHalfEdge.at( e1 )->getNext() )->getNext();
 
  874         unsigned int e5 = mHalfEdge.at( mHalfEdge.at( e1 )->getDual() )->getNext();
 
  875         unsigned int e6 = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( e1 )->getDual() )->getNext() )->getNext();
 
  876         mHalfEdge.at( e1 )->setNext( e4 );
 
  877         mHalfEdge.at( e2 )->setNext( e6 );
 
  878         mHalfEdge.at( e3 )->setNext( e2 );
 
  879         mHalfEdge.at( e4 )->setNext( e5 );
 
  880         mHalfEdge.at( e5 )->setNext( e1 );
 
  881         mHalfEdge.at( e6 )->setNext( e3 );
 
  882         mHalfEdge.at( e1 )->setPoint( mHalfEdge.at( e3 )->getPoint() );
 
  883         mHalfEdge.at( e2 )->setPoint( mHalfEdge.at( e5 )->getPoint() );
 
  885         edgesToSwap.push( e3 );
 
  886         edgesToSwap.push( e6 );
 
  887         edgesToSwap.push( e4 );
 
  888         edgesToSwap.push( e5 );
 
  896 void DualEdgeTriangulation::draw( QPainter *p, 
double xlowleft, 
double ylowleft, 
double xupright, 
double yupright, 
double width, 
double height )
 const 
  899   if ( mPointVector.isEmpty() )
 
  904   p->setPen( mEdgeColor );
 
  906   bool *control = 
new bool[mHalfEdge.count()];
 
  907   bool *control2 = 
new bool[mHalfEdge.count()];
 
  909   for ( 
unsigned int i = 0; i <= mHalfEdge.count() - 1; i++ )
 
  915   if ( ( ( xupright - xlowleft ) / width ) > ( ( yupright - ylowleft ) / height ) )
 
  917     double lowerborder = -( height * ( xupright - xlowleft ) / width - yupright );
 
  918     for ( 
unsigned int i = 0; i < mHalfEdge.count() - 1; i++ )
 
  920       if ( mHalfEdge[i]->getPoint() == -1 || mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() == -1 )
 
  927         if ( mHalfEdge[i]->getPoint() != -1 && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 && mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint() != -1 )
 
  929           p1 = mPointVector[mHalfEdge[i]->getPoint()]->getZ();
 
  930           p2 = mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getZ();
 
  931           p3 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getZ();
 
  932           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 ) )
 
  935             pa.setPoint( 0, ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( xupright - xlowleft )*width );
 
  936             pa.setPoint( 1, ( mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getY() ) / ( xupright - xlowleft )*width );
 
  937             pa.setPoint( 2, ( mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getY() ) / ( xupright - xlowleft )*width );
 
  938             QColor 
c( 255, 0, 0 );
 
  940             p->drawPolygon( pa );
 
  945         control2[mHalfEdge[i]->getNext()] = 
true;
 
  946         control2[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()] = 
true;
 
  953       if ( halfEdgeBBoxTest( i, xlowleft, lowerborder, xupright, yupright ) )
 
  955         if ( mHalfEdge[i]->getBreak() )
 
  957           p->setPen( mBreakEdgeColor );
 
  959         else if ( mHalfEdge[i]->getForced() )
 
  961           p->setPen( mForcedEdgeColor );
 
  965         p->drawLine( ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( xupright - xlowleft )*width, ( mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()]->getY() ) / ( xupright - xlowleft )*width );
 
  967         if ( mHalfEdge[i]->getForced() )
 
  969           p->setPen( mEdgeColor );
 
  975       control[mHalfEdge[i]->getDual()] = 
true;
 
  980     double rightborder = width * ( yupright - ylowleft ) / height + xlowleft;
 
  981     for ( 
unsigned int i = 0; i < mHalfEdge.count() - 1; i++ )
 
  983       if ( mHalfEdge[i]->getPoint() == -1 || mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() == -1 )
 
  990         if ( mHalfEdge[i]->getPoint() != -1 && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 && mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint() != -1 )
 
  992           p1 = mPointVector[mHalfEdge[i]->getPoint()]->getZ();
 
  993           p2 = mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getZ();
 
  994           p3 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getZ();
 
  995           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 ) )
 
  998             pa.setPoint( 0, ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( yupright - ylowleft )*height );
 
  999             pa.setPoint( 1, ( mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getY() ) / ( yupright - ylowleft )*height );
 
 1000             pa.setPoint( 2, ( mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getY() ) / ( yupright - ylowleft )*height );
 
 1001             QColor 
c( 255, 0, 0 );
 
 1003             p->drawPolygon( pa );
 
 1008         control2[mHalfEdge[i]->getNext()] = 
true;
 
 1009         control2[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()] = 
true;
 
 1017       if ( halfEdgeBBoxTest( i, xlowleft, ylowleft, rightborder, yupright ) )
 
 1019         if ( mHalfEdge[i]->getBreak() )
 
 1021           p->setPen( mBreakEdgeColor );
 
 1023         else if ( mHalfEdge[i]->getForced() )
 
 1025           p->setPen( mForcedEdgeColor );
 
 1028         p->drawLine( ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( yupright - ylowleft )*height, ( mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()]->getY() ) / ( yupright - ylowleft )*height );
 
 1030         if ( mHalfEdge[i]->getForced() )
 
 1032           p->setPen( mEdgeColor );
 
 1037       control[mHalfEdge[i]->getDual()] = 
true;
 
 1050   int firstedge = baseEdgeOfPoint( p2 );
 
 1054   int nextnextedge = firstedge;
 
 1058     edge = mHalfEdge[nextnextedge]->getDual();
 
 1059     if ( mHalfEdge[edge]->getPoint() == p1 )
 
 1061       theedge = nextnextedge;
 
 1064     nextedge = mHalfEdge[edge]->getNext();
 
 1065     nextnextedge = mHalfEdge[nextedge]->getNext();
 
 1067   while ( nextnextedge != firstedge );
 
 1069   if ( theedge == -10 )
 
 1076   return mHalfEdge[mHalfEdge[mHalfEdge[theedge]->getDual()]->getNext()]->getPoint();
 
 1082   int firstedge = baseEdgeOfPoint( pointno );
 
 1085   if ( firstedge == -1 )
 
 1090   int actedge = firstedge;
 
 1091   int edge, nextedge, nextnextedge;
 
 1094     edge = mHalfEdge[actedge]->getDual();
 
 1095     vlist.append( mHalfEdge[edge]->getPoint() );
 
 1096     nextedge = mHalfEdge[edge]->getNext();
 
 1097     vlist.append( mHalfEdge[nextedge]->getPoint() );
 
 1098     nextnextedge = mHalfEdge[nextedge]->getNext();
 
 1099     vlist.append( mHalfEdge[nextnextedge]->getPoint() );
 
 1100     if ( mHalfEdge[nextnextedge]->getBreak() )
 
 1102       vlist.append( -10 );
 
 1106       vlist.append( -20 );
 
 1108     actedge = nextnextedge;
 
 1110   while ( nextnextedge != firstedge );
 
 1118   if ( mPointVector.size() < 3 )
 
 1124   int edge = baseEdgeOfTriangle( 
point );
 
 1130   else if ( edge >= 0 )
 
 1132     int ptnr1 = mHalfEdge[edge]->getPoint();
 
 1133     int ptnr2 = mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint();
 
 1134     int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint();
 
 1135     p1.
setX( mPointVector[ptnr1]->x() );
 
 1136     p1.
setY( mPointVector[ptnr1]->y() );
 
 1137     p1.
setZ( mPointVector[ptnr1]->z() );
 
 1138     p2.
setX( mPointVector[ptnr2]->x() );
 
 1139     p2.
setY( mPointVector[ptnr2]->y() );
 
 1140     p2.
setZ( mPointVector[ptnr2]->z() );
 
 1141     p3.
setX( mPointVector[ptnr3]->x() );
 
 1142     p3.
setY( mPointVector[ptnr3]->y() );
 
 1143     p3.
setZ( mPointVector[ptnr3]->z() );
 
 1149   else if ( edge == -20 )
 
 1151     int ptnr1 = mHalfEdge[mEdgeWithPoint]->getPoint();
 
 1152     int ptnr2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getPoint();
 
 1153     int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getNext()]->getPoint();
 
 1154     if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
 
 1158     p1.
setX( mPointVector[ptnr1]->x() );
 
 1159     p1.
setY( mPointVector[ptnr1]->y() );
 
 1160     p1.
setZ( mPointVector[ptnr1]->z() );
 
 1161     p2.
setX( mPointVector[ptnr2]->x() );
 
 1162     p2.
setY( mPointVector[ptnr2]->y() );
 
 1163     p2.
setZ( mPointVector[ptnr2]->z() );
 
 1164     p3.
setX( mPointVector[ptnr3]->x() );
 
 1165     p3.
setY( mPointVector[ptnr3]->y() );
 
 1166     p3.
setZ( mPointVector[ptnr3]->z() );
 
 1172   else if ( edge == -25 )
 
 1174     int edge1 = baseEdgeOfPoint( mTwiceInsPoint );
 
 1175     int edge2 = mHalfEdge[edge1]->getNext();
 
 1176     int edge3 = mHalfEdge[edge2]->getNext();
 
 1177     int ptnr1 = mHalfEdge[edge1]->getPoint();
 
 1178     int ptnr2 = mHalfEdge[edge2]->getPoint();
 
 1179     int ptnr3 = mHalfEdge[edge3]->getPoint();
 
 1180     p1.
setX( mPointVector[ptnr1]->x() );
 
 1181     p1.
setY( mPointVector[ptnr1]->y() );
 
 1182     p1.
setZ( mPointVector[ptnr1]->z() );
 
 1183     p2.
setX( mPointVector[ptnr2]->x() );
 
 1184     p2.
setY( mPointVector[ptnr2]->y() );
 
 1185     p2.
setZ( mPointVector[ptnr2]->z() );
 
 1186     p3.
setX( mPointVector[ptnr3]->x() );
 
 1187     p3.
setY( mPointVector[ptnr3]->y() );
 
 1188     p3.
setZ( mPointVector[ptnr3]->z() );
 
 1194   else if ( edge == -5 )
 
 1196     int ptnr1 = mHalfEdge[mUnstableEdge]->getPoint();
 
 1197     int ptnr2 = mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getPoint();
 
 1198     int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getNext()]->getPoint();
 
 1199     if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
 
 1203     p1.
setX( mPointVector[ptnr1]->x() );
 
 1204     p1.
setY( mPointVector[ptnr1]->y() );
 
 1205     p1.
setZ( mPointVector[ptnr1]->z() );
 
 1206     p2.
setX( mPointVector[ptnr2]->x() );
 
 1207     p2.
setY( mPointVector[ptnr2]->y() );
 
 1208     p2.
setZ( mPointVector[ptnr2]->z() );
 
 1209     p3.
setX( mPointVector[ptnr3]->x() );
 
 1210     p3.
setY( mPointVector[ptnr3]->y() );
 
 1211     p3.
setZ( mPointVector[ptnr3]->z() );
 
 1226   if ( mPointVector.size() < 3 )
 
 1232   int edge = baseEdgeOfTriangle( 
point );
 
 1237   else if ( edge >= 0 )
 
 1239     int ptnr1 = mHalfEdge[edge]->getPoint();
 
 1240     int ptnr2 = mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint();
 
 1241     int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint();
 
 1242     p1.
setX( mPointVector[ptnr1]->x() );
 
 1243     p1.
setY( mPointVector[ptnr1]->y() );
 
 1244     p1.
setZ( mPointVector[ptnr1]->z() );
 
 1245     p2.
setX( mPointVector[ptnr2]->x() );
 
 1246     p2.
setY( mPointVector[ptnr2]->y() );
 
 1247     p2.
setZ( mPointVector[ptnr2]->z() );
 
 1248     p3.
setX( mPointVector[ptnr3]->x() );
 
 1249     p3.
setY( mPointVector[ptnr3]->y() );
 
 1250     p3.
setZ( mPointVector[ptnr3]->z() );
 
 1253   else if ( edge == -20 )
 
 1255     int ptnr1 = mHalfEdge[mEdgeWithPoint]->getPoint();
 
 1256     int ptnr2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getPoint();
 
 1257     int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getNext()]->getPoint();
 
 1258     if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
 
 1262     p1.
setX( mPointVector[ptnr1]->x() );
 
 1263     p1.
setY( mPointVector[ptnr1]->y() );
 
 1264     p1.
setZ( mPointVector[ptnr1]->z() );
 
 1265     p2.
setX( mPointVector[ptnr2]->x() );
 
 1266     p2.
setY( mPointVector[ptnr2]->y() );
 
 1267     p2.
setZ( mPointVector[ptnr2]->z() );
 
 1268     p3.
setX( mPointVector[ptnr3]->x() );
 
 1269     p3.
setY( mPointVector[ptnr3]->y() );
 
 1270     p3.
setZ( mPointVector[ptnr3]->z() );
 
 1273   else if ( edge == -25 )
 
 1275     int edge1 = baseEdgeOfPoint( mTwiceInsPoint );
 
 1276     int edge2 = mHalfEdge[edge1]->getNext();
 
 1277     int edge3 = mHalfEdge[edge2]->getNext();
 
 1278     int ptnr1 = mHalfEdge[edge1]->getPoint();
 
 1279     int ptnr2 = mHalfEdge[edge2]->getPoint();
 
 1280     int ptnr3 = mHalfEdge[edge3]->getPoint();
 
 1281     if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
 
 1285     p1.
setX( mPointVector[ptnr1]->x() );
 
 1286     p1.
setY( mPointVector[ptnr1]->y() );
 
 1287     p1.
setZ( mPointVector[ptnr1]->z() );
 
 1288     p2.
setX( mPointVector[ptnr2]->x() );
 
 1289     p2.
setY( mPointVector[ptnr2]->y() );
 
 1290     p2.
setZ( mPointVector[ptnr2]->z() );
 
 1291     p3.
setX( mPointVector[ptnr3]->x() );
 
 1292     p3.
setY( mPointVector[ptnr3]->y() );
 
 1293     p3.
setZ( mPointVector[ptnr3]->z() );
 
 1296   else if ( edge == -5 )
 
 1298     int ptnr1 = mHalfEdge[mUnstableEdge]->getPoint();
 
 1299     int ptnr2 = mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getPoint();
 
 1300     int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getNext()]->getPoint();
 
 1301     if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
 
 1305     p1.
setX( mPointVector[ptnr1]->x() );
 
 1306     p1.
setY( mPointVector[ptnr1]->y() );
 
 1307     p1.
setZ( mPointVector[ptnr1]->z() );
 
 1308     p2.
setX( mPointVector[ptnr2]->x() );
 
 1309     p2.
setY( mPointVector[ptnr2]->y() );
 
 1310     p2.
setZ( mPointVector[ptnr2]->z() );
 
 1311     p3.
setX( mPointVector[ptnr3]->x() );
 
 1312     p3.
setY( mPointVector[ptnr3]->y() );
 
 1313     p3.
setZ( mPointVector[ptnr3]->z() );
 
 1322 unsigned int QgsDualEdgeTriangulation::insertEdge( 
int dual, 
int next, 
int point, 
bool mbreak, 
bool forced )
 
 1325   mHalfEdge.append( edge );
 
 1326   return mHalfEdge.count() - 1;
 
 1330 static bool altitudeTriangleIsSmall( 
const QgsPoint &pointBase1, 
const QgsPoint &pointBase2, 
const QgsPoint &pt3, 
double tolerance )
 
 1333   double x1 = pointBase1.
x();
 
 1334   double y1 = pointBase1.
y();
 
 1335   double x2 = pointBase2.
x();
 
 1336   double y2 = pointBase2.
y();
 
 1347   t = ( X * ny - Y * nx - x1 * ny + y1 * nx ) / ( ( x2 - x1 ) * ny - ( y2 - y1 ) * nx );
 
 1348   projectedPoint.
setX( x1 + t * ( x2 - x1 ) );
 
 1349   projectedPoint.
setY( y1 + t * ( y2 - y1 ) );
 
 1351   return pt3.
distance( projectedPoint ) < tolerance;
 
 1361   QgsPoint *point1 = mPointVector.at( p1 );
 
 1362   QgsPoint *point2 = mPointVector.at( p2 );
 
 1365   QList<int> crossedEdges;
 
 1368   int pointingEdge = 0;
 
 1370   pointingEdge = baseEdgeOfPoint( p1 );
 
 1372   if ( pointingEdge == -1 )
 
 1378   int actEdge = mHalfEdge[pointingEdge]->getDual();
 
 1379   int firstActEdge = actEdge;
 
 1386     if ( control > 100 )
 
 1392     if ( mHalfEdge[actEdge]->getPoint() == -1 )
 
 1394       actEdge = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getNext()]->getDual();
 
 1399     if ( mHalfEdge[actEdge]->getPoint() == p2 )
 
 1401       mHalfEdge[actEdge]->setForced( 
true );
 
 1403       mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced( 
true );
 
 1409     if ( ( point2->
y() - point1->
y() ) / ( mPointVector[mHalfEdge[actEdge]->getPoint()]->y() - point1->
y() ) == ( point2->
x() - point1->
x() ) / ( mPointVector[mHalfEdge[actEdge]->getPoint()]->x() - point1->
x() )
 
 1410                                && ( ( point2->
y() - point1->
y() ) >= 0 ) == ( ( mPointVector[mHalfEdge[actEdge]->getPoint()]->y() - point1->
y() ) > 0 )
 
 1411                                && ( ( point2->
x() - point1->
x() ) >= 0 ) == ( ( mPointVector[mHalfEdge[actEdge]->getPoint()]->x() - point1->
x() ) > 0 ) )
 
 1414       mHalfEdge[actEdge]->setForced( 
true );
 
 1416       mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced( 
true );
 
 1418       int a = insertForcedSegment( mHalfEdge[actEdge]->getPoint(), p2, segmentType );
 
 1423     int oppositeEdge = mHalfEdge[actEdge]->getNext();
 
 1425     if ( mHalfEdge[oppositeEdge]->getPoint() == -1 || mHalfEdge[mHalfEdge[oppositeEdge]->getDual()]->getPoint() == -1 ) 
 
 1427       actEdge = mHalfEdge[mHalfEdge[oppositeEdge]->getNext()]->getDual(); 
 
 1431     QgsPoint *oppositePoint1 = mPointVector[mHalfEdge[oppositeEdge]->getPoint()];
 
 1432     QgsPoint *oppositePoint2 = mPointVector[mHalfEdge[mHalfEdge[oppositeEdge]->getDual()]->getPoint()];
 
 1434     if ( altitudeTriangleIsSmall( *oppositePoint1, *oppositePoint2, *point1, oppositePoint1->
distance( *oppositePoint2 ) / 500 ) )
 
 1442                                       mPointVector[mHalfEdge[oppositeEdge]->getPoint()],
 
 1443                                       mPointVector[mHalfEdge[mHalfEdge[oppositeEdge]->getDual()]->getPoint()] ) )
 
 1449         p3 = mHalfEdge[mHalfEdge[actEdge]->getNext()]->getPoint();
 
 1450         p4 = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getDual()]->getPoint();
 
 1452         double dista = std::sqrt( ( crosspoint.x() - mPointVector[p3]->x() ) * ( crosspoint.x() - mPointVector[p3]->x() ) + ( crosspoint.y() - mPointVector[p3]->y() ) * ( crosspoint.y() - mPointVector[p3]->y() ) );
 
 1453         double distb = std::sqrt( ( crosspoint.x() - mPointVector[p4]->x() ) * ( crosspoint.x() - mPointVector[p4]->x() ) + ( crosspoint.y() - mPointVector[p4]->y() ) * ( crosspoint.y() - mPointVector[p4]->y() ) );
 
 1454         if ( dista <= distb )
 
 1456           insertForcedSegment( p1, p3, segmentType );
 
 1457           int e = insertForcedSegment( p3, p2, segmentType );
 
 1460         else if ( distb <= dista )
 
 1462           insertForcedSegment( p1, p4, segmentType );
 
 1463           int e = insertForcedSegment( p4, p2, segmentType );
 
 1472         p3 = mHalfEdge[mHalfEdge[actEdge]->getNext()]->getPoint();
 
 1473         p4 = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getDual()]->getPoint();
 
 1475         double distpart = std::sqrt( ( crosspoint.x() - mPointVector[p4]->x() ) * ( crosspoint.x() - mPointVector[p4]->x() ) + ( crosspoint.y() - mPointVector[p4]->y() ) * ( crosspoint.y() - mPointVector[p4]->y() ) );
 
 1476         double disttot = std::sqrt( ( mPointVector[p3]->x() - mPointVector[p4]->x() ) * ( mPointVector[p3]->x() - mPointVector[p4]->x() ) + ( mPointVector[p3]->y() - mPointVector[p4]->y() ) * ( mPointVector[p3]->y() - mPointVector[p4]->y() ) );
 
 1477         float frac = distpart / disttot;
 
 1479         if ( frac == 0 || frac == 1 )
 
 1484             mHalfEdge[actEdge]->setForced( 
true );
 
 1486             mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced( 
true );
 
 1488             int a = insertForcedSegment( p4, p2, segmentType );
 
 1491           else if ( frac == 1 )
 
 1494             mHalfEdge[actEdge]->setForced( 
true );
 
 1496             mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced( 
true );
 
 1500               int a = insertForcedSegment( p3, p2, segmentType );
 
 1512           int newpoint = splitHalfEdge( mHalfEdge[actEdge]->getNext(), frac );
 
 1513           insertForcedSegment( p1, newpoint, segmentType );
 
 1514           int e = insertForcedSegment( newpoint, p2, segmentType );
 
 1520       crossedEdges.append( oppositeEdge );
 
 1523     actEdge = mHalfEdge[mHalfEdge[oppositeEdge]->getNext()]->getDual(); 
 
 1525   while ( actEdge != firstActEdge );
 
 1527   if ( crossedEdges.isEmpty() ) 
 
 1529   int lastEdgeOppositePointIndex = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
 
 1532   while ( lastEdgeOppositePointIndex != p2 )
 
 1534     QgsPoint *lastEdgePoint1 = mPointVector[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint()];
 
 1535     QgsPoint *lastEdgePoint2 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint()];
 
 1536     QgsPoint *lastEdgeOppositePoint = mPointVector[lastEdgeOppositePointIndex];
 
 1545         p3 = mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint();
 
 1546         p4 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
 
 1548         double dista = std::sqrt( ( crosspoint.x() - mPointVector[p3]->x() ) * ( crosspoint.x() - mPointVector[p3]->x() ) + ( crosspoint.y() - mPointVector[p3]->y() ) * ( crosspoint.y() - mPointVector[p3]->y() ) );
 
 1549         double distb = std::sqrt( ( crosspoint.x() - mPointVector[p4]->x() ) * ( crosspoint.x() - mPointVector[p4]->x() ) + ( crosspoint.y() - mPointVector[p4]->y() ) * ( crosspoint.y() - mPointVector[p4]->y() ) );
 
 1550         if ( dista <= distb )
 
 1552           insertForcedSegment( p1, p3, segmentType );
 
 1553           int e = insertForcedSegment( p3, p2, segmentType );
 
 1556         else if ( distb <= dista )
 
 1558           insertForcedSegment( p1, p4, segmentType );
 
 1559           int e = insertForcedSegment( p4, p2, segmentType );
 
 1563       else if ( mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getForced() && mForcedCrossBehavior == 
QgsTriangulation::InsertVertex )
 
 1567         p3 = mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint();
 
 1568         p4 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
 
 1570         double distpart = std::sqrt( ( crosspoint.x() - mPointVector[p3]->x() ) * ( crosspoint.x() - mPointVector[p3]->x() ) + ( crosspoint.y() - mPointVector[p3]->y() ) * ( crosspoint.y() - mPointVector[p3]->y() ) );
 
 1571         double disttot = std::sqrt( ( mPointVector[p3]->x() - mPointVector[p4]->x() ) * ( mPointVector[p3]->x() - mPointVector[p4]->x() ) + ( mPointVector[p3]->y() - mPointVector[p4]->y() ) * ( mPointVector[p3]->y() - mPointVector[p4]->y() ) );
 
 1572         float frac = distpart / disttot;
 
 1573         if ( frac == 0 || frac == 1 )
 
 1577         int newpoint = splitHalfEdge( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext(), frac );
 
 1578         insertForcedSegment( p1, newpoint, segmentType );
 
 1579         int e = insertForcedSegment( newpoint, p2, segmentType );
 
 1583       crossedEdges.append( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext() );
 
 1588       if ( mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getForced() && mForcedCrossBehavior == 
QgsTriangulation::SnappingTypeVertex )
 
 1592         p3 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
 
 1593         p4 = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint();
 
 1595         double dista = std::sqrt( ( crosspoint.x() - mPointVector[p3]->x() ) * ( crosspoint.x() - mPointVector[p3]->x() ) + ( crosspoint.y() - mPointVector[p3]->y() ) * ( crosspoint.y() - mPointVector[p3]->y() ) );
 
 1596         double distb = std::sqrt( ( crosspoint.x() - mPointVector[p4]->x() ) * ( crosspoint.x() - mPointVector[p4]->x() ) + ( crosspoint.y() - mPointVector[p4]->y() ) * ( crosspoint.y() - mPointVector[p4]->y() ) );
 
 1597         if ( dista <= distb )
 
 1599           insertForcedSegment( p1, p3, segmentType );
 
 1600           int e = insertForcedSegment( p3, p2, segmentType );
 
 1603         else if ( distb <= dista )
 
 1605           insertForcedSegment( p1, p4, segmentType );
 
 1606           int e = insertForcedSegment( p4, p2, segmentType );
 
 1610       else if ( mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getForced() && mForcedCrossBehavior == 
QgsTriangulation::InsertVertex )
 
 1614         p3 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
 
 1615         p4 = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint();
 
 1617         double distpart = std::sqrt( ( crosspoint.x() - mPointVector[p3]->x() ) * ( crosspoint.x() - mPointVector[p3]->x() ) + ( crosspoint.y() - mPointVector[p3]->y() ) * ( crosspoint.y() - mPointVector[p3]->y() ) );
 
 1618         double disttot = std::sqrt( ( mPointVector[p3]->x() - mPointVector[p4]->x() ) * ( mPointVector[p3]->x() - mPointVector[p4]->x() ) + ( mPointVector[p3]->y() - mPointVector[p4]->y() ) * ( mPointVector[p3]->y() - mPointVector[p4]->y() ) );
 
 1619         float frac = distpart / disttot;
 
 1620         if ( frac == 0 || frac == 1 )
 
 1624         int newpoint = splitHalfEdge( mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext(), frac );
 
 1625         insertForcedSegment( p1, newpoint, segmentType );
 
 1626         int e = insertForcedSegment( newpoint, p2, segmentType );
 
 1630       crossedEdges.append( mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext() );
 
 1637     lastEdgeOppositePointIndex = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
 
 1641   QgsPoint *lastEdgePoint1 = mPointVector[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint()];
 
 1642   QgsPoint *lastEdgePoint2 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint()];
 
 1643   QgsPoint *lastEdgeOppositePoint = mPointVector[lastEdgeOppositePointIndex];
 
 1644   if ( altitudeTriangleIsSmall( *lastEdgePoint1, *lastEdgePoint2, *lastEdgeOppositePoint, lastEdgePoint1->
distance( *lastEdgePoint2 ) / 500 ) )
 
 1648   QList<int>::const_iterator iter;
 
 1649   for ( iter = crossedEdges.constBegin(); iter != crossedEdges.constEnd(); ++iter )
 
 1651     mHalfEdge[( *( iter ) )]->setForced( 
false );
 
 1652     mHalfEdge[( *( iter ) )]->setBreak( 
false );
 
 1653     mHalfEdge[mHalfEdge[( *( iter ) )]->getDual()]->setForced( 
false );
 
 1654     mHalfEdge[mHalfEdge[( *( iter ) )]->getDual()]->setBreak( 
false );
 
 1659   QList<int> freelist = crossedEdges;
 
 1662   QList<int> leftPolygon;
 
 1663   QList<int> rightPolygon;
 
 1666   int firstedge = freelist.first();
 
 1667   mHalfEdge[firstedge]->setForced( 
true );
 
 1669   leftPolygon.append( firstedge );
 
 1670   int dualfirstedge = mHalfEdge[freelist.first()]->getDual();
 
 1671   mHalfEdge[dualfirstedge]->setForced( 
true );
 
 1673   rightPolygon.append( dualfirstedge );
 
 1674   freelist.pop_front();
 
 1678   QList<int>::const_iterator leftiter; 
 
 1679   leftiter = crossedEdges.constEnd();
 
 1683     int newpoint = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[( *leftiter )]->getDual()]->getNext()]->getNext()]->getPoint();
 
 1684     if ( newpoint != actpointl )
 
 1687       actpointl = newpoint;
 
 1688       int theedge = mHalfEdge[mHalfEdge[mHalfEdge[( *leftiter )]->getDual()]->getNext()]->getNext();
 
 1689       leftPolygon.append( theedge );
 
 1691     if ( leftiter == crossedEdges.constBegin() )
 
 1697   leftPolygon.append( mHalfEdge[crossedEdges.first()]->getNext() );
 
 1700   QList<int>::const_iterator rightiter;
 
 1702   for ( rightiter = crossedEdges.constBegin(); rightiter != crossedEdges.constEnd(); ++rightiter )
 
 1704     int newpoint = mHalfEdge[mHalfEdge[mHalfEdge[( *rightiter )]->getNext()]->getNext()]->getPoint();
 
 1705     if ( newpoint != actpointr )
 
 1708       actpointr = newpoint;
 
 1709       int theedge = mHalfEdge[mHalfEdge[( *rightiter )]->getNext()]->getNext();
 
 1710       rightPolygon.append( theedge );
 
 1716   rightPolygon.append( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext() );
 
 1717   mHalfEdge[rightPolygon.last()]->setNext( dualfirstedge );
 
 1720   int actedgel = leftPolygon[1];
 
 1721   leftiter = leftPolygon.constBegin();
 
 1723   for ( ; leftiter != leftPolygon.constEnd(); ++leftiter )
 
 1725     mHalfEdge[actedgel]->setNext( ( *leftiter ) );
 
 1726     actedgel = ( *leftiter );
 
 1730   int actedger = rightPolygon[1];
 
 1731   rightiter = rightPolygon.constBegin();
 
 1733   for ( ; rightiter != rightPolygon.constEnd(); ++rightiter )
 
 1735     mHalfEdge[actedger]->setNext( ( *rightiter ) );
 
 1736     actedger = ( *( rightiter ) );
 
 1741   mHalfEdge[leftPolygon.first()]->setNext( ( *( ++( leftiter = leftPolygon.constBegin() ) ) ) );
 
 1742   mHalfEdge[leftPolygon.first()]->setPoint( p2 );
 
 1743   mHalfEdge[leftPolygon.last()]->setNext( firstedge );
 
 1744   mHalfEdge[rightPolygon.first()]->setNext( ( *( ++( rightiter = rightPolygon.constBegin() ) ) ) );
 
 1745   mHalfEdge[rightPolygon.first()]->setPoint( p1 );
 
 1746   mHalfEdge[rightPolygon.last()]->setNext( dualfirstedge );
 
 1748   triangulatePolygon( &leftPolygon, &freelist, firstedge );
 
 1749   triangulatePolygon( &rightPolygon, &freelist, dualfirstedge );
 
 1752   for ( iter = crossedEdges.constBegin(); iter != crossedEdges.constEnd(); ++iter )
 
 1754     checkSwapRecursively( ( *( iter ) ), 0 );
 
 1757   return leftPolygon.first();
 
 1762   mForcedCrossBehavior = b;
 
 1767   mTriangleInterpolator = interpolator;
 
 1773   double minangle = 0;
 
 1777     bool swapped = 
false;
 
 1778     bool *control = 
new bool[mHalfEdge.count()];
 
 1780     for ( 
int i = 0; i <= mHalfEdge.count() - 1; i++ )
 
 1786     for ( 
int i = 0; i <= mHalfEdge.count() - 1; i++ )
 
 1795       e2 = mHalfEdge[e1]->getNext();
 
 1796       e3 = mHalfEdge[e2]->getNext();
 
 1799       p1 = mHalfEdge[e1]->getPoint();
 
 1800       p2 = mHalfEdge[e2]->getPoint();
 
 1801       p3 = mHalfEdge[e3]->getPoint();
 
 1804       if ( p1 == -1 || p2 == -1 || p3 == -1 )
 
 1812       double el1, el2, el3;
 
 1813       el1 = mPointVector[p1]->z();
 
 1814       el2 = mPointVector[p2]->z();
 
 1815       el3 = mPointVector[p3]->z();
 
 1817       if ( el1 == el2 && el2 == el3 )
 
 1820         if ( swapPossible( ( uint )e1 ) && mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[e1]->getDual()]->getNext()]->getPoint()]->z() != el1 && swapMinAngle( e1 ) > minangle )
 
 1822           doOnlySwap( ( uint )e1 );
 
 1825         else if ( swapPossible( ( uint )e2 ) && mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[e2]->getDual()]->getNext()]->getPoint()]->z() != el2 && swapMinAngle( e2 ) > minangle )
 
 1827           doOnlySwap( ( uint )e2 );
 
 1830         else if ( swapPossible( ( uint )e3 ) && mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[e3]->getDual()]->getNext()]->getPoint()]->z() != el3 && swapMinAngle( e3 ) > minangle )
 
 1832           doOnlySwap( ( uint )e3 );
 
 1865   std::map<int, double> edge_angle;
 
 1866   std::multimap<double, int> angle_edge;
 
 1867   QSet<int> dontexamine;
 
 1876     int nhalfedges = mHalfEdge.count();
 
 1878     for ( 
int i = 0; i < nhalfedges - 1; i++ )
 
 1880       int next = mHalfEdge[i]->getNext();
 
 1881       int nextnext = mHalfEdge[next]->getNext();
 
 1883       if ( mHalfEdge[next]->getPoint() != -1 && ( mHalfEdge[i]->getForced() || mHalfEdge[mHalfEdge[mHalfEdge[i]->getDual()]->getNext()]->getPoint() == -1 ) )
 
 1885         if ( !( ( mHalfEdge[next]->getForced() || edgeOnConvexHull( next ) ) || ( mHalfEdge[nextnext]->getForced() || edgeOnConvexHull( nextnext ) ) ) ) 
 
 1888           while ( 
MathUtils::inDiametral( mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()], mPointVector[mHalfEdge[i]->getPoint()], mPointVector[mHalfEdge[next]->getPoint()] ) )
 
 1891             int pointno = splitHalfEdge( i, 0.5 );
 
 1903   for ( 
int i = 0; i < mHalfEdge.count() - 1; i++ )
 
 1905     p1 = mHalfEdge[mHalfEdge[i]->getDual()]->getPoint();
 
 1906     p2 = mHalfEdge[i]->getPoint();
 
 1907     p3 = mHalfEdge[mHalfEdge[i]->getNext()]->getPoint();
 
 1909     if ( p1 == -1 || p2 == -1 || p3 == -1 )
 
 1915     bool twoforcededges;
 
 1918     twoforcededges = ( mHalfEdge[i]->getForced() || edgeOnConvexHull( i ) ) && ( mHalfEdge[mHalfEdge[i]->getNext()]->getForced() || edgeOnConvexHull( mHalfEdge[i]->getNext() ) );
 
 1920     if ( 
angle < mintol && !twoforcededges )
 
 1922       edge_angle.insert( std::make_pair( i, 
angle ) );
 
 1923       angle_edge.insert( std::make_pair( 
angle, i ) );
 
 1928   for ( std::multimap<double, int>::const_iterator it = angle_edge.begin(); it != angle_edge.end(); ++it )
 
 1930     QgsDebugMsg( QStringLiteral( 
"angle: %1" ).arg( it->first ) );
 
 1934   double minangle = 0;
 
 1937   int minedgenextnext;
 
 1941   while ( !edge_angle.empty() )
 
 1943     minangle = angle_edge.begin()->first;
 
 1944     QgsDebugMsg( QStringLiteral( 
"minangle: %1" ).arg( minangle ) );
 
 1945     minedge = angle_edge.begin()->second;
 
 1946     minedgenext = mHalfEdge[minedge]->getNext();
 
 1947     minedgenextnext = mHalfEdge[minedgenext]->getNext();
 
 1950     if ( !
MathUtils::circumcenter( mPointVector[mHalfEdge[minedge]->getPoint()], mPointVector[mHalfEdge[minedgenext]->getPoint()], mPointVector[mHalfEdge[minedgenextnext]->getPoint()], &
circumcenter ) )
 
 1952       QgsDebugMsg( QStringLiteral( 
"warning, calculation of circumcenter failed" ) );
 
 1954       dontexamine.insert( minedge );
 
 1955       edge_angle.erase( minedge );
 
 1956       std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
 
 1957       while ( minedgeiter->second != minedge )
 
 1961       angle_edge.erase( minedgeiter );
 
 1968       QgsDebugMsg( QStringLiteral( 
"put circumcenter %1//%2 on dontexamine list because it is outside the convex hull" )
 
 1970       dontexamine.insert( minedge );
 
 1971       edge_angle.erase( minedge );
 
 1972       std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
 
 1973       while ( minedgeiter->second != minedge )
 
 1977       angle_edge.erase( minedgeiter );
 
 1983     bool encroached = 
false;
 
 1986     int numhalfedges = mHalfEdge.count();
 
 1987     for ( 
int i = 0; i < numhalfedges; i++ )
 
 1989       if ( mHalfEdge[i]->getForced() || edgeOnConvexHull( i ) )
 
 1996           int pointno = splitHalfEdge( i, 0.5 );
 
 1999           int pointingedge = baseEdgeOfPoint( pointno );
 
 2001           int actedge = pointingedge;
 
 2004           double angle1, angle2, angle3;
 
 2008             ed1 = mHalfEdge[actedge]->getDual();
 
 2009             pt1 = mHalfEdge[ed1]->getPoint();
 
 2010             ed2 = mHalfEdge[ed1]->getNext();
 
 2011             pt2 = mHalfEdge[ed2]->getPoint();
 
 2012             ed3 = mHalfEdge[ed2]->getNext();
 
 2013             pt3 = mHalfEdge[ed3]->getPoint();
 
 2016             if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
 
 2021             angle1 = 
MathUtils::angle( mPointVector[pt3], mPointVector[pt1], mPointVector[pt2], mPointVector[pt1] );
 
 2022             angle2 = 
MathUtils::angle( mPointVector[pt1], mPointVector[pt2], mPointVector[pt3], mPointVector[pt2] );
 
 2023             angle3 = 
MathUtils::angle( mPointVector[pt2], mPointVector[pt3], mPointVector[pt1], mPointVector[pt3] );
 
 2026             bool twoforcededges1, twoforcededges2, twoforcededges3;
 
 2028             if ( ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) && ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) )
 
 2030               twoforcededges1 = 
true;
 
 2034               twoforcededges1 = 
false;
 
 2037             if ( ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) && ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) )
 
 2039               twoforcededges2 = 
true;
 
 2043               twoforcededges2 = 
false;
 
 2046             if ( ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) && ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) )
 
 2048               twoforcededges3 = 
true;
 
 2052               twoforcededges3 = 
false;
 
 2056             QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
 
 2057             if ( ed1iter != dontexamine.end() )
 
 2060               dontexamine.erase( ed1iter );
 
 2065               std::map<int, double>::iterator tempit1;
 
 2066               tempit1 = edge_angle.find( ed1 );
 
 2067               if ( tempit1 != edge_angle.end() )
 
 2070                 double angle = tempit1->second;
 
 2071                 edge_angle.erase( ed1 );
 
 2072                 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( 
angle );
 
 2073                 while ( tempit2->second != ed1 )
 
 2077                 angle_edge.erase( tempit2 );
 
 2081             if ( angle1 < mintol && !twoforcededges1 )
 
 2083               edge_angle.insert( std::make_pair( ed1, angle1 ) );
 
 2084               angle_edge.insert( std::make_pair( angle1, ed1 ) );
 
 2088             QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
 
 2089             if ( ed2iter != dontexamine.end() )
 
 2092               dontexamine.erase( ed2iter );
 
 2097               std::map<int, double>::iterator tempit1;
 
 2098               tempit1 = edge_angle.find( ed2 );
 
 2099               if ( tempit1 != edge_angle.end() )
 
 2102                 double angle = tempit1->second;
 
 2103                 edge_angle.erase( ed2 );
 
 2104                 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( 
angle );
 
 2105                 while ( tempit2->second != ed2 )
 
 2109                 angle_edge.erase( tempit2 );
 
 2113             if ( angle2 < mintol && !twoforcededges2 )
 
 2115               edge_angle.insert( std::make_pair( ed2, angle2 ) );
 
 2116               angle_edge.insert( std::make_pair( angle2, ed2 ) );
 
 2120             QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
 
 2121             if ( ed3iter != dontexamine.end() )
 
 2124               dontexamine.erase( ed3iter );
 
 2129               std::map<int, double>::iterator tempit1;
 
 2130               tempit1 = edge_angle.find( ed3 );
 
 2131               if ( tempit1 != edge_angle.end() )
 
 2134                 double angle = tempit1->second;
 
 2135                 edge_angle.erase( ed3 );
 
 2136                 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( 
angle );
 
 2137                 while ( tempit2->second != ed3 )
 
 2141                 angle_edge.erase( tempit2 );
 
 2145             if ( angle3 < mintol && !twoforcededges3 )
 
 2147               edge_angle.insert( std::make_pair( ed3, angle3 ) );
 
 2148               angle_edge.insert( std::make_pair( angle3, ed3 ) );
 
 2153           while ( actedge != pointingedge );
 
 2161     QSet<int> influenceedges;
 
 2163     if ( baseedge == -5 )
 
 2166       edge_angle.erase( minedge );
 
 2167       std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
 
 2168       while ( minedgeiter->second != minedge )
 
 2172       angle_edge.erase( minedgeiter );
 
 2175     else if ( baseedge == -25 )
 
 2178       edge_angle.erase( minedge );
 
 2179       std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
 
 2180       while ( minedgeiter->second != minedge )
 
 2184       angle_edge.erase( minedgeiter );
 
 2187     else if ( baseedge == -20 )
 
 2189       baseedge = mEdgeWithPoint;
 
 2192     evaluateInfluenceRegion( &
circumcenter, baseedge, influenceedges );
 
 2193     evaluateInfluenceRegion( &
circumcenter, mHalfEdge[baseedge]->getNext(), influenceedges );
 
 2194     evaluateInfluenceRegion( &
circumcenter, mHalfEdge[mHalfEdge[baseedge]->getNext()]->getNext(), influenceedges );
 
 2196     for ( QSet<int>::iterator it = influenceedges.begin(); it != influenceedges.end(); ++it )
 
 2198       if ( ( mHalfEdge[*it]->getForced() || edgeOnConvexHull( *it ) ) && 
MathUtils::inDiametral( mPointVector[mHalfEdge[*it]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[*it]->getDual()]->getPoint()], &
circumcenter ) )
 
 2202         int pointno = splitHalfEdge( *it, 0.5 );
 
 2206         int pointingedge = baseEdgeOfPoint( pointno );
 
 2208         int actedge = pointingedge;
 
 2211         double angle1, angle2, angle3;
 
 2215           ed1 = mHalfEdge[actedge]->getDual();
 
 2216           pt1 = mHalfEdge[ed1]->getPoint();
 
 2217           ed2 = mHalfEdge[ed1]->getNext();
 
 2218           pt2 = mHalfEdge[ed2]->getPoint();
 
 2219           ed3 = mHalfEdge[ed2]->getNext();
 
 2220           pt3 = mHalfEdge[ed3]->getPoint();
 
 2223           if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
 
 2228           angle1 = 
MathUtils::angle( mPointVector[pt3], mPointVector[pt1], mPointVector[pt2], mPointVector[pt1] );
 
 2229           angle2 = 
MathUtils::angle( mPointVector[pt1], mPointVector[pt2], mPointVector[pt3], mPointVector[pt2] );
 
 2230           angle3 = 
MathUtils::angle( mPointVector[pt2], mPointVector[pt3], mPointVector[pt1], mPointVector[pt3] );
 
 2233           bool twoforcededges1, twoforcededges2, twoforcededges3;
 
 2237           twoforcededges1 = ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) && ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) );
 
 2239           twoforcededges2 = ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) && ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) );
 
 2241           twoforcededges3 = ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) && ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) );
 
 2245           QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
 
 2246           if ( ed1iter != dontexamine.end() )
 
 2249             dontexamine.erase( ed1iter );
 
 2254             std::map<int, double>::iterator tempit1;
 
 2255             tempit1 = edge_angle.find( ed1 );
 
 2256             if ( tempit1 != edge_angle.end() )
 
 2259               double angle = tempit1->second;
 
 2260               edge_angle.erase( ed1 );
 
 2261               std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( 
angle );
 
 2262               while ( tempit2->second != ed1 )
 
 2266               angle_edge.erase( tempit2 );
 
 2270           if ( angle1 < mintol && !twoforcededges1 )
 
 2272             edge_angle.insert( std::make_pair( ed1, angle1 ) );
 
 2273             angle_edge.insert( std::make_pair( angle1, ed1 ) );
 
 2277           QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
 
 2278           if ( ed2iter != dontexamine.end() )
 
 2281             dontexamine.erase( ed2iter );
 
 2286             std::map<int, double>::iterator tempit1;
 
 2287             tempit1 = edge_angle.find( ed2 );
 
 2288             if ( tempit1 != edge_angle.end() )
 
 2291               double angle = tempit1->second;
 
 2292               edge_angle.erase( ed2 );
 
 2293               std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( 
angle );
 
 2294               while ( tempit2->second != ed2 )
 
 2298               angle_edge.erase( tempit2 );
 
 2302           if ( angle2 < mintol && !twoforcededges2 )
 
 2304             edge_angle.insert( std::make_pair( ed2, angle2 ) );
 
 2305             angle_edge.insert( std::make_pair( angle2, ed2 ) );
 
 2309           QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
 
 2310           if ( ed3iter != dontexamine.end() )
 
 2313             dontexamine.erase( ed3iter );
 
 2318             std::map<int, double>::iterator tempit1;
 
 2319             tempit1 = edge_angle.find( ed3 );
 
 2320             if ( tempit1 != edge_angle.end() )
 
 2323               double angle = tempit1->second;
 
 2324               edge_angle.erase( ed3 );
 
 2325               std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( 
angle );
 
 2326               while ( tempit2->second != ed3 )
 
 2330               angle_edge.erase( tempit2 );
 
 2334           if ( angle3 < mintol && !twoforcededges3 )
 
 2336             edge_angle.insert( std::make_pair( ed3, angle3 ) );
 
 2337             angle_edge.insert( std::make_pair( angle3, ed3 ) );
 
 2342         while ( actedge != pointingedge );
 
 2358     if ( pointno == -100 || pointno == mTwiceInsPoint )
 
 2360       if ( pointno == -100 )
 
 2362         QgsDebugMsg( QStringLiteral( 
"put circumcenter %1//%2 on dontexamine list because of numerical instabilities" )
 
 2365       else if ( pointno == mTwiceInsPoint )
 
 2367         QgsDebugMsg( QStringLiteral( 
"put circumcenter %1//%2 on dontexamine list because it is already inserted" )
 
 2371         for ( 
int i = 0; i < mPointVector.count(); i++ )
 
 2380           QgsDebugMsg( QStringLiteral( 
"point is not present in the triangulation" ) );
 
 2384       dontexamine.insert( minedge );
 
 2385       edge_angle.erase( minedge );
 
 2386       std::multimap<double, int>::iterator minedgeiter = angle_edge.lower_bound( minangle );
 
 2387       while ( minedgeiter->second != minedge )
 
 2391       angle_edge.erase( minedgeiter );
 
 2396       QgsDebugMsg( QStringLiteral( 
"circumcenter added" ) );
 
 2400       int pointingedge = baseEdgeOfPoint( pointno );
 
 2402       int actedge = pointingedge;
 
 2405       double angle1, angle2, angle3;
 
 2409         ed1 = mHalfEdge[actedge]->getDual();
 
 2410         pt1 = mHalfEdge[ed1]->getPoint();
 
 2411         ed2 = mHalfEdge[ed1]->getNext();
 
 2412         pt2 = mHalfEdge[ed2]->getPoint();
 
 2413         ed3 = mHalfEdge[ed2]->getNext();
 
 2414         pt3 = mHalfEdge[ed3]->getPoint();
 
 2417         if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
 
 2422         angle1 = 
MathUtils::angle( mPointVector[pt3], mPointVector[pt1], mPointVector[pt2], mPointVector[pt1] );
 
 2423         angle2 = 
MathUtils::angle( mPointVector[pt1], mPointVector[pt2], mPointVector[pt3], mPointVector[pt2] );
 
 2424         angle3 = 
MathUtils::angle( mPointVector[pt2], mPointVector[pt3], mPointVector[pt1], mPointVector[pt3] );
 
 2427         bool twoforcededges1, twoforcededges2, twoforcededges3;
 
 2429         twoforcededges1 = ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) && ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) );
 
 2431         twoforcededges2 = ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) && ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) );
 
 2433         twoforcededges3 = ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) && ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) );
 
 2437         QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
 
 2438         if ( ed1iter != dontexamine.end() )
 
 2441           dontexamine.erase( ed1iter );
 
 2446           std::map<int, double>::iterator tempit1;
 
 2447           tempit1 = edge_angle.find( ed1 );
 
 2448           if ( tempit1 != edge_angle.end() )
 
 2451             double angle = tempit1->second;
 
 2452             edge_angle.erase( ed1 );
 
 2453             std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( 
angle );
 
 2454             while ( tempit2->second != ed1 )
 
 2458             angle_edge.erase( tempit2 );
 
 2462         if ( angle1 < mintol && !twoforcededges1 )
 
 2464           edge_angle.insert( std::make_pair( ed1, angle1 ) );
 
 2465           angle_edge.insert( std::make_pair( angle1, ed1 ) );
 
 2470         QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
 
 2471         if ( ed2iter != dontexamine.end() )
 
 2474           dontexamine.erase( ed2iter );
 
 2479           std::map<int, double>::iterator tempit1;
 
 2480           tempit1 = edge_angle.find( ed2 );
 
 2481           if ( tempit1 != edge_angle.end() )
 
 2484             double angle = tempit1->second;
 
 2485             edge_angle.erase( ed2 );
 
 2486             std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( 
angle );
 
 2487             while ( tempit2->second != ed2 )
 
 2491             angle_edge.erase( tempit2 );
 
 2495         if ( angle2 < mintol && !twoforcededges2 )
 
 2497           edge_angle.insert( std::make_pair( ed2, angle2 ) );
 
 2498           angle_edge.insert( std::make_pair( angle2, ed2 ) );
 
 2502         QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
 
 2503         if ( ed3iter != dontexamine.end() )
 
 2506           dontexamine.erase( ed3iter );
 
 2511           std::map<int, double>::iterator tempit1;
 
 2512           tempit1 = edge_angle.find( ed3 );
 
 2513           if ( tempit1 != edge_angle.end() )
 
 2516             double angle = tempit1->second;
 
 2517             edge_angle.erase( ed3 );
 
 2518             std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( 
angle );
 
 2519             while ( tempit2->second != ed3 )
 
 2523             angle_edge.erase( tempit2 );
 
 2527         if ( angle3 < mintol && !twoforcededges3 )
 
 2529           edge_angle.insert( std::make_pair( ed3, angle3 ) );
 
 2530           angle_edge.insert( std::make_pair( angle3, ed3 ) );
 
 2535       while ( actedge != pointingedge );
 
 2541   for ( QSet<int>::iterator it = dontexamine.begin(); it != dontexamine.end(); ++it )
 
 2543     QgsDebugMsg( QStringLiteral( 
"edge nr. %1 is in dontexamine" ).arg( *it ) );
 
 2549 bool QgsDualEdgeTriangulation::swapPossible( 
unsigned int edge )
 const 
 2552   if ( mHalfEdge[edge]->getForced() )
 
 2558   if ( mHalfEdge[edge]->getPoint() == -1 || mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() == -1 || mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() == -1 || mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() == -1 )
 
 2563   QgsPoint *pta = mPointVector[mHalfEdge[edge]->getPoint()];
 
 2564   QgsPoint *ptb = mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()];
 
 2565   QgsPoint *ptc = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint()];
 
 2566   QgsPoint *ptd = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint()];
 
 2586 void QgsDualEdgeTriangulation::triangulatePolygon( QList<int> *poly, QList<int> *free, 
int mainedge )
 
 2590     if ( poly->count() == 3 )
 
 2596     QList<int>::const_iterator iterator = ++( poly->constBegin() );
 
 2597     double distance = 
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] );
 
 2598     int distedge = ( *iterator );
 
 2599     int nextdistedge = mHalfEdge[( *iterator )]->getNext();
 
 2602     while ( iterator != --( poly->constEnd() ) )
 
 2604       if ( 
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] ) < distance )
 
 2606         distedge = ( *iterator );
 
 2607         nextdistedge = mHalfEdge[( *iterator )]->getNext();
 
 2608         distance = 
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] );
 
 2613     if ( nextdistedge == ( *( --poly->end() ) ) )
 
 2615       int inserta = free->first();
 
 2616       int insertb = mHalfEdge[inserta]->getDual();
 
 2619       mHalfEdge[inserta]->setNext( ( poly->at( 1 ) ) );
 
 2620       mHalfEdge[inserta]->setPoint( mHalfEdge[mainedge]->getPoint() );
 
 2621       mHalfEdge[insertb]->setNext( nextdistedge );
 
 2622       mHalfEdge[insertb]->setPoint( mHalfEdge[distedge]->getPoint() );
 
 2623       mHalfEdge[distedge]->setNext( inserta );
 
 2624       mHalfEdge[mainedge]->setNext( insertb );
 
 2627       for ( iterator = ( ++( poly->constBegin() ) ); ( *iterator ) != nextdistedge; ++iterator )
 
 2629         polya.append( ( *iterator ) );
 
 2631       polya.prepend( inserta );
 
 2635       for ( iterator = polya.begin(); iterator != polya.end(); ++iterator )
 
 2641       triangulatePolygon( &polya, free, inserta );
 
 2644     else if ( distedge == ( *( ++poly->begin() ) ) )
 
 2646       int inserta = free->first();
 
 2647       int insertb = mHalfEdge[inserta]->getDual();
 
 2650       mHalfEdge[inserta]->setNext( ( poly->at( 2 ) ) );
 
 2651       mHalfEdge[inserta]->setPoint( mHalfEdge[distedge]->getPoint() );
 
 2652       mHalfEdge[insertb]->setNext( mainedge );
 
 2653       mHalfEdge[insertb]->setPoint( mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint() );
 
 2654       mHalfEdge[distedge]->setNext( insertb );
 
 2655       mHalfEdge[( *( --poly->end() ) )]->setNext( inserta );
 
 2658       iterator = poly->constBegin();
 
 2660       while ( iterator != poly->constEnd() )
 
 2662         polya.append( ( *iterator ) );
 
 2665       polya.prepend( inserta );
 
 2667       triangulatePolygon( &polya, free, inserta );
 
 2672       int inserta = free->first();
 
 2673       int insertb = mHalfEdge[inserta]->getDual();
 
 2676       int insertc = free->first();
 
 2677       int insertd = mHalfEdge[insertc]->getDual();
 
 2680       mHalfEdge[inserta]->setNext( ( poly->at( 1 ) ) );
 
 2681       mHalfEdge[inserta]->setPoint( mHalfEdge[mainedge]->getPoint() );
 
 2682       mHalfEdge[insertb]->setNext( insertd );
 
 2683       mHalfEdge[insertb]->setPoint( mHalfEdge[distedge]->getPoint() );
 
 2684       mHalfEdge[insertc]->setNext( nextdistedge );
 
 2685       mHalfEdge[insertc]->setPoint( mHalfEdge[distedge]->getPoint() );
 
 2686       mHalfEdge[insertd]->setNext( mainedge );
 
 2687       mHalfEdge[insertd]->setPoint( mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint() );
 
 2689       mHalfEdge[distedge]->setNext( inserta );
 
 2690       mHalfEdge[mainedge]->setNext( insertb );
 
 2691       mHalfEdge[( *( --poly->end() ) )]->setNext( insertc );
 
 2697       for ( iterator = ++( poly->constBegin() ); ( *iterator ) != nextdistedge; ++iterator )
 
 2699         polya.append( ( *iterator ) );
 
 2701       polya.prepend( inserta );
 
 2704       while ( iterator != poly->constEnd() )
 
 2706         polyb.append( ( *iterator ) );
 
 2709       polyb.prepend( insertc );
 
 2711       triangulatePolygon( &polya, free, inserta );
 
 2712       triangulatePolygon( &polyb, free, insertc );
 
 2718     QgsDebugMsg( QStringLiteral( 
"warning, null pointer" ) );
 
 2726   unsigned int actedge = mEdgeInside;
 
 2734     if ( runs > MAX_BASE_ITERATIONS )
 
 2736       QgsDebugMsg( QStringLiteral( 
"warning, instability detected: Point coordinates: %1//%2" ).arg( x ).arg( y ) );
 
 2740     if ( 
MathUtils::leftOf( 
point, mPointVector[mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[actedge]->getPoint()] ) < ( -
leftOfTresh ) )
 
 2749     else if ( fabs( 
MathUtils::leftOf( 
point, mPointVector[mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[actedge]->getPoint()] ) ) <= 
leftOfTresh ) 
 
 2752       mEdgeWithPoint = actedge;
 
 2762       actedge = mHalfEdge[actedge]->getDual();
 
 2768     actedge = mHalfEdge[actedge]->getNext();
 
 2769     if ( mHalfEdge[actedge]->getPoint() == -1 )
 
 2775       mEdgeOutside = ( 
unsigned int )mHalfEdge[mHalfEdge[actedge]->getNext()]->getNext();
 
 2785   if ( numinstabs > 0 )
 
 2787     QgsDebugMsg( QStringLiteral( 
"numerical instabilities" ) );
 
 2795   mEdgeInside = actedge;
 
 2800 bool DualEdgeTriangulation::readFromTAFF( QString filename )
 
 2802   QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
 
 2804   QFile file( filename );
 
 2805   file.open( IO_Raw | IO_ReadOnly );
 
 2806   QBuffer buffer( file.readAll() );
 
 2809   QTextStream textstream( &buffer );
 
 2810   buffer.open( IO_ReadOnly );
 
 2813   int numberofhalfedges;
 
 2817   while ( buff.mid( 0, 4 ) != 
"TRIA" )
 
 2819     buff = textstream.readLine();
 
 2821   while ( buff.mid( 0, 4 ) != 
"NEDG" )
 
 2823     buff = textstream.readLine();
 
 2825   numberofhalfedges = buff.section( 
' ', 1, 1 ).toInt();
 
 2826   mHalfEdge.resize( numberofhalfedges );
 
 2829   while ( buff.mid( 0, 4 ) != 
"DATA" )
 
 2834   int nr1, nr2, dual1, dual2, point1, point2, next1, next2, fo1, fo2, b1, b2;
 
 2835   bool forced1, forced2, break1, break2;
 
 2839   QProgressBar *edgebar = 
new QProgressBar();
 
 2840   edgebar->setCaption( tr( 
"Reading edges…" ) );
 
 2841   edgebar->setTotalSteps( numberofhalfedges / 2 );
 
 2842   edgebar->setMinimumWidth( 400 );
 
 2843   edgebar->move( 500, 500 );
 
 2846   for ( 
int i = 0; i < numberofhalfedges / 2; i++ )
 
 2848     if ( i % 1000 == 0 )
 
 2850       edgebar->setProgress( i );
 
 2854     textstream >> point1;
 
 2855     textstream >> next1;
 
 2879     textstream >> point2;
 
 2880     textstream >> next2;
 
 2918     mHalfEdge.insert( nr1, hf1 );
 
 2919     mHalfEdge.insert( nr2, hf2 );
 
 2923   edgebar->setProgress( numberofhalfedges / 2 );
 
 2927   for ( 
int i = 0; i < numberofhalfedges; i++ )
 
 2930     a = mHalfEdge[i]->getPoint();
 
 2931     b = mHalfEdge[mHalfEdge[i]->getDual()]->getPoint();
 
 2932     c = mHalfEdge[mHalfEdge[i]->getNext()]->getPoint();
 
 2933     d = mHalfEdge[mHalfEdge[mHalfEdge[i]->getDual()]->getNext()]->getPoint();
 
 2934     if ( a != -1 && b != -1 && 
c != -1 && d != -1 )
 
 2942   while ( buff.mid( 0, 4 ) != 
"POIN" )
 
 2944     buff = textstream.readLine();
 
 2947   while ( buff.mid( 0, 4 ) != 
"NPTS" )
 
 2949     buff = textstream.readLine();
 
 2952   numberofpoints = buff.section( 
' ', 1, 1 ).toInt();
 
 2953   mPointVector.resize( numberofpoints );
 
 2955   while ( buff.mid( 0, 4 ) != 
"DATA" )
 
 2960   QProgressBar *pointbar = 
new QProgressBar();
 
 2961   pointbar->setCaption( tr( 
"Reading points…" ) );
 
 2962   pointbar->setTotalSteps( numberofpoints );
 
 2963   pointbar->setMinimumWidth( 400 );
 
 2964   pointbar->move( 500, 500 );
 
 2969   for ( 
int i = 0; i < numberofpoints; i++ )
 
 2971     if ( i % 1000 == 0 )
 
 2973       pointbar->setProgress( i );
 
 2983     mPointVector.insert( i, p );
 
 2999       else if ( x > xMax )
 
 3008       else if ( y > yMax )
 
 3015   pointbar->setProgress( numberofpoints );
 
 3017   QApplication::restoreOverrideCursor();
 
 3021 bool DualEdgeTriangulation::saveToTAFF( QString filename )
 const 
 3023   QFile outputfile( filename );
 
 3024   if ( !outputfile.open( IO_WriteOnly ) )
 
 3026     QMessageBox::warning( 0, tr( 
"Warning" ), tr( 
"File could not be written." ), QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton );
 
 3030   QTextStream outstream( &outputfile );
 
 3031   outstream.precision( 9 );
 
 3034   outstream << 
"TRIA" << std::endl << std::flush;
 
 3035   outstream << 
"NEDG " << mHalfEdge.count() << std::endl << std::flush;
 
 3036   outstream << 
"PANO 1" << std::endl << std::flush;
 
 3037   outstream << 
"DATA ";
 
 3039   bool *cont = 
new bool[mHalfEdge.count()];
 
 3040   for ( 
unsigned int i = 0; i <= mHalfEdge.count() - 1; i++ )
 
 3045   for ( 
unsigned int i = 0; i < mHalfEdge.count(); i++ )
 
 3052     int dual = mHalfEdge[i]->getDual();
 
 3053     outstream << i << 
" " << mHalfEdge[i]->getPoint() << 
" " << mHalfEdge[i]->getNext() << 
" " << mHalfEdge[i]->getForced() << 
" " << mHalfEdge[i]->getBreak() << 
" ";
 
 3054     outstream << dual << 
" " << mHalfEdge[dual]->getPoint() << 
" " << mHalfEdge[dual]->getNext() << 
" " << mHalfEdge[dual]->getForced() << 
" " << mHalfEdge[dual]->getBreak() << 
" ";
 
 3058   outstream << std::endl << std::flush;
 
 3059   outstream << std::endl << std::flush;
 
 3064   outstream << 
"POIN" << std::endl << std::flush;
 
 3065   outstream << 
"NPTS " << getNumberOfPoints() << std::endl << std::flush;
 
 3066   outstream << 
"PATT 3" << std::endl << std::flush;
 
 3067   outstream << 
"DATA ";
 
 3069   for ( 
int i = 0; i < getNumberOfPoints(); i++ )
 
 3072     outstream << p->getX() << 
" " << p->getY() << 
" " << p->getZ() << 
" ";
 
 3074   outstream << std::endl << std::flush;
 
 3075   outstream << std::endl << std::flush;
 
 3084   int edge1 = baseEdgeOfTriangle( p );
 
 3091     edge2 = mHalfEdge[edge1]->getNext();
 
 3092     edge3 = mHalfEdge[edge2]->getNext();
 
 3093     point1 = 
point( mHalfEdge[edge1]->getPoint() );
 
 3094     point2 = 
point( mHalfEdge[edge2]->getPoint() );
 
 3095     point3 = 
point( mHalfEdge[edge3]->getPoint() );
 
 3096     if ( point1 && point2 && point3 )
 
 3099       double dist1, dist2, dist3;
 
 3103       if ( dist1 <= dist2 && dist1 <= dist3 )
 
 3106         if ( swapPossible( edge1 ) )
 
 3108           doOnlySwap( edge1 );
 
 3111       else if ( dist2 <= dist1 && dist2 <= dist3 )
 
 3114         if ( swapPossible( edge2 ) )
 
 3116           doOnlySwap( edge2 );
 
 3119       else if ( dist3 <= dist1 && dist3 <= dist2 )
 
 3122         if ( swapPossible( edge3 ) )
 
 3124           doOnlySwap( edge3 );
 
 3146   const int edge1 = baseEdgeOfTriangle( p );
 
 3149     const int edge2 = mHalfEdge[edge1]->getNext();
 
 3150     const int edge3 = mHalfEdge[edge2]->getNext();
 
 3154     if ( point1 && point2 && point3 )
 
 3160       if ( dist1 <= dist2 && dist1 <= dist3 )
 
 3162         p1 = mHalfEdge[edge1]->getPoint();
 
 3163         p2 = mHalfEdge[mHalfEdge[edge1]->getNext()]->getPoint();
 
 3164         p3 = mHalfEdge[mHalfEdge[edge1]->getDual()]->getPoint();
 
 3165         p4 = mHalfEdge[mHalfEdge[mHalfEdge[edge1]->getDual()]->getNext()]->getPoint();
 
 3167       else if ( dist2 <= dist1 && dist2 <= dist3 )
 
 3169         p1 = mHalfEdge[edge2]->getPoint();
 
 3170         p2 = mHalfEdge[mHalfEdge[edge2]->getNext()]->getPoint();
 
 3171         p3 = mHalfEdge[mHalfEdge[edge2]->getDual()]->getPoint();
 
 3172         p4 = mHalfEdge[mHalfEdge[mHalfEdge[edge2]->getDual()]->getNext()]->getPoint();
 
 3176         p1 = mHalfEdge[edge3]->getPoint();
 
 3177         p2 = mHalfEdge[mHalfEdge[edge3]->getNext()]->getPoint();
 
 3178         p3 = mHalfEdge[mHalfEdge[edge3]->getDual()]->getPoint();
 
 3179         p4 = mHalfEdge[mHalfEdge[mHalfEdge[edge3]->getDual()]->getNext()]->getPoint();
 
 3190       QgsDebugMsg( QStringLiteral( 
"warning: null pointer" ) );
 
 3195     QgsDebugMsg( QStringLiteral( 
"Edge number negative" ) );
 
 3207   bool *alreadyVisitedEdges = 
new bool[mHalfEdge.size()];
 
 3208   if ( !alreadyVisitedEdges )
 
 3214   for ( 
int i = 0; i < mHalfEdge.size(); ++i )
 
 3216     alreadyVisitedEdges[i] = 
false;
 
 3219   for ( 
int i = 0; i < mHalfEdge.size(); ++i )
 
 3224     HalfEdge *currentEdge = mHalfEdge[i];
 
 3225     if ( currentEdge->
getPoint() != -1 && mHalfEdge[currentEdge->
getDual()]->getPoint() != -1 && !alreadyVisitedEdges[currentEdge->
getDual()] )
 
 3231       QgsPoint *p2 = mPointVector[mHalfEdge[currentEdge->
getDual()]->getPoint()];
 
 3239       QString attributeString;
 
 3244           attributeString = QStringLiteral( 
"break line" );
 
 3248           attributeString = QStringLiteral( 
"structure line" );
 
 3255     alreadyVisitedEdges[i] = 
true;
 
 3258   delete [] alreadyVisitedEdges;
 
 3265   QVector<bool> alreadyVisitedEdges( mHalfEdge.count(), 
false );
 
 3270   QVector< bool> edgeToTreat( mHalfEdge.count(), 
true );
 
 3271   QHash<HalfEdge *, int > edgesHash;
 
 3272   for ( 
int i = 0; i < mHalfEdge.count(); ++i )
 
 3274     edgesHash.insert( mHalfEdge[i], i );
 
 3283   int edgeCount = edgeToTreat.count();
 
 3284   for ( 
int i = 0 ; i < edgeCount; ++i )
 
 3286     bool containVirtualPoint = 
false;
 
 3287     if ( edgeToTreat[i] )
 
 3289       HalfEdge *currentEdge = mHalfEdge[i];
 
 3294         edgeToTreat[edgesHash.value( currentEdge )] = 
false;
 
 3295         face.append( currentEdge->
getPoint() );
 
 3296         containVirtualPoint |= currentEdge->
getPoint() == -1;
 
 3297         currentEdge = mHalfEdge.at( currentEdge->
getNext() );
 
 3299       while ( currentEdge != firstEdge && !containVirtualPoint && ( !feedback || !feedback->
isCanceled() ) );
 
 3300       if ( !containVirtualPoint )
 
 3301         mesh.
faces.append( face );
 
 3305       feedback->
setProgress( ( 100 *  i ) / edgeCount ) ;
 
 3312 double QgsDualEdgeTriangulation::swapMinAngle( 
int edge )
 const 
 3315   QgsPoint *p2 = 
point( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() );
 
 3316   QgsPoint *p3 = 
point( mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() );
 
 3317   QgsPoint *p4 = 
point( mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() );
 
 3324   if ( angle2 < minangle )
 
 3329   if ( angle3 < minangle )
 
 3334   if ( angle4 < minangle )
 
 3339   if ( angle5 < minangle )
 
 3344   if ( angle6 < minangle )
 
 3352 int QgsDualEdgeTriangulation::splitHalfEdge( 
int edge, 
float position )
 
 3355   if ( position < 0 || position > 1 )
 
 3357     QgsDebugMsg( QStringLiteral( 
"warning, position is not between 0 and 1" ) );
 
 3361   QgsPoint *p = 
new QgsPoint( mPointVector[mHalfEdge[edge]->getPoint()]->x()*position + mPointVector[mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint()]->x() * ( 1 - position ), mPointVector[mHalfEdge[edge]->getPoint()]->y()*position + mPointVector[mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint()]->y() * ( 1 - position ), 0 );
 
 3366   p->
setZ( zvaluepoint.z() );
 
 3369   if ( mPointVector.count() >= mPointVector.size() )
 
 3371     mPointVector.resize( mPointVector.count() + 1 );
 
 3373   QgsDebugMsg( QStringLiteral( 
"inserting point nr. %1, %2//%3//%4" ).arg( mPointVector.count() ).arg( p->
x() ).arg( p->
y() ).arg( p->
z() ) );
 
 3374   mPointVector.insert( mPointVector.count(), p );
 
 3377   int dualedge = mHalfEdge[edge]->getDual();
 
 3378   int edge1 = insertEdge( -10, -10, mPointVector.count() - 1, 
false, 
false );
 
 3379   int edge2 = insertEdge( edge1, mHalfEdge[mHalfEdge[edge]->getNext()]->getNext(), mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint(), 
false, 
false );
 
 3380   int edge3 = insertEdge( -10, mHalfEdge[mHalfEdge[dualedge]->getNext()]->getNext(), mHalfEdge[mHalfEdge[dualedge]->getNext()]->getPoint(), 
false, 
false );
 
 3381   int edge4 = insertEdge( edge3, dualedge, mPointVector.count() - 1, 
false, 
false );
 
 3382   int edge5 = insertEdge( -10, mHalfEdge[edge]->getNext(), mHalfEdge[edge]->getPoint(), mHalfEdge[edge]->getBreak(), mHalfEdge[edge]->getForced() );
 
 3383   int edge6 = insertEdge( edge5, edge3, mPointVector.count() - 1, mHalfEdge[dualedge]->getBreak(), mHalfEdge[dualedge]->getForced() );
 
 3384   mHalfEdge[edge1]->setDual( edge2 );
 
 3385   mHalfEdge[edge1]->setNext( edge5 );
 
 3386   mHalfEdge[edge3]->setDual( edge4 );
 
 3387   mHalfEdge[edge5]->setDual( edge6 );
 
 3390   mHalfEdge[mHalfEdge[edge]->getNext()]->setNext( edge1 );
 
 3391   mHalfEdge[mHalfEdge[dualedge]->getNext()]->setNext( edge4 );
 
 3392   mHalfEdge[edge]->setNext( edge2 );
 
 3393   mHalfEdge[edge]->setPoint( mPointVector.count() - 1 );
 
 3394   mHalfEdge[mHalfEdge[edge3]->getNext()]->setNext( edge6 );
 
 3397   checkSwapRecursively( mHalfEdge[edge5]->getNext(), 0 );
 
 3398   checkSwapRecursively( mHalfEdge[edge2]->getNext(), 0 );
 
 3399   checkSwapRecursively( mHalfEdge[dualedge]->getNext(), 0 );
 
 3400   checkSwapRecursively( mHalfEdge[edge3]->getNext(), 0 );
 
 3404   return mPointVector.count() - 1;
 
 3407 bool QgsDualEdgeTriangulation::edgeOnConvexHull( 
int edge )
 
 3409   return ( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() == -1 || mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() == -1 );
 
 3412 void QgsDualEdgeTriangulation::evaluateInfluenceRegion( 
QgsPoint *point, 
int edge, QSet<int> &set )
 
 3414   if ( set.find( edge ) == set.end() )
 
 3423   if ( !mHalfEdge[edge]->getForced() && !edgeOnConvexHull( edge ) )
 
 3426     if ( 
inCircle( *
point, *mPointVector[mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint()], *mPointVector[mHalfEdge[edge]->getPoint()], *mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()] ) )
 
 3428       evaluateInfluenceRegion( 
point, mHalfEdge[mHalfEdge[edge]->getDual()]->getNext(), set );
 
 3429       evaluateInfluenceRegion( 
point, mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getNext(), set );
 
 3434 int QgsDualEdgeTriangulation::firstEdgeOutSide()
 
 3437   while ( ( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() != -1 ||
 
 3438             mHalfEdge[edge]->getPoint() == -1 || mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() == -1 ) &&
 
 3439           edge < mHalfEdge.count() )
 
 3444   if ( edge >= mHalfEdge.count() )
 
 3450 void QgsDualEdgeTriangulation::removeLastPoint()
 
 3452   if ( mPointVector.isEmpty() )
 
 3454   QgsPoint *p = mPointVector.takeLast();
 
bool getForced() const
Returns, whether the HalfEdge belongs to a constrained edge or not.
int getNext() const
Returns the number of the next HalfEdge.
void setNext(int n)
Sets the number of the next HalfEdge.
void setPoint(int p)
Sets the number of point at which this HalfEdge points.
int getPoint() const
Returns the number of the point at which this HalfEdge points.
int getDual() const
Returns the number of the dual HalfEdge.
void setDual(int d)
Sets the number of the dual HalfEdge.
void setForced(bool f)
Sets the forced flag.
bool getBreak() const
Returns, whether the HalfEdge belongs to a break line or not.
void setBreak(bool b)
Sets the break flag.
bool saveTriangulation(QgsFeatureSink *sink, QgsFeedback *feedback=nullptr) const override
Saves the triangulation features to a feature sink.
QgsPoint * point(int i) const override
Draws the points, edges and the forced lines.
QList< int > surroundingTriangles(int pointno) override
Returns a value list with the information of the triangles surrounding (counterclockwise) a point.
void ruppertRefinement() override
Adds points to make the triangles better shaped (algorithm of ruppert)
bool pointInside(double x, double y) override
Returns true, if the point with coordinates x and y is inside the convex hull and false otherwise.
void setTriangleInterpolator(TriangleInterpolator *interpolator) override
Sets an interpolator object.
void performConsistencyTest() override
Performs a consistency check, remove this later.
int oppositePoint(int p1, int p2) override
Returns the number of the point opposite to the triangle points p1, p2 (which have to be on a halfedg...
int addPoint(const QgsPoint &p) override
Adds a point to the triangulation.
virtual QgsMesh triangulationToMesh(QgsFeedback *feedback=nullptr) const override
Returns a QgsMesh corresponding to the triangulation.
void setForcedCrossBehavior(QgsTriangulation::ForcedCrossBehavior b) override
Sets the behavior of the triangulation in case of crossing forced lines.
bool calcNormal(double x, double y, QgsPoint &result) override
Calculates the normal at a point on the surface.
void addLine(const QVector< QgsPoint > &points, QgsInterpolator::SourceType lineType) override
Adds a line (e.g.
bool calcPoint(double x, double y, QgsPoint &result) override
Calculates x-, y and z-value of the point on the surface and assigns it to 'result'.
void eliminateHorizontalTriangles() override
Eliminates the horizontal triangles by swapping or by insertion of new points.
bool triangleVertices(double x, double y, QgsPoint &p1, int &n1, QgsPoint &p2, int &n2, QgsPoint &p3, int &n3) override
Finds out in which triangle the point with coordinates x and y is and assigns the numbers of the vert...
~QgsDualEdgeTriangulation() override
bool swapEdge(double x, double y) override
Swaps the edge which is closest to the point with x and y coordinates (if this is possible)
QList< int > pointsAroundEdge(double x, double y) override
Returns a value list with the numbers of the four points, which would be affected by an edge swap....
An interface for objects which accept features via addFeature(s) methods.
virtual bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags())
Adds a single feature to the sink.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
SourceType
Describes the type of input data.
@ SourceBreakLines
Break lines.
A class to represent a 2D point.
Point geometry type, with support for z-dimension and m-values.
double distance(double x, double y) const SIP_HOLDGIL
Returns the Cartesian 2D distance between this point and a specified x, y coordinate.
void setX(double x) SIP_HOLDGIL
Sets the point's x-coordinate.
void setY(double y) SIP_HOLDGIL
Sets the point's y-coordinate.
void setZ(double z) SIP_HOLDGIL
Sets the point's z-coordinate.
double distanceSquared(double x, double y) const SIP_HOLDGIL
Returns the Cartesian 2D squared distance between this point a specified x, y coordinate.
ForcedCrossBehavior
Enumeration describing the behavior, if two forced lines cross.
@ SnappingTypeVertex
The second inserted forced line is snapped to the closest vertice of the first inserted forced line.
This is an interface for interpolator classes for triangulations.
virtual bool calcNormVec(double x, double y, QgsPoint &result)=0
Calculates the normal vector and assigns it to vec.
virtual bool calcPoint(double x, double y, QgsPoint &result)=0
Performs a linear interpolation in a triangle and assigns the x-,y- and z-coordinates to point.
bool ANALYSIS_EXPORT inDiametral(QgsPoint *p1, QgsPoint *p2, QgsPoint *point)
Tests, whether 'point' is inside the diametral circle through 'p1' and 'p2'.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
bool ANALYSIS_EXPORT lineIntersection(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Returns true, if line1 (p1 to p2) and line2 (p3 to p4) intersect. If the lines have an endpoint in co...
bool ANALYSIS_EXPORT circumcenter(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *result)
Calculates the center of the circle passing through p1, p2 and p3. Returns true in case of success an...
double ANALYSIS_EXPORT leftOf(const QgsPoint &thepoint, const QgsPoint *p1, const QgsPoint *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'. Negative values mean left ...
double ANALYSIS_EXPORT distPointFromLine(QgsPoint *thepoint, QgsPoint *p1, QgsPoint *p2)
Calculates the (2 dimensional) distance from 'thepoint' to the line defined by p1 and p2.
bool ANALYSIS_EXPORT inCircle(QgsPoint *testp, QgsPoint *p1, QgsPoint *p2, QgsPoint *p3)
Tests, whether 'testp' is inside the circle through 'p1', 'p2' and 'p3'.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
QVector< int > QgsMeshFace
List of vertex indexes.
Mesh - vertices, edges and faces.
QVector< QgsMeshVertex > vertices
QVector< QgsMeshFace > faces