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 );
512 int QgsDualEdgeTriangulation::baseEdgeOfPoint(
int point )
514 unsigned int actedge = mEdgeInside;
516 if ( mPointVector.count() < 4 ||
point == -1 || mDimension == 1 )
518 int fromVirtualPoint = -1;
520 for (
int i = 0; i < mHalfEdge.count(); i++ )
522 if ( mHalfEdge[i]->getPoint() ==
point )
524 if ( mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() != -1 )
527 fromVirtualPoint = i;
530 return fromVirtualPoint;
538 if ( control > 1000000 )
544 for (
int i = 0; i < mHalfEdge.count(); i++ )
546 if ( mHalfEdge[i]->getPoint() ==
point && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 )
553 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();
587 int QgsDualEdgeTriangulation::baseEdgeOfTriangle(
const QgsPoint &point )
589 unsigned int actEdge = mEdgeInside;
590 if ( mHalfEdge.at( actEdge )->getPoint() < 0 )
591 actEdge = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getNext() )->getDual();
592 if ( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint() < 0 )
593 actEdge = mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getDual();
599 int firstEndPoint = 0, secEndPoint = 0, thEndPoint = 0, fouEndPoint = 0;
603 if ( runs > MAX_BASE_ITERATIONS )
609 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" ) );
782 bool QgsDualEdgeTriangulation::checkSwapRecursively(
unsigned int edge,
unsigned int recursiveDeep )
784 if ( swapPossible( edge ) )
786 QgsPoint *pta = mPointVector.at( mHalfEdge.at( edge )->getPoint() );
787 QgsPoint *ptb = mPointVector.at( mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getPoint() );
788 QgsPoint *ptc = mPointVector.at( mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getNext( ) )->getNext() )->getPoint() );
789 QgsPoint *ptd = mPointVector.at( mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext() )->getPoint() );
790 if ( inCircle( *ptd, *pta, *ptb, *ptc ) )
792 doSwapRecursively( edge, recursiveDeep );
799 bool QgsDualEdgeTriangulation::isEdgeNeedSwap(
unsigned int edge )
const
801 if ( swapPossible( edge ) )
803 QgsPoint *pta = mPointVector[mHalfEdge[edge]->getPoint()];
804 QgsPoint *ptb = mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()];
805 QgsPoint *ptc = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint()];
806 QgsPoint *ptd = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint()];
807 return inCircle( *ptd, *pta, *ptb, *ptc );
814 void QgsDualEdgeTriangulation::doOnlySwap(
unsigned int edge )
816 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() );
832 void 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 );
896 void DualEdgeTriangulation::draw( QPainter *p,
double xlowleft,
double ylowleft,
double xupright,
double yupright,
double width,
double height )
const
899 if ( mPointVector.isEmpty() )
904 p->setPen( mEdgeColor );
906 bool *control =
new bool[mHalfEdge.count()];
907 bool *control2 =
new bool[mHalfEdge.count()];
909 for (
unsigned int i = 0; i <= mHalfEdge.count() - 1; i++ )
915 if ( ( ( xupright - xlowleft ) / width ) > ( ( yupright - ylowleft ) / height ) )
917 double lowerborder = -( height * ( xupright - xlowleft ) / width - yupright );
918 for (
unsigned int i = 0; i < mHalfEdge.count() - 1; i++ )
920 if ( mHalfEdge[i]->getPoint() == -1 || mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() == -1 )
927 if ( mHalfEdge[i]->getPoint() != -1 && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 && mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint() != -1 )
929 p1 = mPointVector[mHalfEdge[i]->getPoint()]->getZ();
930 p2 = mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getZ();
931 p3 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getZ();
932 if ( p1 == p2 && p2 == p3 && halfEdgeBBoxTest( i, xlowleft, lowerborder, xupright, yupright ) && halfEdgeBBoxTest( mHalfEdge[i]->getNext(), xlowleft, lowerborder, xupright, yupright ) && halfEdgeBBoxTest( mHalfEdge[mHalfEdge[i]->getNext()]->getNext(), xlowleft, lowerborder, xupright, yupright ) )
935 pa.setPoint( 0, ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( xupright - xlowleft )*width );
936 pa.setPoint( 1, ( mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getY() ) / ( xupright - xlowleft )*width );
937 pa.setPoint( 2, ( mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getY() ) / ( xupright - xlowleft )*width );
938 QColor
c( 255, 0, 0 );
940 p->drawPolygon( pa );
945 control2[mHalfEdge[i]->getNext()] =
true;
946 control2[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()] =
true;
953 if ( halfEdgeBBoxTest( i, xlowleft, lowerborder, xupright, yupright ) )
955 if ( mHalfEdge[i]->getBreak() )
957 p->setPen( mBreakEdgeColor );
959 else if ( mHalfEdge[i]->getForced() )
961 p->setPen( mForcedEdgeColor );
965 p->drawLine( ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( xupright - xlowleft )*width, ( mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()]->getY() ) / ( xupright - xlowleft )*width );
967 if ( mHalfEdge[i]->getForced() )
969 p->setPen( mEdgeColor );
975 control[mHalfEdge[i]->getDual()] =
true;
980 double rightborder = width * ( yupright - ylowleft ) / height + xlowleft;
981 for (
unsigned int i = 0; i < mHalfEdge.count() - 1; i++ )
983 if ( mHalfEdge[i]->getPoint() == -1 || mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() == -1 )
990 if ( mHalfEdge[i]->getPoint() != -1 && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 && mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint() != -1 )
992 p1 = mPointVector[mHalfEdge[i]->getPoint()]->getZ();
993 p2 = mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getZ();
994 p3 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getZ();
995 if ( p1 == p2 && p2 == p3 && halfEdgeBBoxTest( i, xlowleft, ylowleft, rightborder, yupright ) && halfEdgeBBoxTest( mHalfEdge[i]->getNext(), xlowleft, ylowleft, rightborder, yupright ) && halfEdgeBBoxTest( mHalfEdge[mHalfEdge[i]->getNext()]->getNext(), xlowleft, ylowleft, rightborder, yupright ) )
998 pa.setPoint( 0, ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( yupright - ylowleft )*height );
999 pa.setPoint( 1, ( mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getY() ) / ( yupright - ylowleft )*height );
1000 pa.setPoint( 2, ( mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getY() ) / ( yupright - ylowleft )*height );
1001 QColor
c( 255, 0, 0 );
1003 p->drawPolygon( pa );
1008 control2[mHalfEdge[i]->getNext()] =
true;
1009 control2[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()] =
true;
1017 if ( halfEdgeBBoxTest( i, xlowleft, ylowleft, rightborder, yupright ) )
1019 if ( mHalfEdge[i]->getBreak() )
1021 p->setPen( mBreakEdgeColor );
1023 else if ( mHalfEdge[i]->getForced() )
1025 p->setPen( mForcedEdgeColor );
1028 p->drawLine( ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( yupright - ylowleft )*height, ( mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()]->getY() ) / ( yupright - ylowleft )*height );
1030 if ( mHalfEdge[i]->getForced() )
1032 p->setPen( mEdgeColor );
1037 control[mHalfEdge[i]->getDual()] =
true;
1050 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() );
1322 unsigned int QgsDualEdgeTriangulation::insertEdge(
int dual,
int next,
int point,
bool mbreak,
bool forced )
1325 mHalfEdge.append( edge );
1326 return mHalfEdge.count() - 1;
1330 static bool altitudeTriangleIsSmall(
const QgsPoint &pointBase1,
const QgsPoint &pointBase2,
const QgsPoint &pt3,
double tolerance )
1333 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;
1985 #if 0 //slow version
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 );
2157 #endif //end slow version
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 ) );
2549 bool QgsDualEdgeTriangulation::swapPossible(
unsigned int edge )
const
2552 if ( mHalfEdge[edge]->getForced() )
2558 if ( mHalfEdge[edge]->getPoint() == -1 || mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() == -1 || mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() == -1 || mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() == -1 )
2563 QgsPoint *pta = mPointVector[mHalfEdge[edge]->getPoint()];
2564 QgsPoint *ptb = mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()];
2565 QgsPoint *ptc = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint()];
2566 QgsPoint *ptd = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint()];
2586 void QgsDualEdgeTriangulation::triangulatePolygon( QList<int> *poly, QList<int> *free,
int mainedge )
2590 if ( poly->count() == 3 )
2596 QList<int>::const_iterator iterator = ++( poly->constBegin() );
2597 double distance =
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] );
2598 int distedge = ( *iterator );
2599 int nextdistedge = mHalfEdge[( *iterator )]->getNext();
2602 while ( iterator != --( poly->constEnd() ) )
2604 if (
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] ) < distance )
2606 distedge = ( *iterator );
2607 nextdistedge = mHalfEdge[( *iterator )]->getNext();
2608 distance =
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] );
2613 if ( nextdistedge == ( *( --poly->end() ) ) )
2615 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;
2800 bool DualEdgeTriangulation::readFromTAFF( QString filename )
2802 QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
2804 QFile file( filename );
2805 file.open( IO_Raw | IO_ReadOnly );
2806 QBuffer buffer( file.readAll() );
2809 QTextStream textstream( &buffer );
2810 buffer.open( IO_ReadOnly );
2813 int numberofhalfedges;
2817 while ( buff.mid( 0, 4 ) !=
"TRIA" )
2819 buff = textstream.readLine();
2821 while ( buff.mid( 0, 4 ) !=
"NEDG" )
2823 buff = textstream.readLine();
2825 numberofhalfedges = buff.section(
' ', 1, 1 ).toInt();
2826 mHalfEdge.resize( numberofhalfedges );
2829 while ( buff.mid( 0, 4 ) !=
"DATA" )
2834 int nr1, nr2, dual1, dual2, point1, point2, next1, next2, fo1, fo2, b1, b2;
2835 bool forced1, forced2, break1, break2;
2839 QProgressBar *edgebar =
new QProgressBar();
2840 edgebar->setCaption( tr(
"Reading edges…" ) );
2841 edgebar->setTotalSteps( numberofhalfedges / 2 );
2842 edgebar->setMinimumWidth( 400 );
2843 edgebar->move( 500, 500 );
2846 for (
int i = 0; i < numberofhalfedges / 2; i++ )
2848 if ( i % 1000 == 0 )
2850 edgebar->setProgress( i );
2854 textstream >> point1;
2855 textstream >> next1;
2879 textstream >> point2;
2880 textstream >> next2;
2918 mHalfEdge.insert( nr1, hf1 );
2919 mHalfEdge.insert( nr2, hf2 );
2923 edgebar->setProgress( numberofhalfedges / 2 );
2927 for (
int i = 0; i < numberofhalfedges; i++ )
2930 a = mHalfEdge[i]->getPoint();
2931 b = mHalfEdge[mHalfEdge[i]->getDual()]->getPoint();
2932 c = mHalfEdge[mHalfEdge[i]->getNext()]->getPoint();
2933 d = mHalfEdge[mHalfEdge[mHalfEdge[i]->getDual()]->getNext()]->getPoint();
2934 if ( a != -1 && b != -1 &&
c != -1 && d != -1 )
2942 while ( buff.mid( 0, 4 ) !=
"POIN" )
2944 buff = textstream.readLine();
2947 while ( buff.mid( 0, 4 ) !=
"NPTS" )
2949 buff = textstream.readLine();
2952 numberofpoints = buff.section(
' ', 1, 1 ).toInt();
2953 mPointVector.resize( numberofpoints );
2955 while ( buff.mid( 0, 4 ) !=
"DATA" )
2960 QProgressBar *pointbar =
new QProgressBar();
2961 pointbar->setCaption( tr(
"Reading points…" ) );
2962 pointbar->setTotalSteps( numberofpoints );
2963 pointbar->setMinimumWidth( 400 );
2964 pointbar->move( 500, 500 );
2969 for (
int i = 0; i < numberofpoints; i++ )
2971 if ( i % 1000 == 0 )
2973 pointbar->setProgress( i );
2983 mPointVector.insert( i, p );
2999 else if ( x > xMax )
3008 else if ( y > yMax )
3015 pointbar->setProgress( numberofpoints );
3017 QApplication::restoreOverrideCursor();
3021 bool DualEdgeTriangulation::saveToTAFF( QString filename )
const
3023 QFile outputfile( filename );
3024 if ( !outputfile.open( IO_WriteOnly ) )
3026 QMessageBox::warning( 0, tr(
"Warning" ), tr(
"File could not be written." ), QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton );
3030 QTextStream outstream( &outputfile );
3031 outstream.precision( 9 );
3034 outstream <<
"TRIA" << std::endl << std::flush;
3035 outstream <<
"NEDG " << mHalfEdge.count() << std::endl << std::flush;
3036 outstream <<
"PANO 1" << std::endl << std::flush;
3037 outstream <<
"DATA ";
3039 bool *cont =
new bool[mHalfEdge.count()];
3040 for (
unsigned int i = 0; i <= mHalfEdge.count() - 1; i++ )
3045 for (
unsigned int i = 0; i < mHalfEdge.count(); i++ )
3052 int dual = mHalfEdge[i]->getDual();
3053 outstream << i <<
" " << mHalfEdge[i]->getPoint() <<
" " << mHalfEdge[i]->getNext() <<
" " << mHalfEdge[i]->getForced() <<
" " << mHalfEdge[i]->getBreak() <<
" ";
3054 outstream << dual <<
" " << mHalfEdge[dual]->getPoint() <<
" " << mHalfEdge[dual]->getNext() <<
" " << mHalfEdge[dual]->getForced() <<
" " << mHalfEdge[dual]->getBreak() <<
" ";
3058 outstream << std::endl << std::flush;
3059 outstream << std::endl << std::flush;
3064 outstream <<
"POIN" << std::endl << std::flush;
3065 outstream <<
"NPTS " << getNumberOfPoints() << std::endl << std::flush;
3066 outstream <<
"PATT 3" << std::endl << std::flush;
3067 outstream <<
"DATA ";
3069 for (
int i = 0; i < getNumberOfPoints(); i++ )
3072 outstream << p->getX() <<
" " << p->getY() <<
" " << p->getZ() <<
" ";
3074 outstream << std::endl << std::flush;
3075 outstream << std::endl << std::flush;
3084 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 ) ;
3310 double 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 )
3350 int 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;
3405 bool QgsDualEdgeTriangulation::edgeOnConvexHull(
int edge )
3407 return ( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() == -1 || mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() == -1 );
3410 void 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 );
3432 int 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() )
3448 void QgsDualEdgeTriangulation::removeLastPoint()
3450 if ( mPointVector.isEmpty() )
3452 QgsPoint *p = mPointVector.takeLast();