30  const double x2 = point2.
x() - point1.
x();
 
   31  const double y2 = point2.
y() - point1.
y();
 
   32  const double x3 = point3.
x() - point1.
x();
 
   33  const double y3 = point3.
y() - point1.
y();
 
   35  const double denom = x2 * y3 - y2 * x3;
 
   41  frac = ( x2 * ( x2 - x3 ) + y2 * ( y2 - y3 ) ) / denom;
 
   42  const double cx = ( x3 + frac * y3 ) / 2;
 
   43  const double cy = ( y3 - frac * x3 ) / 2;
 
   44  const double squaredRadius = ( cx * cx + cy * cy );
 
   45  const 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    const int a = mHalfEdge[mHalfEdge[i]->getDual()]->getDual();
 
   78    const 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    const unsigned int zedge  = insertEdge( -10, -10, -1, 
false, 
false ); 
 
  148    const 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    const unsigned int edgeFromPoint0ToPoint1  = insertEdge( -10, -10, 1, 
false, 
false );
 
  164    const unsigned int edgeFromPoint1ToPoint0  = insertEdge( edgeFromPoint0ToPoint1, -10, 0, 
false, 
false ); 
 
  165    const unsigned int edgeFromVirtualToPoint1Side1  = insertEdge( -10, -10, 1, 
false, 
false ); 
 
  166    const unsigned int edgeFromPoint1ToVirtualSide1  = insertEdge( edgeFromVirtualToPoint1Side1, 1, -1, 
false, 
false ); 
 
  167    const unsigned int edgeFromVirtualToPoint1Side2  = insertEdge( -10, edgeFromPoint1ToPoint0, 1, 
false, 
false );
 
  168    const unsigned int edgeFromPoint1ToVirtualSide2  = insertEdge( edgeFromVirtualToPoint1Side2, edgeFromVirtualToPoint1Side1, -1, 
false, 
false );
 
  169    const unsigned int edgeFromVirtualToPoint0Side2  = insertEdge( -10, -10, 0, 
false, 
false );
 
  170    const 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    const 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      const int firstEdge = mEdgeOutside;
 
  203        const int point1 = mHalfEdge[mEdgeOutside]->getPoint();
 
  204        const int point2 = mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint();
 
  205        const double distance1 = p.
distance( *mPointVector[point1] );
 
  211        const double distance2 = p.
distance( *mPointVector[point2] );
 
  218        const double edgeLength = mPointVector[point1]->distance( *mPointVector[point2] );
 
  220        if ( distance1 < edgeLength && distance2 < edgeLength )
 
  223          const int newPoint = mPointVector.count() - 1;
 
  226          const int edgeFromNewPointToPoint1 = mEdgeOutside;
 
  227          const int edgeFromNewPointToPoint2 = mHalfEdge[mEdgeOutside]->getDual();
 
  229          const int edgeFromPoint1ToVirtualSide2 = mHalfEdge[edgeFromNewPointToPoint1]->getNext();
 
  230          const int edgeFromVirtualToPoint1Side1 = mHalfEdge[mHalfEdge[edgeFromNewPointToPoint2]->getNext()]->getNext();
 
  231          const int edgeFromPoint2ToVirtualSide1 = mHalfEdge[edgeFromNewPointToPoint2]->getNext();
 
  232          const int edgeFromVirtualToPoint2Side2 = mHalfEdge[mHalfEdge[edgeFromNewPointToPoint1]->getNext()]->getNext();
 
  234          const int edgeFromVirtualToNewPointSide1 = insertEdge( -10, edgeFromNewPointToPoint2, newPoint, 
false, 
false );
 
  235          const int edgeFromNewPointToVirtualSide1 = insertEdge( edgeFromVirtualToNewPointSide1, edgeFromVirtualToPoint1Side1, -1, 
false, 
false );
 
  236          const int edgeFromVirtualToNewPointSide2 = insertEdge( -10, edgeFromNewPointToPoint1, newPoint, 
false, 
false );
 
  237          const int edgeFromNewPointToVirtualSide2 = insertEdge( edgeFromVirtualToNewPointSide2, edgeFromVirtualToPoint2Side2, -1, 
false, 
false );
 
  238          const int edgeFromPoint1ToNewPoint = insertEdge( edgeFromNewPointToPoint1, edgeFromNewPointToVirtualSide1, newPoint, 
false, 
false );
 
  239          const 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      const int extremPoint = mHalfEdge[closestEdge]->getPoint();
 
  273      const int newPoint = mPointVector.count() - 1;
 
  275      const int edgeFromExtremeToOpposite = mHalfEdge[closestEdge]->getDual();
 
  277      const int edgeFromVirtualToExtremeSide1 = mHalfEdge[mHalfEdge[closestEdge]->getNext()]->getDual();
 
  278      const int edgeFromVirtualToExtremeSide2 = mHalfEdge[mHalfEdge[mHalfEdge[closestEdge]->getDual()]->getNext()]->getNext();
 
  279      const int edgeFromExtremeToVirtualSide2 = mHalfEdge[edgeFromVirtualToExtremeSide2]->getDual();
 
  281      const int edgeFromExtremeToNewPoint = insertEdge( -10, -10, newPoint, 
false, 
false );
 
  282      const int edgeFromNewPointToExtrem = insertEdge( edgeFromExtremeToNewPoint, edgeFromExtremeToVirtualSide2, extremPoint, 
false, 
false );
 
  283      const int edgeFromNewPointToVirtualSide1 = insertEdge( -10, edgeFromVirtualToExtremeSide1, -1, 
false, 
false );
 
  284      const int edgeFromVirtualToNewPointSide1 = insertEdge( edgeFromNewPointToVirtualSide1, -10, newPoint, 
false, 
false );
 
  285      const int edgeFromNewPointToVirtualSide2 = insertEdge( -10, edgeFromVirtualToNewPointSide1, -1, 
false, 
false );
 
  286      const 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    const 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    const int edgeFromLastCwPointToVirtualPoint = mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext();
 
  316    const int edgeFromLastCwPointToNewPointPoint = mHalfEdge[ cwEdge ]->getNext();
 
  317    const int edgeFromNewPointPointToLastCwPoint = mHalfEdge[ edgeFromLastCwPointToNewPointPoint ]->getDual();
 
  319    const int edgeFromNewPointtoVirtualPoint = insertEdge( -10, -10, -1, 
false, 
false );
 
  320    const 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    const int edgeToLastCcwPoint = mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getNext()]->getDual();
 
  334    const int edgeFromLastCcwPointToNewPoint = mHalfEdge[edgeToLastCcwPoint]->getNext();
 
  335    mHalfEdge.at( edgeFromNewPointtoVirtualPoint )->setNext( edgeToLastCcwPoint );
 
  336    mHalfEdge.at( edgeFromLastCcwPointToNewPoint )->setNext( edgeFromNewPointtoVirtualPoint );
 
  337    mHalfEdge.at( edgeFromLastCcwPointToNewPoint )->setPoint( newPoint );
 
  341    const 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      const unsigned int edge1 = insertEdge( mHalfEdge[cwEdge]->getNext(), -10, mHalfEdge[cwEdge]->getPoint(), 
false, 
false );
 
  364      const unsigned int edge2 = insertEdge( mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual(), -10, -1, 
false, 
false );
 
  365      const 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      const unsigned int edge4 = insertEdge( mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext(), -10, mPointVector.count() - 1, 
false, 
false );
 
  384      const unsigned int edge5 = insertEdge( edge3, -10, -1, 
false, 
false );
 
  385      const 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      const int nextnumber = mHalfEdge[number]->getNext();
 
  413      const int nextnextnumber = mHalfEdge[mHalfEdge[number]->getNext()]->getNext();
 
  416      const unsigned int edge1 = insertEdge( -10, nextnumber, mHalfEdge[number]->getPoint(), 
false, 
false );
 
  417      const unsigned int edge2 = insertEdge( 
static_cast<int>( edge1 ), -10, mPointVector.count() - 1, 
false, 
false );
 
  418      const unsigned int edge3 = insertEdge( -10, nextnextnumber, mHalfEdge[nextnumber]->getPoint(), 
false, 
false );
 
  419      const unsigned int edge4 = insertEdge( 
static_cast<int>( edge3 ), 
static_cast<int>( edge1 ), mPointVector.count() - 1, 
false, 
false );
 
  420      const unsigned int edge5 = insertEdge( -10, number, mHalfEdge[nextnextnumber]->getPoint(), 
false, 
false );
 
  421      const 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      const int point1 = mHalfEdge[mEdgeWithPoint]->getPoint();
 
  444      const int point2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getDual()]->getPoint();
 
  445      const double distance1 = p.
distance( *mPointVector[point1] );
 
  451      const double distance2 = p.
distance( *mPointVector[point2] );
 
  458      const int edgea = mEdgeWithPoint;
 
  459      const int edgeb = mHalfEdge[mEdgeWithPoint]->getDual();
 
  460      const int edgec = mHalfEdge[edgea]->getNext();
 
  461      const int edged = mHalfEdge[edgec]->getNext();
 
  462      const int edgee = mHalfEdge[edgeb]->getNext();
 
  463      const int edgef = mHalfEdge[edgee]->getNext();
 
  466      const int nedge1 = insertEdge( -10, mHalfEdge[edgea]->getNext(), mHalfEdge[edgea]->getPoint(), 
false, 
false );
 
  467      const int nedge2 = insertEdge( nedge1, -10, mPointVector.count() - 1, 
false, 
false );
 
  468      const int nedge3 = insertEdge( -10, edged, mHalfEdge[edgec]->getPoint(), 
false, 
false );
 
  469      const int nedge4 = insertEdge( nedge3, nedge1, mPointVector.count() - 1, 
false, 
false );
 
  470      const int nedge5 = insertEdge( -10, edgef, mHalfEdge[edgee]->getPoint(), 
false, 
false );
 
  471      const 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 );
 
  512int 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    const int fromPoint = mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint();
 
  554    const 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    const 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();
 
  587int 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    const 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  const double x1 = mPointVector.at( nr1 )->x();
 
  700  const double y1 = mPointVector.at( nr1 )->y();
 
  701  const double x2 = mPointVector.at( nr2 )->x();
 
  702  const double y2 = mPointVector.at( nr2 )->y();
 
  703  const double x3 = mPointVector.at( nr3 )->x();
 
  704  const 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" ) );
 
  782bool 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 );
 
  799bool 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 );
 
  814void QgsDualEdgeTriangulation::doOnlySwap( 
unsigned int edge )
 
  816  const unsigned int edge1 = edge;
 
  817  const unsigned int edge2 = mHalfEdge[edge]->getDual();
 
  818  const unsigned int edge3 = mHalfEdge[edge]->getNext();
 
  819  const unsigned int edge4 = mHalfEdge[mHalfEdge[edge]->getNext()]->getNext();
 
  820  const unsigned int edge5 = mHalfEdge[mHalfEdge[edge]->getDual()]->getNext();
 
  821  const 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() );
 
  832void QgsDualEdgeTriangulation::doSwapRecursively( 
unsigned int edge, 
unsigned int recursiveDeep )
 
  834  const unsigned int edge1 = edge;
 
  835  const unsigned int edge2 = mHalfEdge.at( edge )->getDual();
 
  836  const unsigned int edge3 = mHalfEdge.at( edge )->getNext();
 
  837  const unsigned int edge4 = mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getNext();
 
  838  const unsigned int edge5 = mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext();
 
  839  const 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      const unsigned int e1 = edgesToSwap.pop();
 
  869      if ( isEdgeNeedSwap( e1 ) )
 
  871        const unsigned int e2 = mHalfEdge.at( e1 )->getDual();
 
  872        const unsigned int e3 = mHalfEdge.at( e1 )->getNext();
 
  873        const unsigned int e4 = mHalfEdge.at( mHalfEdge.at( e1 )->getNext() )->getNext();
 
  874        const unsigned int e5 = mHalfEdge.at( mHalfEdge.at( e1 )->getDual() )->getNext();
 
  875        const 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 );
 
  896void 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  const 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  const 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  const int edge = baseEdgeOfTriangle( 
point );
 
 1130  else if ( edge >= 0 )
 
 1132    const int ptnr1 = mHalfEdge[edge]->getPoint();
 
 1133    const int ptnr2 = mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint();
 
 1134    const 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    const int ptnr1 = mHalfEdge[mEdgeWithPoint]->getPoint();
 
 1152    const int ptnr2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getPoint();
 
 1153    const 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    const int edge1 = baseEdgeOfPoint( mTwiceInsPoint );
 
 1175    const int edge2 = mHalfEdge[edge1]->getNext();
 
 1176    const int edge3 = mHalfEdge[edge2]->getNext();
 
 1177    const int ptnr1 = mHalfEdge[edge1]->getPoint();
 
 1178    const int ptnr2 = mHalfEdge[edge2]->getPoint();
 
 1179    const 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    const int ptnr1 = mHalfEdge[mUnstableEdge]->getPoint();
 
 1197    const int ptnr2 = mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getPoint();
 
 1198    const 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  const int edge = baseEdgeOfTriangle( 
point );
 
 1237  else if ( edge >= 0 )
 
 1239    const int ptnr1 = mHalfEdge[edge]->getPoint();
 
 1240    const int ptnr2 = mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint();
 
 1241    const 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    const int ptnr1 = mHalfEdge[mEdgeWithPoint]->getPoint();
 
 1256    const int ptnr2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getPoint();
 
 1257    const 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    const int edge1 = baseEdgeOfPoint( mTwiceInsPoint );
 
 1276    const int edge2 = mHalfEdge[edge1]->getNext();
 
 1277    const int edge3 = mHalfEdge[edge2]->getNext();
 
 1278    const int ptnr1 = mHalfEdge[edge1]->getPoint();
 
 1279    const int ptnr2 = mHalfEdge[edge2]->getPoint();
 
 1280    const 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    const int ptnr1 = mHalfEdge[mUnstableEdge]->getPoint();
 
 1299    const int ptnr2 = mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getPoint();
 
 1300    const 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() );
 
 1322unsigned int QgsDualEdgeTriangulation::insertEdge( 
int dual, 
int next, 
int point, 
bool mbreak, 
bool forced )
 
 1325  mHalfEdge.append( edge );
 
 1326  return mHalfEdge.count() - 1;
 
 1330static bool altitudeTriangleIsSmall( 
const QgsPoint &pointBase1, 
const QgsPoint &pointBase2, 
const QgsPoint &pt3, 
double tolerance )
 
 1333  const double x1 = pointBase1.
x();
 
 1334  const double y1 = pointBase1.
y();
 
 1335  const double x2 = pointBase2.
x();
 
 1336  const double y2 = pointBase2.
y();
 
 1337  const double X = pt3.
x();
 
 1338  const double Y = pt3.
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  const 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      const int a = insertForcedSegment( mHalfEdge[actEdge]->getPoint(), p2, segmentType );
 
 1423    const 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        const 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        const 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          const int e = insertForcedSegment( p3, p2, segmentType );
 
 1460        else if ( distb <= dista )
 
 1462          insertForcedSegment( p1, p4, segmentType );
 
 1463          const int e = insertForcedSegment( p4, p2, segmentType );
 
 1472        p3 = mHalfEdge[mHalfEdge[actEdge]->getNext()]->getPoint();
 
 1473        p4 = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getDual()]->getPoint();
 
 1475        const 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        const 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        const float frac = distpart / disttot;
 
 1479        if ( frac == 0 || frac == 1 )
 
 1484            mHalfEdge[actEdge]->setForced( 
true );
 
 1486            mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced( 
true );
 
 1488            const int a = insertForcedSegment( p4, p2, segmentType );
 
 1491          else if ( frac == 1 )
 
 1494            mHalfEdge[actEdge]->setForced( 
true );
 
 1496            mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced( 
true );
 
 1500              const int a = insertForcedSegment( p3, p2, segmentType );
 
 1512          const int newpoint = splitHalfEdge( mHalfEdge[actEdge]->getNext(), frac );
 
 1513          insertForcedSegment( p1, newpoint, segmentType );
 
 1514          const 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        const 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        const 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          const int e = insertForcedSegment( p3, p2, segmentType );
 
 1556        else if ( distb <= dista )
 
 1558          insertForcedSegment( p1, p4, segmentType );
 
 1559          const 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        const 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        const 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        const float frac = distpart / disttot;
 
 1573        if ( frac == 0 || frac == 1 )
 
 1577        const int newpoint = splitHalfEdge( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext(), frac );
 
 1578        insertForcedSegment( p1, newpoint, segmentType );
 
 1579        const 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        const 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        const 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          const int e = insertForcedSegment( p3, p2, segmentType );
 
 1603        else if ( distb <= dista )
 
 1605          insertForcedSegment( p1, p4, segmentType );
 
 1606          const 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        const 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        const 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        const float frac = distpart / disttot;
 
 1620        if ( frac == 0 || frac == 1 )
 
 1624        const int newpoint = splitHalfEdge( mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext(), frac );
 
 1625        insertForcedSegment( p1, newpoint, segmentType );
 
 1626        const 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  const int firstedge = freelist.first();
 
 1667  mHalfEdge[firstedge]->setForced( 
true );
 
 1669  leftPolygon.append( firstedge );
 
 1670  const 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    const int newpoint = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[( *leftiter )]->getDual()]->getNext()]->getNext()]->getPoint();
 
 1684    if ( newpoint != actpointl )
 
 1687      actpointl = newpoint;
 
 1688      const 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    const int newpoint = mHalfEdge[mHalfEdge[mHalfEdge[( *rightiter )]->getNext()]->getNext()]->getPoint();
 
 1705    if ( newpoint != actpointr )
 
 1708      actpointr = newpoint;
 
 1709      const 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  const 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 );
 
 1862  const double mintol = 17;
 
 1865  std::map<int, double> edge_angle;
 
 1866  std::multimap<double, int> angle_edge;
 
 1867  QSet<int> dontexamine;
 
 1876    const int nhalfedges = mHalfEdge.count();
 
 1878    for ( 
int i = 0; i < nhalfedges - 1; i++ )
 
 1880      const int next = mHalfEdge[i]->getNext();
 
 1881      const 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            const 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        const int pointno = splitHalfEdge( *it, 0.5 );
 
 2206        const 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          const 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              const 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          const 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              const 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          const 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              const 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      const 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        const 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            const 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        const 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            const 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        const 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            const 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 ) );
 
 2549bool 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()];
 
 2586void 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      const int inserta = free->first();
 
 2616      const 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      const int inserta = free->first();
 
 2647      const 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      const int inserta = free->first();
 
 2673      const int insertb = mHalfEdge[inserta]->getDual();
 
 2676      const int insertc = free->first();
 
 2677      const 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;
 
 2800bool 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();
 
 3021bool 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  const 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;
 
 3268  QVector< bool> edgeToTreat( mHalfEdge.count(), 
true );
 
 3269  QHash<HalfEdge *, int > edgesHash;
 
 3270  for ( 
int i = 0; i < mHalfEdge.count(); ++i )
 
 3272    edgesHash.insert( mHalfEdge[i], i );
 
 3281  const int edgeCount = edgeToTreat.count();
 
 3282  for ( 
int i = 0 ; i < edgeCount; ++i )
 
 3284    bool containVirtualPoint = 
false;
 
 3285    if ( edgeToTreat[i] )
 
 3287      HalfEdge *currentEdge = mHalfEdge[i];
 
 3292        edgeToTreat[edgesHash.value( currentEdge )] = 
false;
 
 3293        face.append( currentEdge->
getPoint() );
 
 3294        containVirtualPoint |= currentEdge->
getPoint() == -1;
 
 3295        currentEdge = mHalfEdge.at( currentEdge->
getNext() );
 
 3297      while ( currentEdge != firstEdge && !containVirtualPoint && ( !feedback || !feedback->
isCanceled() ) );
 
 3298      if ( !containVirtualPoint )
 
 3299        mesh.
faces.append( face );
 
 3303      feedback->
setProgress( ( 100 *  i ) / edgeCount ) ;
 
 3310double QgsDualEdgeTriangulation::swapMinAngle( 
int edge )
 const 
 3313  QgsPoint *p2 = 
point( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() );
 
 3314  QgsPoint *p3 = 
point( mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() );
 
 3315  QgsPoint *p4 = 
point( mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() );
 
 3322  if ( angle2 < minangle )
 
 3327  if ( angle3 < minangle )
 
 3332  if ( angle4 < minangle )
 
 3337  if ( angle5 < minangle )
 
 3342  if ( angle6 < minangle )
 
 3350int QgsDualEdgeTriangulation::splitHalfEdge( 
int edge, 
float position )
 
 3353  if ( position < 0 || position > 1 )
 
 3355    QgsDebugMsg( QStringLiteral( 
"warning, position is not between 0 and 1" ) );
 
 3359  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 );
 
 3364  p->
setZ( zvaluepoint.z() );
 
 3367  if ( mPointVector.count() >= mPointVector.size() )
 
 3369    mPointVector.resize( mPointVector.count() + 1 );
 
 3371  QgsDebugMsg( QStringLiteral( 
"inserting point nr. %1, %2//%3//%4" ).arg( mPointVector.count() ).arg( p->
x() ).arg( p->
y() ).arg( p->
z() ) );
 
 3372  mPointVector.insert( mPointVector.count(), p );
 
 3375  const int dualedge = mHalfEdge[edge]->getDual();
 
 3376  const int edge1 = insertEdge( -10, -10, mPointVector.count() - 1, 
false, 
false );
 
 3377  const int edge2 = insertEdge( edge1, mHalfEdge[mHalfEdge[edge]->getNext()]->getNext(), mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint(), 
false, 
false );
 
 3378  const int edge3 = insertEdge( -10, mHalfEdge[mHalfEdge[dualedge]->getNext()]->getNext(), mHalfEdge[mHalfEdge[dualedge]->getNext()]->getPoint(), 
false, 
false );
 
 3379  const int edge4 = insertEdge( edge3, dualedge, mPointVector.count() - 1, 
false, 
false );
 
 3380  const int edge5 = insertEdge( -10, mHalfEdge[edge]->getNext(), mHalfEdge[edge]->getPoint(), mHalfEdge[edge]->getBreak(), mHalfEdge[edge]->getForced() );
 
 3381  const int edge6 = insertEdge( edge5, edge3, mPointVector.count() - 1, mHalfEdge[dualedge]->getBreak(), mHalfEdge[dualedge]->getForced() );
 
 3382  mHalfEdge[edge1]->setDual( edge2 );
 
 3383  mHalfEdge[edge1]->setNext( edge5 );
 
 3384  mHalfEdge[edge3]->setDual( edge4 );
 
 3385  mHalfEdge[edge5]->setDual( edge6 );
 
 3388  mHalfEdge[mHalfEdge[edge]->getNext()]->setNext( edge1 );
 
 3389  mHalfEdge[mHalfEdge[dualedge]->getNext()]->setNext( edge4 );
 
 3390  mHalfEdge[edge]->setNext( edge2 );
 
 3391  mHalfEdge[edge]->setPoint( mPointVector.count() - 1 );
 
 3392  mHalfEdge[mHalfEdge[edge3]->getNext()]->setNext( edge6 );
 
 3395  checkSwapRecursively( mHalfEdge[edge5]->getNext(), 0 );
 
 3396  checkSwapRecursively( mHalfEdge[edge2]->getNext(), 0 );
 
 3397  checkSwapRecursively( mHalfEdge[dualedge]->getNext(), 0 );
 
 3398  checkSwapRecursively( mHalfEdge[edge3]->getNext(), 0 );
 
 3402  return mPointVector.count() - 1;
 
 3405bool QgsDualEdgeTriangulation::edgeOnConvexHull( 
int edge )
 
 3407  return ( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() == -1 || mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() == -1 );
 
 3410void QgsDualEdgeTriangulation::evaluateInfluenceRegion( 
QgsPoint *point, 
int edge, QSet<int> &set )
 
 3412  if ( set.find( edge ) == set.end() )
 
 3421  if ( !mHalfEdge[edge]->getForced() && !edgeOnConvexHull( edge ) )
 
 3424    if ( 
inCircle( *
point, *mPointVector[mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint()], *mPointVector[mHalfEdge[edge]->getPoint()], *mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()] ) )
 
 3426      evaluateInfluenceRegion( 
point, mHalfEdge[mHalfEdge[edge]->getDual()]->getNext(), set );
 
 3427      evaluateInfluenceRegion( 
point, mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getNext(), set );
 
 3432int QgsDualEdgeTriangulation::firstEdgeOutSide()
 
 3435  while ( ( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() != -1 ||
 
 3436            mHalfEdge[edge]->getPoint() == -1 || mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() == -1 ) &&
 
 3437          edge < mHalfEdge.count() )
 
 3442  if ( edge >= mHalfEdge.count() )
 
 3448void QgsDualEdgeTriangulation::removeLastPoint()
 
 3450  if ( mPointVector.isEmpty() )
 
 3452  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