33 const double x2 = point2.
x() - point1.
x();
34 const double y2 = point2.
y() - point1.
y();
35 const double x3 = point3.
x() - point1.
x();
36 const double y3 = point3.
y() - point1.
y();
38 const double denom = x2 * y3 - y2 * x3;
44 frac = ( x2 * ( x2 - x3 ) + y2 * ( y2 - y3 ) ) / denom;
45 const double cx = ( x3 + frac * y3 ) / 2;
46 const double cy = ( y3 - frac * x3 ) / 2;
47 const double squaredRadius = ( cx * cx + cy * cy );
48 const QgsPoint center( cx + point1.
x(), cy + point1.
y() );
55 qDeleteAll( mPointVector );
56 qDeleteAll( mHalfEdge );
63 for (
int i = 0; i < mHalfEdge.count(); i++ )
65 const int a = mHalfEdge[mHalfEdge[i]->getDual()]->getDual();
66 const int b = mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getNext();
69 QgsDebugError( QStringLiteral(
"warning, first test failed" ) );
73 QgsDebugError( QStringLiteral(
"warning, second test failed" ) );
82 int currentpoint = -10;
89 if ( actpoint != -100 )
95 if ( actpoint == -100 )
100 for ( ; i < points.size(); ++i )
102 currentpoint =
addPoint( points.at( i ) );
103 if ( currentpoint != -100 && actpoint != -100 && currentpoint != actpoint )
105 insertForcedSegment( actpoint, currentpoint, lineType );
107 actpoint = currentpoint;
114 if ( mPointVector.isEmpty() )
123 mXMin = std::min( p.
x(), mXMin );
124 mXMax = std::max( p.
x(), mXMax );
125 mYMin = std::min( p.
y(), mYMin );
126 mYMax = std::max( p.
y(), mYMax );
130 mPointVector.append(
new QgsPoint( p ) );
133 if ( mDimension == -1 )
135 const unsigned int zedge = insertEdge( -10, -10, -1,
false,
false );
136 const unsigned int fedge = insertEdge(
static_cast<int>( zedge ),
static_cast<int>( zedge ), 0,
false,
false );
137 ( mHalfEdge.at( zedge ) )->setDual(
static_cast<int>( fedge ) );
138 ( mHalfEdge.at( zedge ) )->setNext(
static_cast<int>( fedge ) );
141 else if ( mDimension == 0 )
144 if ( p.
x() == mPointVector[0]->x() && p.
y() == mPointVector[0]->y() )
151 const unsigned int edgeFromPoint0ToPoint1 = insertEdge( -10, -10, 1,
false,
false );
152 const unsigned int edgeFromPoint1ToPoint0 = insertEdge( edgeFromPoint0ToPoint1, -10, 0,
false,
false );
153 const unsigned int edgeFromVirtualToPoint1Side1 = insertEdge( -10, -10, 1,
false,
false );
154 const unsigned int edgeFromPoint1ToVirtualSide1 = insertEdge( edgeFromVirtualToPoint1Side1, 1, -1,
false,
false );
155 const unsigned int edgeFromVirtualToPoint1Side2 = insertEdge( -10, edgeFromPoint1ToPoint0, 1,
false,
false );
156 const unsigned int edgeFromPoint1ToVirtualSide2 = insertEdge( edgeFromVirtualToPoint1Side2, edgeFromVirtualToPoint1Side1, -1,
false,
false );
157 const unsigned int edgeFromVirtualToPoint0Side2 = insertEdge( -10, -10, 0,
false,
false );
158 const unsigned int edgeFromPoint0ToVirtualSide2 = insertEdge( edgeFromVirtualToPoint0Side2, edgeFromVirtualToPoint1Side2, -1,
false,
false );
159 mHalfEdge.at( edgeFromPoint1ToPoint0 )->setNext( edgeFromPoint0ToVirtualSide2 );
160 mHalfEdge.at( edgeFromPoint0ToPoint1 )->setDual( edgeFromPoint1ToPoint0 );
161 mHalfEdge.at( edgeFromPoint0ToPoint1 )->setNext( edgeFromPoint1ToVirtualSide1 );
162 mHalfEdge.at( edgeFromVirtualToPoint1Side1 )->setDual( edgeFromPoint1ToVirtualSide1 );
163 mHalfEdge.at( edgeFromVirtualToPoint1Side1 )->setNext( edgeFromPoint1ToVirtualSide2 );
164 mHalfEdge.at( 0 )->setNext(
static_cast<int>( edgeFromVirtualToPoint0Side2 ) );
165 mHalfEdge.at( 1 )->setNext(
static_cast<int>( edgeFromPoint0ToPoint1 ) );
166 mHalfEdge.at( edgeFromVirtualToPoint1Side2 )->setDual( edgeFromPoint1ToVirtualSide2 );
167 mHalfEdge.at( edgeFromVirtualToPoint0Side2 )->setDual( edgeFromPoint0ToVirtualSide2 );
168 mHalfEdge.at( edgeFromVirtualToPoint0Side2 )->setNext( 0 );
170 mEdgeOutside = edgeFromPoint0ToPoint1;
173 else if ( mDimension == 1 )
175 if ( mEdgeOutside < 0 || mHalfEdge[mEdgeOutside]->getPoint() < 0 || mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint() < 0 )
176 mEdgeOutside = firstEdgeOutSide();
177 if ( mEdgeOutside < 0 || mHalfEdge[mEdgeOutside]->getPoint() < 0 || mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint() < 0 )
180 const double leftOfNumber =
MathUtils::leftOf( p, mPointVector[mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint()], mPointVector[mHalfEdge[mEdgeOutside]->getPoint()] );
186 int closestEdge = -1;
187 double distance = std::numeric_limits<double>::max();
188 const int firstEdge = mEdgeOutside;
191 const int point1 = mHalfEdge[mEdgeOutside]->getPoint();
192 const int point2 = mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint();
193 const double distance1 = p.
distance( *mPointVector[point1] );
199 const double distance2 = p.
distance( *mPointVector[point2] );
206 const double edgeLength = mPointVector[point1]->distance( *mPointVector[point2] );
208 if ( distance1 < edgeLength && distance2 < edgeLength )
211 const int newPoint = mPointVector.count() - 1;
214 const int edgeFromNewPointToPoint1 = mEdgeOutside;
215 const int edgeFromNewPointToPoint2 = mHalfEdge[mEdgeOutside]->getDual();
217 const int edgeFromPoint1ToVirtualSide2 = mHalfEdge[edgeFromNewPointToPoint1]->getNext();
218 const int edgeFromVirtualToPoint1Side1 = mHalfEdge[mHalfEdge[edgeFromNewPointToPoint2]->getNext()]->getNext();
219 const int edgeFromPoint2ToVirtualSide1 = mHalfEdge[edgeFromNewPointToPoint2]->getNext();
220 const int edgeFromVirtualToPoint2Side2 = mHalfEdge[mHalfEdge[edgeFromNewPointToPoint1]->getNext()]->getNext();
222 const int edgeFromVirtualToNewPointSide1 = insertEdge( -10, edgeFromNewPointToPoint2, newPoint,
false,
false );
223 const int edgeFromNewPointToVirtualSide1 = insertEdge( edgeFromVirtualToNewPointSide1, edgeFromVirtualToPoint1Side1, -1,
false,
false );
224 const int edgeFromVirtualToNewPointSide2 = insertEdge( -10, edgeFromNewPointToPoint1, newPoint,
false,
false );
225 const int edgeFromNewPointToVirtualSide2 = insertEdge( edgeFromVirtualToNewPointSide2, edgeFromVirtualToPoint2Side2, -1,
false,
false );
226 const int edgeFromPoint1ToNewPoint = insertEdge( edgeFromNewPointToPoint1, edgeFromNewPointToVirtualSide1, newPoint,
false,
false );
227 const int edgeFromPoint2ToNewPoint = insertEdge( edgeFromNewPointToPoint2, edgeFromNewPointToVirtualSide2, newPoint,
false,
false );
228 mHalfEdge.at( edgeFromVirtualToNewPointSide1 )->setDual( edgeFromNewPointToVirtualSide1 );
229 mHalfEdge.at( edgeFromVirtualToNewPointSide2 )->setDual( edgeFromNewPointToVirtualSide2 );
231 mHalfEdge.at( edgeFromPoint1ToVirtualSide2 )->setNext( edgeFromVirtualToNewPointSide2 );
232 mHalfEdge.at( edgeFromVirtualToPoint1Side1 )->setNext( edgeFromPoint1ToNewPoint );
233 mHalfEdge.at( edgeFromPoint2ToVirtualSide1 )->setNext( edgeFromVirtualToNewPointSide1 );
234 mHalfEdge.at( edgeFromVirtualToPoint2Side2 )->setNext( edgeFromPoint2ToNewPoint );
235 mHalfEdge.at( edgeFromNewPointToPoint1 )->setDual( edgeFromPoint1ToNewPoint );
236 mHalfEdge.at( edgeFromNewPointToPoint2 )->setDual( edgeFromPoint2ToNewPoint );
241 if ( distance1 < distance )
243 closestEdge = mEdgeOutside;
244 distance = distance1;
246 else if ( distance2 < distance )
248 closestEdge = mHalfEdge[mEdgeOutside]->getDual();
249 distance = distance2;
252 mEdgeOutside = mHalfEdge[mHalfEdge[mHalfEdge[mEdgeOutside]->getNext()]->getDual()]->getNext();
253 }
while ( mEdgeOutside != firstEdge && mHalfEdge[mEdgeOutside]->getPoint() != -1 && mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint() != -1 );
255 if ( closestEdge < 0 )
259 const int extremePoint = mHalfEdge[closestEdge]->getPoint();
260 const int newPoint = mPointVector.count() - 1;
262 const int edgeFromExtremeToOpposite = mHalfEdge[closestEdge]->getDual();
264 const int edgeFromVirtualToExtremeSide1 = mHalfEdge[mHalfEdge[closestEdge]->getNext()]->getDual();
265 const int edgeFromVirtualToExtremeSide2 = mHalfEdge[mHalfEdge[mHalfEdge[closestEdge]->getDual()]->getNext()]->getNext();
266 const int edgeFromExtremeToVirtualSide2 = mHalfEdge[edgeFromVirtualToExtremeSide2]->getDual();
268 const int edgeFromExtremeToNewPoint = insertEdge( -10, -10, newPoint,
false,
false );
269 const int edgeFromNewPointToExtreme = insertEdge( edgeFromExtremeToNewPoint, edgeFromExtremeToVirtualSide2, extremePoint,
false,
false );
270 const int edgeFromNewPointToVirtualSide1 = insertEdge( -10, edgeFromVirtualToExtremeSide1, -1,
false,
false );
271 const int edgeFromVirtualToNewPointSide1 = insertEdge( edgeFromNewPointToVirtualSide1, -10, newPoint,
false,
false );
272 const int edgeFromNewPointToVirtualSide2 = insertEdge( -10, edgeFromVirtualToNewPointSide1, -1,
false,
false );
273 const int edgeFromVirtualToNewPointSide2 = insertEdge( edgeFromNewPointToVirtualSide2, edgeFromNewPointToExtreme, newPoint,
false,
false );
274 mHalfEdge.at( edgeFromExtremeToNewPoint )->setDual( edgeFromNewPointToExtreme );
275 mHalfEdge.at( edgeFromExtremeToNewPoint )->setNext( edgeFromNewPointToVirtualSide1 );
276 mHalfEdge.at( edgeFromNewPointToVirtualSide1 )->setDual( edgeFromVirtualToNewPointSide1 );
277 mHalfEdge.at( edgeFromNewPointToVirtualSide2 )->setDual( edgeFromVirtualToNewPointSide2 );
278 mHalfEdge.at( edgeFromVirtualToNewPointSide1 )->setNext( edgeFromNewPointToVirtualSide2 );
280 mHalfEdge.at( edgeFromVirtualToExtremeSide1 )->setNext( edgeFromExtremeToNewPoint );
281 mHalfEdge.at( edgeFromVirtualToExtremeSide2 )->setNext( edgeFromExtremeToOpposite );
282 mHalfEdge.at( edgeFromExtremeToVirtualSide2 )->setNext( edgeFromVirtualToNewPointSide2 );
289 mEdgeOutside = mHalfEdge[mEdgeOutside]->getDual();
292 const int newPoint = mPointVector.count() - 1;
295 int cwEdge = mEdgeOutside;
296 while ( mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext()]->getPoint() != -1 )
298 mHalfEdge[mHalfEdge[cwEdge]->getNext()]->setPoint( newPoint );
299 cwEdge = mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext();
302 const int edgeFromLastCwPointToVirtualPoint = mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext();
303 const int edgeFromLastCwPointToNewPointPoint = mHalfEdge[cwEdge]->getNext();
304 const int edgeFromNewPointPointToLastCwPoint = mHalfEdge[edgeFromLastCwPointToNewPointPoint]->getDual();
306 const int edgeFromNewPointtoVirtualPoint = insertEdge( -10, -10, -1,
false,
false );
307 const int edgeFromVirtualPointToNewPoint = insertEdge( edgeFromNewPointtoVirtualPoint, edgeFromNewPointPointToLastCwPoint, newPoint,
false,
false );
308 mHalfEdge.at( edgeFromLastCwPointToNewPointPoint )->setPoint( newPoint );
309 mHalfEdge.at( edgeFromNewPointtoVirtualPoint )->setDual( edgeFromVirtualPointToNewPoint );
310 mHalfEdge.at( edgeFromLastCwPointToVirtualPoint )->setNext( edgeFromVirtualPointToNewPoint );
313 int ccwEdge = mEdgeOutside;
314 while ( mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getNext()]->getDual()]->getNext()]->getPoint() != -1 )
316 mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->setPoint( newPoint );
317 ccwEdge = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getNext()]->getDual()]->getNext()]->getDual();
320 const int edgeToLastCcwPoint = mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getNext()]->getDual();
321 const int edgeFromLastCcwPointToNewPoint = mHalfEdge[edgeToLastCcwPoint]->getNext();
322 mHalfEdge.at( edgeFromNewPointtoVirtualPoint )->setNext( edgeToLastCcwPoint );
323 mHalfEdge.at( edgeFromLastCcwPointToNewPoint )->setNext( edgeFromNewPointtoVirtualPoint );
324 mHalfEdge.at( edgeFromLastCcwPointToNewPoint )->setPoint( newPoint );
328 const int number = baseEdgeOfTriangle( p );
333 unsigned int cwEdge = mEdgeOutside;
334 unsigned int ccwEdge = mEdgeOutside;
337 mHalfEdge[mHalfEdge[mEdgeOutside]->getNext()]->setPoint( mPointVector.count() - 1 );
340 while (
MathUtils::leftOf( *mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext()]->getPoint()], &p, mPointVector[mHalfEdge[cwEdge]->getPoint()] ) < ( -
leftOfTresh ) )
343 mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext()]->getNext()]->setPoint( mPointVector.count() - 1 );
345 cwEdge = (
unsigned int ) mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext();
349 const unsigned int edge1 = insertEdge( mHalfEdge[cwEdge]->getNext(), -10, mHalfEdge[cwEdge]->getPoint(),
false,
false );
350 const unsigned int edge2 = insertEdge( mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual(), -10, -1,
false,
false );
351 const unsigned int edge3 = insertEdge( -10, edge1, mPointVector.count() - 1,
false,
false );
354 mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->setDual( edge2 );
355 mHalfEdge[mHalfEdge[cwEdge]->getNext()]->setDual( edge1 );
356 mHalfEdge[edge1]->setNext( edge2 );
357 mHalfEdge[edge2]->setNext( edge3 );
360 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 ) )
363 mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->setPoint( mPointVector.count() - 1 );
365 ccwEdge = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->getNext()]->getNext();
369 const unsigned int edge4 = insertEdge( mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext(), -10, mPointVector.count() - 1,
false,
false );
370 const unsigned int edge5 = insertEdge( edge3, -10, -1,
false,
false );
371 const unsigned int edge6 = insertEdge( mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual(), edge4, mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getPoint(),
false,
false );
375 mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->setDual( edge6 );
376 mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->setDual( edge4 );
377 mHalfEdge[edge4]->setNext( edge5 );
378 mHalfEdge[edge5]->setNext( edge6 );
379 mHalfEdge[edge3]->setDual( edge5 );
382 unsigned int index = ccwEdge;
387 index = mHalfEdge[mHalfEdge[mHalfEdge[index]->getNext()]->getDual()]->getNext();
388 checkSwapRecursively( toswap, 0 );
389 if ( toswap == cwEdge )
395 else if ( number >= 0 )
397 const int nextnumber = mHalfEdge[number]->getNext();
398 const int nextnextnumber = mHalfEdge[mHalfEdge[number]->getNext()]->getNext();
401 const unsigned int edge1 = insertEdge( -10, nextnumber, mHalfEdge[number]->getPoint(),
false,
false );
402 const unsigned int edge2 = insertEdge(
static_cast<int>( edge1 ), -10, mPointVector.count() - 1,
false,
false );
403 const unsigned int edge3 = insertEdge( -10, nextnextnumber, mHalfEdge[nextnumber]->getPoint(),
false,
false );
404 const unsigned int edge4 = insertEdge(
static_cast<int>( edge3 ),
static_cast<int>( edge1 ), mPointVector.count() - 1,
false,
false );
405 const unsigned int edge5 = insertEdge( -10, number, mHalfEdge[nextnextnumber]->getPoint(),
false,
false );
406 const unsigned int edge6 = insertEdge(
static_cast<int>( edge5 ),
static_cast<int>( edge3 ), mPointVector.count() - 1,
false,
false );
409 mHalfEdge.at( edge1 )->setDual(
static_cast<int>( edge2 ) );
410 mHalfEdge.at( edge2 )->setNext(
static_cast<int>( edge5 ) );
411 mHalfEdge.at( edge3 )->setDual(
static_cast<int>( edge4 ) );
412 mHalfEdge.at( edge5 )->setDual(
static_cast<int>( edge6 ) );
413 mHalfEdge.at( number )->setNext(
static_cast<int>( edge2 ) );
414 mHalfEdge.at( nextnumber )->setNext(
static_cast<int>( edge4 ) );
415 mHalfEdge.at( nextnextnumber )->setNext(
static_cast<int>( edge6 ) );
418 checkSwapRecursively( number, 0 );
419 checkSwapRecursively( nextnumber, 0 );
420 checkSwapRecursively( nextnextnumber, 0 );
423 else if ( number == -20 )
428 const int point1 = mHalfEdge[mEdgeWithPoint]->getPoint();
429 const int point2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getDual()]->getPoint();
430 const double distance1 = p.
distance( *mPointVector[point1] );
436 const double distance2 = p.
distance( *mPointVector[point2] );
443 const int edgea = mEdgeWithPoint;
444 const int edgeb = mHalfEdge[mEdgeWithPoint]->getDual();
445 const int edgec = mHalfEdge[edgea]->getNext();
446 const int edged = mHalfEdge[edgec]->getNext();
447 const int edgee = mHalfEdge[edgeb]->getNext();
448 const int edgef = mHalfEdge[edgee]->getNext();
451 const int nedge1 = insertEdge( -10, mHalfEdge[edgea]->getNext(), mHalfEdge[edgea]->getPoint(),
false,
false );
452 const int nedge2 = insertEdge( nedge1, -10, mPointVector.count() - 1,
false,
false );
453 const int nedge3 = insertEdge( -10, edged, mHalfEdge[edgec]->getPoint(),
false,
false );
454 const int nedge4 = insertEdge( nedge3, nedge1, mPointVector.count() - 1,
false,
false );
455 const int nedge5 = insertEdge( -10, edgef, mHalfEdge[edgee]->getPoint(),
false,
false );
456 const int nedge6 = insertEdge( nedge5, edgeb, mPointVector.count() - 1,
false,
false );
459 mHalfEdge[nedge1]->setDual( nedge2 );
460 mHalfEdge[nedge2]->setNext( nedge5 );
461 mHalfEdge[nedge3]->setDual( nedge4 );
462 mHalfEdge[nedge5]->setDual( nedge6 );
463 mHalfEdge[edgea]->setPoint( mPointVector.count() - 1 );
464 mHalfEdge[edgea]->setNext( nedge3 );
465 mHalfEdge[edgec]->setNext( nedge4 );
466 mHalfEdge[edgee]->setNext( nedge6 );
467 mHalfEdge[edgef]->setNext( nedge2 );
470 checkSwapRecursively( edgec, 0 );
471 checkSwapRecursively( edged, 0 );
472 checkSwapRecursively( edgee, 0 );
473 checkSwapRecursively( edgef, 0 );
476 else if ( number == -100 || number == -5 )
482 else if ( number == -25 )
485 QgsPoint *newPoint = mPointVector[mPointVector.count() - 1];
486 QgsPoint *existingPoint = mPointVector[mTwiceInsPoint];
487 existingPoint->
setZ( std::max( newPoint->
z(), existingPoint->
z() ) );
490 return mTwiceInsPoint;
494 return ( mPointVector.count() - 1 );
497int QgsDualEdgeTriangulation::baseEdgeOfPoint(
int point )
499 unsigned int actedge = mEdgeInside;
501 if ( mPointVector.count() < 4 ||
point == -1 || mDimension == 1 )
503 int fromVirtualPoint = -1;
505 for (
int i = 0; i < mHalfEdge.count(); i++ )
507 if ( mHalfEdge[i]->getPoint() ==
point )
509 if ( mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() != -1 )
512 fromVirtualPoint = i;
515 return fromVirtualPoint;
523 if ( control > 1000000 )
529 for (
int i = 0; i < mHalfEdge.count(); i++ )
531 if ( mHalfEdge[i]->getPoint() ==
point && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 )
538 const int fromPoint = mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint();
539 const int toPoint = mHalfEdge[actedge]->getPoint();
541 if ( fromPoint == -1 || toPoint == -1 )
543 for (
int i = 0; i < mHalfEdge.count(); i++ )
545 if ( mHalfEdge[i]->getPoint() ==
point && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 )
553 const double leftOfNumber =
MathUtils::leftOf( *mPointVector[
point], mPointVector[mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[actedge]->getPoint()] );
556 if ( mHalfEdge[actedge]->getPoint() ==
point && mHalfEdge[mHalfEdge[actedge]->getNext()]->getPoint() != -1 )
558 mEdgeInside = actedge;
561 else if ( leftOfNumber <= 0.0 )
563 actedge = mHalfEdge[actedge]->getNext();
567 actedge = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[actedge]->getDual()]->getNext()]->getNext()]->getDual();
572int QgsDualEdgeTriangulation::baseEdgeOfTriangle(
const QgsPoint &point )
574 unsigned int actEdge = mEdgeInside;
575 if ( mHalfEdge.at( actEdge )->getPoint() < 0 )
576 actEdge = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getNext() )->getDual();
577 if ( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint() < 0 )
578 actEdge = mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getDual();
584 int firstEndPoint = 0, secEndPoint = 0, thEndPoint = 0, fouEndPoint = 0;
588 if ( runs > MAX_BASE_ITERATIONS )
594 const double leftOfValue =
MathUtils::leftOf(
point, mPointVector.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint() ), mPointVector.at( mHalfEdge.at( actEdge )->getPoint() ) );
609 firstEndPoint = mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint();
610 secEndPoint = mHalfEdge.at( actEdge )->getPoint();
612 else if ( nulls == 1 )
615 thEndPoint = mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint();
616 fouEndPoint = mHalfEdge.at( actEdge )->getPoint();
619 mEdgeWithPoint = actEdge;
628 actEdge = mHalfEdge.at( actEdge )->getDual();
633 actEdge = mHalfEdge.at( actEdge )->getNext();
634 if ( mHalfEdge.at( actEdge )->getPoint() == -1 )
640 mEdgeOutside = (
unsigned int ) mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
641 mEdgeInside = mHalfEdge.at( mHalfEdge.at( mEdgeOutside )->getDual() )->getNext();
647 if ( numInstabs > 0 )
650 mUnstableEdge = actEdge;
657 if ( firstEndPoint == thEndPoint || firstEndPoint == fouEndPoint )
660 mTwiceInsPoint = firstEndPoint;
663 else if ( secEndPoint == thEndPoint || secEndPoint == fouEndPoint )
666 mTwiceInsPoint = secEndPoint;
678 mEdgeInside = actEdge;
681 nr1 = mHalfEdge.at( actEdge )->getPoint();
682 nr2 = mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getPoint();
683 nr3 = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext() )->getPoint();
684 const double x1 = mPointVector.at( nr1 )->x();
685 const double y1 = mPointVector.at( nr1 )->y();
686 const double x2 = mPointVector.at( nr2 )->x();
687 const double y2 = mPointVector.at( nr2 )->y();
688 const double x3 = mPointVector.at( nr3 )->x();
689 const double y3 = mPointVector.at( nr3 )->y();
692 if ( x1 < x2 && x1 < x3 )
696 else if ( x2 < x1 && x2 < x3 )
698 return mHalfEdge.at( actEdge )->getNext();
700 else if ( x3 < x1 && x3 < x2 )
702 return mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
713 return mHalfEdge.at( actEdge )->getNext();
720 return mHalfEdge.at( actEdge )->getNext();
724 return mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
735 return mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
743 if ( mTriangleInterpolator )
745 return mTriangleInterpolator->calcNormVec( x, y, result );
756 if ( mTriangleInterpolator )
758 return mTriangleInterpolator->calcPoint( x, y, result );
767bool QgsDualEdgeTriangulation::checkSwapRecursively(
unsigned int edge,
unsigned int recursiveDeep )
769 if ( swapPossible( edge ) )
771 QgsPoint *pta = mPointVector.at( mHalfEdge.at( edge )->getPoint() );
772 QgsPoint *ptb = mPointVector.at( mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getPoint() );
773 QgsPoint *ptc = mPointVector.at( mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getNext() )->getPoint() );
774 QgsPoint *ptd = mPointVector.at( mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext() )->getPoint() );
775 if ( inCircle( *ptd, *pta, *ptb, *ptc ) )
777 doSwapRecursively( edge, recursiveDeep );
784bool QgsDualEdgeTriangulation::isEdgeNeedSwap(
unsigned int edge )
const
786 if ( swapPossible( edge ) )
788 QgsPoint *pta = mPointVector[mHalfEdge[edge]->getPoint()];
789 QgsPoint *ptb = mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()];
790 QgsPoint *ptc = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint()];
791 QgsPoint *ptd = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint()];
792 return inCircle( *ptd, *pta, *ptb, *ptc );
798void QgsDualEdgeTriangulation::doOnlySwap(
unsigned int edge )
800 const unsigned int edge1 = edge;
801 const unsigned int edge2 = mHalfEdge[edge]->getDual();
802 const unsigned int edge3 = mHalfEdge[edge]->getNext();
803 const unsigned int edge4 = mHalfEdge[mHalfEdge[edge]->getNext()]->getNext();
804 const unsigned int edge5 = mHalfEdge[mHalfEdge[edge]->getDual()]->getNext();
805 const unsigned int edge6 = mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getNext();
806 mHalfEdge[edge1]->setNext( edge4 );
807 mHalfEdge[edge2]->setNext( edge6 );
808 mHalfEdge[edge3]->setNext( edge2 );
809 mHalfEdge[edge4]->setNext( edge5 );
810 mHalfEdge[edge5]->setNext( edge1 );
811 mHalfEdge[edge6]->setNext( edge3 );
812 mHalfEdge[edge1]->setPoint( mHalfEdge[edge3]->getPoint() );
813 mHalfEdge[edge2]->setPoint( mHalfEdge[edge5]->getPoint() );
816void QgsDualEdgeTriangulation::doSwapRecursively(
unsigned int edge,
unsigned int recursiveDeep )
818 const unsigned int edge1 = edge;
819 const unsigned int edge2 = mHalfEdge.at( edge )->getDual();
820 const unsigned int edge3 = mHalfEdge.at( edge )->getNext();
821 const unsigned int edge4 = mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getNext();
822 const unsigned int edge5 = mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext();
823 const unsigned int edge6 = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext() )->getNext();
824 mHalfEdge.at( edge1 )->setNext( edge4 );
825 mHalfEdge.at( edge2 )->setNext( edge6 );
826 mHalfEdge.at( edge3 )->setNext( edge2 );
827 mHalfEdge.at( edge4 )->setNext( edge5 );
828 mHalfEdge.at( edge5 )->setNext( edge1 );
829 mHalfEdge.at( edge6 )->setNext( edge3 );
830 mHalfEdge.at( edge1 )->setPoint( mHalfEdge.at( edge3 )->getPoint() );
831 mHalfEdge.at( edge2 )->setPoint( mHalfEdge.at( edge5 )->getPoint() );
834 if ( recursiveDeep < 100 )
836 checkSwapRecursively( edge3, recursiveDeep );
837 checkSwapRecursively( edge6, recursiveDeep );
838 checkSwapRecursively( edge4, recursiveDeep );
839 checkSwapRecursively( edge5, recursiveDeep );
843 QStack<int> edgesToSwap;
844 edgesToSwap.push( edge3 );
845 edgesToSwap.push( edge6 );
846 edgesToSwap.push( edge4 );
847 edgesToSwap.push( edge5 );
849 while ( !edgesToSwap.isEmpty() && loopCount < 10000 )
852 const unsigned int e1 = edgesToSwap.pop();
853 if ( isEdgeNeedSwap( e1 ) )
855 const unsigned int e2 = mHalfEdge.at( e1 )->getDual();
856 const unsigned int e3 = mHalfEdge.at( e1 )->getNext();
857 const unsigned int e4 = mHalfEdge.at( mHalfEdge.at( e1 )->getNext() )->getNext();
858 const unsigned int e5 = mHalfEdge.at( mHalfEdge.at( e1 )->getDual() )->getNext();
859 const unsigned int e6 = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( e1 )->getDual() )->getNext() )->getNext();
860 mHalfEdge.at( e1 )->setNext( e4 );
861 mHalfEdge.at( e2 )->setNext( e6 );
862 mHalfEdge.at( e3 )->setNext( e2 );
863 mHalfEdge.at( e4 )->setNext( e5 );
864 mHalfEdge.at( e5 )->setNext( e1 );
865 mHalfEdge.at( e6 )->setNext( e3 );
866 mHalfEdge.at( e1 )->setPoint( mHalfEdge.at( e3 )->getPoint() );
867 mHalfEdge.at( e2 )->setPoint( mHalfEdge.at( e5 )->getPoint() );
869 edgesToSwap.push( e3 );
870 edgesToSwap.push( e6 );
871 edgesToSwap.push( e4 );
872 edgesToSwap.push( e5 );
879void DualEdgeTriangulation::draw( QPainter *p,
double xlowleft,
double ylowleft,
double xupright,
double yupright,
double width,
double height )
const
882 if ( mPointVector.isEmpty() )
887 p->setPen( mEdgeColor );
889 bool *control =
new bool[mHalfEdge.count()];
890 bool *control2 =
new bool[mHalfEdge.count()];
892 for (
unsigned int i = 0; i <= mHalfEdge.count() - 1; i++ )
898 if ( ( ( xupright - xlowleft ) / width ) > ( ( yupright - ylowleft ) / height ) )
900 double lowerborder = -( height * ( xupright - xlowleft ) / width - yupright );
901 for (
unsigned int i = 0; i < mHalfEdge.count() - 1; i++ )
903 if ( mHalfEdge[i]->getPoint() == -1 || mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() == -1 )
910 if ( mHalfEdge[i]->getPoint() != -1 && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 && mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint() != -1 )
912 p1 = mPointVector[mHalfEdge[i]->getPoint()]->getZ();
913 p2 = mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getZ();
914 p3 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getZ();
915 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 ) )
918 pa.setPoint( 0, ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( xupright - xlowleft )*width );
919 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 );
920 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 );
921 QColor
c( 255, 0, 0 );
923 p->drawPolygon( pa );
928 control2[mHalfEdge[i]->getNext()] =
true;
929 control2[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()] =
true;
936 if ( halfEdgeBBoxTest( i, xlowleft, lowerborder, xupright, yupright ) )
938 if ( mHalfEdge[i]->getBreak() )
940 p->setPen( mBreakEdgeColor );
942 else if ( mHalfEdge[i]->getForced() )
944 p->setPen( mForcedEdgeColor );
948 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 );
950 if ( mHalfEdge[i]->getForced() )
952 p->setPen( mEdgeColor );
958 control[mHalfEdge[i]->getDual()] =
true;
963 double rightborder = width * ( yupright - ylowleft ) / height + xlowleft;
964 for (
unsigned int i = 0; i < mHalfEdge.count() - 1; i++ )
966 if ( mHalfEdge[i]->getPoint() == -1 || mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() == -1 )
973 if ( mHalfEdge[i]->getPoint() != -1 && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 && mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint() != -1 )
975 p1 = mPointVector[mHalfEdge[i]->getPoint()]->getZ();
976 p2 = mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getZ();
977 p3 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getZ();
978 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 ) )
981 pa.setPoint( 0, ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( yupright - ylowleft )*height );
982 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 );
983 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 );
984 QColor
c( 255, 0, 0 );
986 p->drawPolygon( pa );
991 control2[mHalfEdge[i]->getNext()] =
true;
992 control2[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()] =
true;
1000 if ( halfEdgeBBoxTest( i, xlowleft, ylowleft, rightborder, yupright ) )
1002 if ( mHalfEdge[i]->getBreak() )
1004 p->setPen( mBreakEdgeColor );
1006 else if ( mHalfEdge[i]->getForced() )
1008 p->setPen( mForcedEdgeColor );
1011 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 );
1013 if ( mHalfEdge[i]->getForced() )
1015 p->setPen( mEdgeColor );
1020 control[mHalfEdge[i]->getDual()] =
true;
1032 const int firstedge = baseEdgeOfPoint( p2 );
1036 int nextnextedge = firstedge;
1040 edge = mHalfEdge[nextnextedge]->getDual();
1041 if ( mHalfEdge[edge]->getPoint() == p1 )
1043 theedge = nextnextedge;
1046 nextedge = mHalfEdge[edge]->getNext();
1047 nextnextedge = mHalfEdge[nextedge]->getNext();
1048 }
while ( nextnextedge != firstedge );
1050 if ( theedge == -10 )
1057 return mHalfEdge[mHalfEdge[mHalfEdge[theedge]->getDual()]->getNext()]->getPoint();
1062 const int firstedge = baseEdgeOfPoint( pointno );
1065 if ( firstedge == -1 )
1070 int actedge = firstedge;
1071 int edge, nextedge, nextnextedge;
1074 edge = mHalfEdge[actedge]->getDual();
1075 vlist.append( mHalfEdge[edge]->getPoint() );
1076 nextedge = mHalfEdge[edge]->getNext();
1077 vlist.append( mHalfEdge[nextedge]->getPoint() );
1078 nextnextedge = mHalfEdge[nextedge]->getNext();
1079 vlist.append( mHalfEdge[nextnextedge]->getPoint() );
1080 if ( mHalfEdge[nextnextedge]->getBreak() )
1082 vlist.append( -10 );
1086 vlist.append( -20 );
1088 actedge = nextnextedge;
1089 }
while ( nextnextedge != firstedge );
1096 if ( mPointVector.size() < 3 )
1102 const int edge = baseEdgeOfTriangle(
point );
1108 else if ( edge >= 0 )
1110 const int ptnr1 = mHalfEdge[edge]->getPoint();
1111 const int ptnr2 = mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint();
1112 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint();
1113 p1.
setX( mPointVector[ptnr1]->x() );
1114 p1.
setY( mPointVector[ptnr1]->y() );
1115 p1.
setZ( mPointVector[ptnr1]->z() );
1116 p2.
setX( mPointVector[ptnr2]->x() );
1117 p2.
setY( mPointVector[ptnr2]->y() );
1118 p2.
setZ( mPointVector[ptnr2]->z() );
1119 p3.
setX( mPointVector[ptnr3]->x() );
1120 p3.
setY( mPointVector[ptnr3]->y() );
1121 p3.
setZ( mPointVector[ptnr3]->z() );
1127 else if ( edge == -20 )
1129 const int ptnr1 = mHalfEdge[mEdgeWithPoint]->getPoint();
1130 const int ptnr2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getPoint();
1131 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getNext()]->getPoint();
1132 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1136 p1.
setX( mPointVector[ptnr1]->x() );
1137 p1.
setY( mPointVector[ptnr1]->y() );
1138 p1.
setZ( mPointVector[ptnr1]->z() );
1139 p2.
setX( mPointVector[ptnr2]->x() );
1140 p2.
setY( mPointVector[ptnr2]->y() );
1141 p2.
setZ( mPointVector[ptnr2]->z() );
1142 p3.
setX( mPointVector[ptnr3]->x() );
1143 p3.
setY( mPointVector[ptnr3]->y() );
1144 p3.
setZ( mPointVector[ptnr3]->z() );
1150 else if ( edge == -25 )
1152 const int edge1 = baseEdgeOfPoint( mTwiceInsPoint );
1153 const int edge2 = mHalfEdge[edge1]->getNext();
1154 const int edge3 = mHalfEdge[edge2]->getNext();
1155 const int ptnr1 = mHalfEdge[edge1]->getPoint();
1156 const int ptnr2 = mHalfEdge[edge2]->getPoint();
1157 const int ptnr3 = mHalfEdge[edge3]->getPoint();
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 == -5 )
1174 const int ptnr1 = mHalfEdge[mUnstableEdge]->getPoint();
1175 const int ptnr2 = mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getPoint();
1176 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getNext()]->getPoint();
1177 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1181 p1.
setX( mPointVector[ptnr1]->x() );
1182 p1.
setY( mPointVector[ptnr1]->y() );
1183 p1.
setZ( mPointVector[ptnr1]->z() );
1184 p2.
setX( mPointVector[ptnr2]->x() );
1185 p2.
setY( mPointVector[ptnr2]->y() );
1186 p2.
setZ( mPointVector[ptnr2]->z() );
1187 p3.
setX( mPointVector[ptnr3]->x() );
1188 p3.
setY( mPointVector[ptnr3]->y() );
1189 p3.
setZ( mPointVector[ptnr3]->z() );
1204 if ( mPointVector.size() < 3 )
1210 const int edge = baseEdgeOfTriangle(
point );
1215 else if ( edge >= 0 )
1217 const int ptnr1 = mHalfEdge[edge]->getPoint();
1218 const int ptnr2 = mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint();
1219 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint();
1220 p1.
setX( mPointVector[ptnr1]->x() );
1221 p1.
setY( mPointVector[ptnr1]->y() );
1222 p1.
setZ( mPointVector[ptnr1]->z() );
1223 p2.
setX( mPointVector[ptnr2]->x() );
1224 p2.
setY( mPointVector[ptnr2]->y() );
1225 p2.
setZ( mPointVector[ptnr2]->z() );
1226 p3.
setX( mPointVector[ptnr3]->x() );
1227 p3.
setY( mPointVector[ptnr3]->y() );
1228 p3.
setZ( mPointVector[ptnr3]->z() );
1231 else if ( edge == -20 )
1233 const int ptnr1 = mHalfEdge[mEdgeWithPoint]->getPoint();
1234 const int ptnr2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getPoint();
1235 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getNext()]->getPoint();
1236 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1240 p1.
setX( mPointVector[ptnr1]->x() );
1241 p1.
setY( mPointVector[ptnr1]->y() );
1242 p1.
setZ( mPointVector[ptnr1]->z() );
1243 p2.
setX( mPointVector[ptnr2]->x() );
1244 p2.
setY( mPointVector[ptnr2]->y() );
1245 p2.
setZ( mPointVector[ptnr2]->z() );
1246 p3.
setX( mPointVector[ptnr3]->x() );
1247 p3.
setY( mPointVector[ptnr3]->y() );
1248 p3.
setZ( mPointVector[ptnr3]->z() );
1251 else if ( edge == -25 )
1253 const int edge1 = baseEdgeOfPoint( mTwiceInsPoint );
1254 const int edge2 = mHalfEdge[edge1]->getNext();
1255 const int edge3 = mHalfEdge[edge2]->getNext();
1256 const int ptnr1 = mHalfEdge[edge1]->getPoint();
1257 const int ptnr2 = mHalfEdge[edge2]->getPoint();
1258 const int ptnr3 = mHalfEdge[edge3]->getPoint();
1259 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1263 p1.
setX( mPointVector[ptnr1]->x() );
1264 p1.
setY( mPointVector[ptnr1]->y() );
1265 p1.
setZ( mPointVector[ptnr1]->z() );
1266 p2.
setX( mPointVector[ptnr2]->x() );
1267 p2.
setY( mPointVector[ptnr2]->y() );
1268 p2.
setZ( mPointVector[ptnr2]->z() );
1269 p3.
setX( mPointVector[ptnr3]->x() );
1270 p3.
setY( mPointVector[ptnr3]->y() );
1271 p3.
setZ( mPointVector[ptnr3]->z() );
1274 else if ( edge == -5 )
1276 const int ptnr1 = mHalfEdge[mUnstableEdge]->getPoint();
1277 const int ptnr2 = mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getPoint();
1278 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getNext()]->getPoint();
1279 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1283 p1.
setX( mPointVector[ptnr1]->x() );
1284 p1.
setY( mPointVector[ptnr1]->y() );
1285 p1.
setZ( mPointVector[ptnr1]->z() );
1286 p2.
setX( mPointVector[ptnr2]->x() );
1287 p2.
setY( mPointVector[ptnr2]->y() );
1288 p2.
setZ( mPointVector[ptnr2]->z() );
1289 p3.
setX( mPointVector[ptnr3]->x() );
1290 p3.
setY( mPointVector[ptnr3]->y() );
1291 p3.
setZ( mPointVector[ptnr3]->z() );
1300unsigned int QgsDualEdgeTriangulation::insertEdge(
int dual,
int next,
int point,
bool mbreak,
bool forced )
1303 mHalfEdge.append( edge );
1304 return mHalfEdge.count() - 1;
1307static bool altitudeTriangleIsSmall(
const QgsPoint &pointBase1,
const QgsPoint &pointBase2,
const QgsPoint &pt3,
double tolerance )
1310 const double x1 = pointBase1.
x();
1311 const double y1 = pointBase1.
y();
1312 const double x2 = pointBase2.
x();
1313 const double y2 = pointBase2.
y();
1314 const double X = pt3.
x();
1315 const double Y = pt3.
y();
1324 t = ( X * ny - Y * nx - x1 * ny + y1 * nx ) / ( ( x2 - x1 ) * ny - ( y2 - y1 ) * nx );
1325 projectedPoint.
setX( x1 + t * ( x2 - x1 ) );
1326 projectedPoint.
setY( y1 + t * ( y2 - y1 ) );
1328 return pt3.
distance( projectedPoint ) < tolerance;
1338 QgsPoint *point1 = mPointVector.at( p1 );
1339 QgsPoint *point2 = mPointVector.at( p2 );
1342 QList<int> crossedEdges;
1345 int pointingEdge = 0;
1347 pointingEdge = baseEdgeOfPoint( p1 );
1349 if ( pointingEdge == -1 )
1355 int actEdge = mHalfEdge[pointingEdge]->getDual();
1356 const int firstActEdge = actEdge;
1363 if ( control > 100 )
1369 if ( mHalfEdge[actEdge]->getPoint() == -1 )
1371 actEdge = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getNext()]->getDual();
1376 if ( mHalfEdge[actEdge]->getPoint() == p2 )
1378 mHalfEdge[actEdge]->setForced(
true );
1380 mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced(
true );
1386 if ( ( point2->
y() - point1->
y() ) / ( mPointVector[mHalfEdge[actEdge]->getPoint()]->y() - point1->
y() ) == ( point2->
x() - point1->
x() ) / ( mPointVector[mHalfEdge[actEdge]->getPoint()]->x() - point1->
x() )
1387 && ( ( point2->
y() - point1->
y() ) >= 0 ) == ( ( mPointVector[mHalfEdge[actEdge]->getPoint()]->y() - point1->
y() ) > 0 )
1388 && ( ( point2->
x() - point1->
x() ) >= 0 ) == ( ( mPointVector[mHalfEdge[actEdge]->getPoint()]->x() - point1->
x() ) > 0 ) )
1391 mHalfEdge[actEdge]->setForced(
true );
1393 mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced(
true );
1395 const int a = insertForcedSegment( mHalfEdge[actEdge]->getPoint(), p2, segmentType );
1400 const int oppositeEdge = mHalfEdge[actEdge]->getNext();
1402 if ( mHalfEdge[oppositeEdge]->getPoint() == -1 || mHalfEdge[mHalfEdge[oppositeEdge]->getDual()]->getPoint() == -1 )
1404 actEdge = mHalfEdge[mHalfEdge[oppositeEdge]->getNext()]->getDual();
1408 QgsPoint *oppositePoint1 = mPointVector[mHalfEdge[oppositeEdge]->getPoint()];
1409 QgsPoint *oppositePoint2 = mPointVector[mHalfEdge[mHalfEdge[oppositeEdge]->getDual()]->getPoint()];
1411 if ( altitudeTriangleIsSmall( *oppositePoint1, *oppositePoint2, *point1, oppositePoint1->
distance( *oppositePoint2 ) / 500 ) )
1417 if (
MathUtils::lineIntersection( point1, point2, mPointVector[mHalfEdge[oppositeEdge]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[oppositeEdge]->getDual()]->getPoint()] ) )
1421 QgsPoint crosspoint( 0, 0, 0 );
1423 p3 = mHalfEdge[mHalfEdge[actEdge]->getNext()]->getPoint();
1424 p4 = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getDual()]->getPoint();
1426 const double dista = crosspoint.distance( *mPointVector[p3] );
1427 const double distb = crosspoint.distance( *mPointVector[p4] );
1428 if ( dista <= distb )
1430 insertForcedSegment( p1, p3, segmentType );
1431 const int e = insertForcedSegment( p3, p2, segmentType );
1434 else if ( distb <= dista )
1436 insertForcedSegment( p1, p4, segmentType );
1437 const int e = insertForcedSegment( p4, p2, segmentType );
1444 QgsPoint crosspoint( 0, 0, 0 );
1446 p3 = mHalfEdge[mHalfEdge[actEdge]->getNext()]->getPoint();
1447 p4 = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getDual()]->getPoint();
1449 const double distpart = crosspoint.distance( *mPointVector[p4] );
1450 const double disttot = mPointVector[p3]->distance( *mPointVector[p4] );
1451 const float frac = distpart / disttot;
1453 if ( frac == 0 || frac == 1 )
1458 mHalfEdge[actEdge]->setForced(
true );
1460 mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced(
true );
1462 const int a = insertForcedSegment( p4, p2, segmentType );
1465 else if ( frac == 1 )
1468 mHalfEdge[actEdge]->setForced(
true );
1470 mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced(
true );
1474 const int a = insertForcedSegment( p3, p2, segmentType );
1485 const int newpoint = splitHalfEdge( mHalfEdge[actEdge]->getNext(), frac );
1486 insertForcedSegment( p1, newpoint, segmentType );
1487 const int e = insertForcedSegment( newpoint, p2, segmentType );
1493 crossedEdges.append( oppositeEdge );
1496 actEdge = mHalfEdge[mHalfEdge[oppositeEdge]->getNext()]->getDual();
1497 }
while ( actEdge != firstActEdge );
1499 if ( crossedEdges.isEmpty() )
1501 int lastEdgeOppositePointIndex = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1504 while ( lastEdgeOppositePointIndex != p2 )
1506 QgsPoint *lastEdgePoint1 = mPointVector[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint()];
1507 QgsPoint *lastEdgePoint2 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint()];
1508 QgsPoint *lastEdgeOppositePoint = mPointVector[lastEdgeOppositePointIndex];
1514 QgsPoint crosspoint( 0, 0, 0 );
1516 p3 = mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint();
1517 p4 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1519 const double dista = crosspoint.distance( *mPointVector[p3] );
1520 const double distb = crosspoint.distance( *mPointVector[p4] );
1521 if ( dista <= distb )
1523 insertForcedSegment( p1, p3, segmentType );
1524 const int e = insertForcedSegment( p3, p2, segmentType );
1527 else if ( distb <= dista )
1529 insertForcedSegment( p1, p4, segmentType );
1530 const int e = insertForcedSegment( p4, p2, segmentType );
1536 QgsPoint crosspoint( 0, 0, 0 );
1538 p3 = mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint();
1539 p4 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1541 const double distpart = crosspoint.distance( *mPointVector[p3] );
1542 const double disttot = mPointVector[p3]->distance( *mPointVector[p4] );
1543 const float frac = distpart / disttot;
1544 if ( frac == 0 || frac == 1 )
1548 const int newpoint = splitHalfEdge( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext(), frac );
1549 insertForcedSegment( p1, newpoint, segmentType );
1550 const int e = insertForcedSegment( newpoint, p2, segmentType );
1554 crossedEdges.append( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext() );
1560 QgsPoint crosspoint( 0, 0, 0 );
1562 p3 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1563 p4 = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint();
1565 const double dista = crosspoint.distance( *mPointVector[p3] );
1566 const double distb = crosspoint.distance( *mPointVector[p4] );
1567 if ( dista <= distb )
1569 insertForcedSegment( p1, p3, segmentType );
1570 const int e = insertForcedSegment( p3, p2, segmentType );
1573 else if ( distb <= dista )
1575 insertForcedSegment( p1, p4, segmentType );
1576 const int e = insertForcedSegment( p4, p2, segmentType );
1582 QgsPoint crosspoint( 0, 0, 0 );
1584 p3 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1585 p4 = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint();
1587 const double distpart = crosspoint.distance( *mPointVector[p3] );
1588 const double disttot = mPointVector[p3]->distance( *mPointVector[p4] );
1589 const float frac = distpart / disttot;
1590 if ( frac == 0 || frac == 1 )
1594 const int newpoint = splitHalfEdge( mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext(), frac );
1595 insertForcedSegment( p1, newpoint, segmentType );
1596 const int e = insertForcedSegment( newpoint, p2, segmentType );
1600 crossedEdges.append( mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext() );
1607 lastEdgeOppositePointIndex = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1611 QgsPoint *lastEdgePoint1 = mPointVector[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint()];
1612 QgsPoint *lastEdgePoint2 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint()];
1613 QgsPoint *lastEdgeOppositePoint = mPointVector[lastEdgeOppositePointIndex];
1614 if ( altitudeTriangleIsSmall( *lastEdgePoint1, *lastEdgePoint2, *lastEdgeOppositePoint, lastEdgePoint1->
distance( *lastEdgePoint2 ) / 500 ) )
1618 QList<int>::const_iterator iter;
1619 for ( iter = crossedEdges.constBegin(); iter != crossedEdges.constEnd(); ++iter )
1621 mHalfEdge[( *( iter ) )]->setForced(
false );
1622 mHalfEdge[( *( iter ) )]->setBreak(
false );
1623 mHalfEdge[mHalfEdge[( *( iter ) )]->getDual()]->setForced(
false );
1624 mHalfEdge[mHalfEdge[( *( iter ) )]->getDual()]->setBreak(
false );
1629 QList<int> freelist = crossedEdges;
1632 QList<int> leftPolygon;
1633 QList<int> rightPolygon;
1636 const int firstedge = freelist.first();
1637 mHalfEdge[firstedge]->setForced(
true );
1639 leftPolygon.append( firstedge );
1640 const int dualfirstedge = mHalfEdge[freelist.first()]->getDual();
1641 mHalfEdge[dualfirstedge]->setForced(
true );
1643 rightPolygon.append( dualfirstedge );
1644 freelist.pop_front();
1648 QList<int>::const_iterator leftiter;
1649 leftiter = crossedEdges.constEnd();
1653 const int newpoint = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[( *leftiter )]->getDual()]->getNext()]->getNext()]->getPoint();
1654 if ( newpoint != actpointl )
1657 actpointl = newpoint;
1658 const int theedge = mHalfEdge[mHalfEdge[mHalfEdge[( *leftiter )]->getDual()]->getNext()]->getNext();
1659 leftPolygon.append( theedge );
1661 if ( leftiter == crossedEdges.constBegin() )
1669 leftPolygon.append( mHalfEdge[crossedEdges.first()]->getNext() );
1672 QList<int>::const_iterator rightiter;
1674 for ( rightiter = crossedEdges.constBegin(); rightiter != crossedEdges.constEnd(); ++rightiter )
1676 const int newpoint = mHalfEdge[mHalfEdge[mHalfEdge[( *rightiter )]->getNext()]->getNext()]->getPoint();
1677 if ( newpoint != actpointr )
1680 actpointr = newpoint;
1681 const int theedge = mHalfEdge[mHalfEdge[( *rightiter )]->getNext()]->getNext();
1682 rightPolygon.append( theedge );
1688 rightPolygon.append( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext() );
1689 mHalfEdge[rightPolygon.last()]->setNext( dualfirstedge );
1692 int actedgel = leftPolygon[1];
1693 leftiter = leftPolygon.constBegin();
1695 for ( ; leftiter != leftPolygon.constEnd(); ++leftiter )
1697 mHalfEdge[actedgel]->setNext( ( *leftiter ) );
1698 actedgel = ( *leftiter );
1702 int actedger = rightPolygon[1];
1703 rightiter = rightPolygon.constBegin();
1705 for ( ; rightiter != rightPolygon.constEnd(); ++rightiter )
1707 mHalfEdge[actedger]->setNext( ( *rightiter ) );
1708 actedger = ( *( rightiter ) );
1713 mHalfEdge[leftPolygon.first()]->setNext( ( *( ++( leftiter = leftPolygon.constBegin() ) ) ) );
1714 mHalfEdge[leftPolygon.first()]->setPoint( p2 );
1715 mHalfEdge[leftPolygon.last()]->setNext( firstedge );
1716 mHalfEdge[rightPolygon.first()]->setNext( ( *( ++( rightiter = rightPolygon.constBegin() ) ) ) );
1717 mHalfEdge[rightPolygon.first()]->setPoint( p1 );
1718 mHalfEdge[rightPolygon.last()]->setNext( dualfirstedge );
1720 triangulatePolygon( &leftPolygon, &freelist, firstedge );
1721 triangulatePolygon( &rightPolygon, &freelist, dualfirstedge );
1724 for ( iter = crossedEdges.constBegin(); iter != crossedEdges.constEnd(); ++iter )
1726 checkSwapRecursively( ( *( iter ) ), 0 );
1729 return leftPolygon.first();
1734 mForcedCrossBehavior = b;
1739 mTriangleInterpolator = interpolator;
1745 const double minangle = 0;
1749 bool swapped =
false;
1750 bool *control =
new bool[mHalfEdge.count()];
1752 for (
int i = 0; i <= mHalfEdge.count() - 1; i++ )
1758 for (
int i = 0; i <= mHalfEdge.count() - 1; i++ )
1767 e2 = mHalfEdge[e1]->getNext();
1768 e3 = mHalfEdge[e2]->getNext();
1771 p1 = mHalfEdge[e1]->getPoint();
1772 p2 = mHalfEdge[e2]->getPoint();
1773 p3 = mHalfEdge[e3]->getPoint();
1776 if ( p1 == -1 || p2 == -1 || p3 == -1 )
1784 double el1, el2, el3;
1785 el1 = mPointVector[p1]->z();
1786 el2 = mPointVector[p2]->z();
1787 el3 = mPointVector[p3]->z();
1789 if ( el1 == el2 && el2 == el3 )
1792 if ( swapPossible( ( uint ) e1 ) && mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[e1]->getDual()]->getNext()]->getPoint()]->z() != el1 && swapMinAngle( e1 ) > minangle )
1794 doOnlySwap( ( uint ) e1 );
1797 else if ( swapPossible( ( uint ) e2 ) && mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[e2]->getDual()]->getNext()]->getPoint()]->z() != el2 && swapMinAngle( e2 ) > minangle )
1799 doOnlySwap( ( uint ) e2 );
1802 else if ( swapPossible( ( uint ) e3 ) && mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[e3]->getDual()]->getNext()]->getPoint()]->z() != el3 && swapMinAngle( e3 ) > minangle )
1804 doOnlySwap( ( uint ) e3 );
1834 const double mintol = 17;
1837 std::map<int, double> edge_angle;
1838 std::multimap<double, int> angle_edge;
1839 QSet<int> dontexamine;
1848 const int nhalfedges = mHalfEdge.count();
1850 for (
int i = 0; i < nhalfedges - 1; i++ )
1852 const int next = mHalfEdge[i]->getNext();
1853 const int nextnext = mHalfEdge[next]->getNext();
1855 if ( mHalfEdge[next]->getPoint() != -1 && ( mHalfEdge[i]->getForced() || mHalfEdge[mHalfEdge[mHalfEdge[i]->getDual()]->getNext()]->getPoint() == -1 ) )
1857 if ( !( ( mHalfEdge[next]->getForced() || edgeOnConvexHull( next ) ) || ( mHalfEdge[nextnext]->getForced() || edgeOnConvexHull( nextnext ) ) ) )
1860 while (
MathUtils::inDiametral( mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()], mPointVector[mHalfEdge[i]->getPoint()], mPointVector[mHalfEdge[next]->getPoint()] ) )
1863 const int pointno = splitHalfEdge( i, 0.5 );
1875 for (
int i = 0; i < mHalfEdge.count() - 1; i++ )
1877 p1 = mHalfEdge[mHalfEdge[i]->getDual()]->getPoint();
1878 p2 = mHalfEdge[i]->getPoint();
1879 p3 = mHalfEdge[mHalfEdge[i]->getNext()]->getPoint();
1881 if ( p1 == -1 || p2 == -1 || p3 == -1 )
1885 angle =
MathUtils::angle( mPointVector[p1], mPointVector[p2], mPointVector[p3], mPointVector[p2] );
1887 bool twoforcededges;
1890 twoforcededges = ( mHalfEdge[i]->getForced() || edgeOnConvexHull( i ) ) && ( mHalfEdge[mHalfEdge[i]->getNext()]->getForced() || edgeOnConvexHull( mHalfEdge[i]->getNext() ) );
1892 if ( angle < mintol && !twoforcededges )
1894 edge_angle.insert( std::make_pair( i, angle ) );
1895 angle_edge.insert( std::make_pair( angle, i ) );
1900 for ( std::multimap<double, int>::const_iterator it = angle_edge.begin(); it != angle_edge.end(); ++it )
1906 double minangle = 0;
1909 int minedgenextnext;
1913 while ( !edge_angle.empty() )
1915 minangle = angle_edge.begin()->first;
1917 minedge = angle_edge.begin()->second;
1918 minedgenext = mHalfEdge[minedge]->getNext();
1919 minedgenextnext = mHalfEdge[minedgenext]->getNext();
1922 if ( !
MathUtils::circumcenter( mPointVector[mHalfEdge[minedge]->getPoint()], mPointVector[mHalfEdge[minedgenext]->getPoint()], mPointVector[mHalfEdge[minedgenextnext]->getPoint()], &circumcenter ) )
1924 QgsDebugError( QStringLiteral(
"warning, calculation of circumcenter failed" ) );
1926 dontexamine.insert( minedge );
1927 edge_angle.erase( minedge );
1928 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
1929 while ( minedgeiter->second != minedge )
1933 angle_edge.erase( minedgeiter );
1937 if ( !
pointInside( circumcenter.x(), circumcenter.y() ) )
1940 QgsDebugError( QStringLiteral(
"put circumcenter %1//%2 on dontexamine list because it is outside the convex hull" )
1941 .arg( circumcenter.x() )
1942 .arg( circumcenter.y() ) );
1943 dontexamine.insert( minedge );
1944 edge_angle.erase( minedge );
1945 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
1946 while ( minedgeiter->second != minedge )
1950 angle_edge.erase( minedgeiter );
1956 bool encroached =
false;
1959 int numhalfedges = mHalfEdge.count();
1960 for (
int i = 0; i < numhalfedges; i++ )
1962 if ( mHalfEdge[i]->getForced() || edgeOnConvexHull( i ) )
1964 if (
MathUtils::inDiametral( mPointVector[mHalfEdge[i]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()], &circumcenter ) )
1969 int pointno = splitHalfEdge( i, 0.5 );
1972 int pointingedge = baseEdgeOfPoint( pointno );
1974 int actedge = pointingedge;
1977 double angle1, angle2, angle3;
1981 ed1 = mHalfEdge[actedge]->getDual();
1982 pt1 = mHalfEdge[ed1]->getPoint();
1983 ed2 = mHalfEdge[ed1]->getNext();
1984 pt2 = mHalfEdge[ed2]->getPoint();
1985 ed3 = mHalfEdge[ed2]->getNext();
1986 pt3 = mHalfEdge[ed3]->getPoint();
1989 if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
1994 angle1 =
MathUtils::angle( mPointVector[pt3], mPointVector[pt1], mPointVector[pt2], mPointVector[pt1] );
1995 angle2 =
MathUtils::angle( mPointVector[pt1], mPointVector[pt2], mPointVector[pt3], mPointVector[pt2] );
1996 angle3 =
MathUtils::angle( mPointVector[pt2], mPointVector[pt3], mPointVector[pt1], mPointVector[pt3] );
1999 bool twoforcededges1, twoforcededges2, twoforcededges3;
2001 if ( ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) && ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) )
2003 twoforcededges1 =
true;
2007 twoforcededges1 =
false;
2010 if ( ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) && ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) )
2012 twoforcededges2 =
true;
2016 twoforcededges2 =
false;
2019 if ( ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) && ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) )
2021 twoforcededges3 =
true;
2025 twoforcededges3 =
false;
2029 QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
2030 if ( ed1iter != dontexamine.end() )
2033 dontexamine.erase( ed1iter );
2038 std::map<int, double>::iterator tempit1;
2039 tempit1 = edge_angle.find( ed1 );
2040 if ( tempit1 != edge_angle.end() )
2043 double angle = tempit1->second;
2044 edge_angle.erase( ed1 );
2045 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2046 while ( tempit2->second != ed1 )
2050 angle_edge.erase( tempit2 );
2054 if ( angle1 < mintol && !twoforcededges1 )
2056 edge_angle.insert( std::make_pair( ed1, angle1 ) );
2057 angle_edge.insert( std::make_pair( angle1, ed1 ) );
2061 QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
2062 if ( ed2iter != dontexamine.end() )
2065 dontexamine.erase( ed2iter );
2070 std::map<int, double>::iterator tempit1;
2071 tempit1 = edge_angle.find( ed2 );
2072 if ( tempit1 != edge_angle.end() )
2075 double angle = tempit1->second;
2076 edge_angle.erase( ed2 );
2077 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2078 while ( tempit2->second != ed2 )
2082 angle_edge.erase( tempit2 );
2086 if ( angle2 < mintol && !twoforcededges2 )
2088 edge_angle.insert( std::make_pair( ed2, angle2 ) );
2089 angle_edge.insert( std::make_pair( angle2, ed2 ) );
2093 QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
2094 if ( ed3iter != dontexamine.end() )
2097 dontexamine.erase( ed3iter );
2102 std::map<int, double>::iterator tempit1;
2103 tempit1 = edge_angle.find( ed3 );
2104 if ( tempit1 != edge_angle.end() )
2107 double angle = tempit1->second;
2108 edge_angle.erase( ed3 );
2109 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2110 while ( tempit2->second != ed3 )
2114 angle_edge.erase( tempit2 );
2118 if ( angle3 < mintol && !twoforcededges3 )
2120 edge_angle.insert( std::make_pair( ed3, angle3 ) );
2121 angle_edge.insert( std::make_pair( angle3, ed3 ) );
2126 while ( actedge != pointingedge );
2134 QSet<int> influenceedges;
2135 int baseedge = baseEdgeOfTriangle( circumcenter );
2136 if ( baseedge == -5 )
2139 edge_angle.erase( minedge );
2140 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
2141 while ( minedgeiter->second != minedge )
2145 angle_edge.erase( minedgeiter );
2148 else if ( baseedge == -25 )
2151 edge_angle.erase( minedge );
2152 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
2153 while ( minedgeiter->second != minedge )
2157 angle_edge.erase( minedgeiter );
2160 else if ( baseedge == -20 )
2162 baseedge = mEdgeWithPoint;
2165 evaluateInfluenceRegion( &circumcenter, baseedge, influenceedges );
2166 evaluateInfluenceRegion( &circumcenter, mHalfEdge[baseedge]->getNext(), influenceedges );
2167 evaluateInfluenceRegion( &circumcenter, mHalfEdge[mHalfEdge[baseedge]->getNext()]->getNext(), influenceedges );
2169 for ( QSet<int>::iterator it = influenceedges.begin(); it != influenceedges.end(); ++it )
2171 if ( ( mHalfEdge[*it]->getForced() || edgeOnConvexHull( *it ) ) &&
MathUtils::inDiametral( mPointVector[mHalfEdge[*it]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[*it]->getDual()]->getPoint()], &circumcenter ) )
2175 const int pointno = splitHalfEdge( *it, 0.5 );
2179 const int pointingedge = baseEdgeOfPoint( pointno );
2181 int actedge = pointingedge;
2184 double angle1, angle2, angle3;
2188 ed1 = mHalfEdge[actedge]->getDual();
2189 pt1 = mHalfEdge[ed1]->getPoint();
2190 ed2 = mHalfEdge[ed1]->getNext();
2191 pt2 = mHalfEdge[ed2]->getPoint();
2192 ed3 = mHalfEdge[ed2]->getNext();
2193 pt3 = mHalfEdge[ed3]->getPoint();
2196 if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
2201 angle1 =
MathUtils::angle( mPointVector[pt3], mPointVector[pt1], mPointVector[pt2], mPointVector[pt1] );
2202 angle2 =
MathUtils::angle( mPointVector[pt1], mPointVector[pt2], mPointVector[pt3], mPointVector[pt2] );
2203 angle3 =
MathUtils::angle( mPointVector[pt2], mPointVector[pt3], mPointVector[pt1], mPointVector[pt3] );
2206 bool twoforcededges1, twoforcededges2, twoforcededges3;
2209 twoforcededges1 = ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) && ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) );
2211 twoforcededges2 = ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) && ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) );
2213 twoforcededges3 = ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) && ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) );
2217 const QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
2218 if ( ed1iter != dontexamine.end() )
2221 dontexamine.erase( ed1iter );
2226 std::map<int, double>::iterator tempit1;
2227 tempit1 = edge_angle.find( ed1 );
2228 if ( tempit1 != edge_angle.end() )
2231 const double angle = tempit1->second;
2232 edge_angle.erase( ed1 );
2233 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2234 while ( tempit2->second != ed1 )
2238 angle_edge.erase( tempit2 );
2242 if ( angle1 < mintol && !twoforcededges1 )
2244 edge_angle.insert( std::make_pair( ed1, angle1 ) );
2245 angle_edge.insert( std::make_pair( angle1, ed1 ) );
2249 const QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
2250 if ( ed2iter != dontexamine.end() )
2253 dontexamine.erase( ed2iter );
2258 std::map<int, double>::iterator tempit1;
2259 tempit1 = edge_angle.find( ed2 );
2260 if ( tempit1 != edge_angle.end() )
2263 const double angle = tempit1->second;
2264 edge_angle.erase( ed2 );
2265 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2266 while ( tempit2->second != ed2 )
2270 angle_edge.erase( tempit2 );
2274 if ( angle2 < mintol && !twoforcededges2 )
2276 edge_angle.insert( std::make_pair( ed2, angle2 ) );
2277 angle_edge.insert( std::make_pair( angle2, ed2 ) );
2281 const QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
2282 if ( ed3iter != dontexamine.end() )
2285 dontexamine.erase( ed3iter );
2290 std::map<int, double>::iterator tempit1;
2291 tempit1 = edge_angle.find( ed3 );
2292 if ( tempit1 != edge_angle.end() )
2295 const double angle = tempit1->second;
2296 edge_angle.erase( ed3 );
2297 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2298 while ( tempit2->second != ed3 )
2302 angle_edge.erase( tempit2 );
2306 if ( angle3 < mintol && !twoforcededges3 )
2308 edge_angle.insert( std::make_pair( ed3, angle3 ) );
2309 angle_edge.insert( std::make_pair( angle3, ed3 ) );
2313 }
while ( actedge != pointingedge );
2326 calcPoint( circumcenter.x(), circumcenter.y(), p );
2329 if ( pointno == -100 || pointno == mTwiceInsPoint )
2331 if ( pointno == -100 )
2333 QgsDebugError( QStringLiteral(
"put circumcenter %1//%2 on dontexamine list because of numerical instabilities" )
2334 .arg( circumcenter.x() )
2335 .arg( circumcenter.y() ) );
2337 else if ( pointno == mTwiceInsPoint )
2339 QgsDebugError( QStringLiteral(
"put circumcenter %1//%2 on dontexamine list because it is already inserted" )
2340 .arg( circumcenter.x() )
2341 .arg( circumcenter.y() ) );
2344 for (
int i = 0; i < mPointVector.count(); i++ )
2346 if ( mPointVector[i]->x() == circumcenter.x() && mPointVector[i]->y() == circumcenter.y() )
2353 QgsDebugError( QStringLiteral(
"point is not present in the triangulation" ) );
2357 dontexamine.insert( minedge );
2358 edge_angle.erase( minedge );
2359 std::multimap<double, int>::iterator minedgeiter = angle_edge.lower_bound( minangle );
2360 while ( minedgeiter->second != minedge )
2364 angle_edge.erase( minedgeiter );
2373 const int pointingedge = baseEdgeOfPoint( pointno );
2375 int actedge = pointingedge;
2378 double angle1, angle2, angle3;
2382 ed1 = mHalfEdge[actedge]->getDual();
2383 pt1 = mHalfEdge[ed1]->getPoint();
2384 ed2 = mHalfEdge[ed1]->getNext();
2385 pt2 = mHalfEdge[ed2]->getPoint();
2386 ed3 = mHalfEdge[ed2]->getNext();
2387 pt3 = mHalfEdge[ed3]->getPoint();
2390 if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
2395 angle1 =
MathUtils::angle( mPointVector[pt3], mPointVector[pt1], mPointVector[pt2], mPointVector[pt1] );
2396 angle2 =
MathUtils::angle( mPointVector[pt1], mPointVector[pt2], mPointVector[pt3], mPointVector[pt2] );
2397 angle3 =
MathUtils::angle( mPointVector[pt2], mPointVector[pt3], mPointVector[pt1], mPointVector[pt3] );
2400 bool twoforcededges1, twoforcededges2, twoforcededges3;
2402 twoforcededges1 = ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) && ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) );
2404 twoforcededges2 = ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) && ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) );
2406 twoforcededges3 = ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) && ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) );
2410 const QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
2411 if ( ed1iter != dontexamine.end() )
2414 dontexamine.erase( ed1iter );
2419 std::map<int, double>::iterator tempit1;
2420 tempit1 = edge_angle.find( ed1 );
2421 if ( tempit1 != edge_angle.end() )
2424 const double angle = tempit1->second;
2425 edge_angle.erase( ed1 );
2426 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2427 while ( tempit2->second != ed1 )
2431 angle_edge.erase( tempit2 );
2435 if ( angle1 < mintol && !twoforcededges1 )
2437 edge_angle.insert( std::make_pair( ed1, angle1 ) );
2438 angle_edge.insert( std::make_pair( angle1, ed1 ) );
2443 const QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
2444 if ( ed2iter != dontexamine.end() )
2447 dontexamine.erase( ed2iter );
2452 std::map<int, double>::iterator tempit1;
2453 tempit1 = edge_angle.find( ed2 );
2454 if ( tempit1 != edge_angle.end() )
2457 const double angle = tempit1->second;
2458 edge_angle.erase( ed2 );
2459 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2460 while ( tempit2->second != ed2 )
2464 angle_edge.erase( tempit2 );
2468 if ( angle2 < mintol && !twoforcededges2 )
2470 edge_angle.insert( std::make_pair( ed2, angle2 ) );
2471 angle_edge.insert( std::make_pair( angle2, ed2 ) );
2475 const QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
2476 if ( ed3iter != dontexamine.end() )
2479 dontexamine.erase( ed3iter );
2484 std::map<int, double>::iterator tempit1;
2485 tempit1 = edge_angle.find( ed3 );
2486 if ( tempit1 != edge_angle.end() )
2489 const double angle = tempit1->second;
2490 edge_angle.erase( ed3 );
2491 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2492 while ( tempit2->second != ed3 )
2496 angle_edge.erase( tempit2 );
2500 if ( angle3 < mintol && !twoforcededges3 )
2502 edge_angle.insert( std::make_pair( ed3, angle3 ) );
2503 angle_edge.insert( std::make_pair( angle3, ed3 ) );
2507 }
while ( actedge != pointingedge );
2513 for ( QSet<int>::iterator it = dontexamine.begin(); it != dontexamine.end(); ++it )
2515 QgsDebugMsgLevel( QStringLiteral(
"edge nr. %1 is in dontexamine" ).arg( *it ), 2 );
2521bool QgsDualEdgeTriangulation::swapPossible(
unsigned int edge )
const
2524 if ( mHalfEdge[edge]->getForced() )
2530 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 )
2535 QgsPoint *pta = mPointVector[mHalfEdge[edge]->getPoint()];
2536 QgsPoint *ptb = mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()];
2537 QgsPoint *ptc = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint()];
2538 QgsPoint *ptd = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint()];
2558void QgsDualEdgeTriangulation::triangulatePolygon( QList<int> *poly, QList<int> *free,
int mainedge )
2562 if ( poly->count() == 3 )
2568 QList<int>::const_iterator iterator = ++( poly->constBegin() );
2569 double distance =
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] );
2570 int distedge = ( *iterator );
2571 int nextdistedge = mHalfEdge[( *iterator )]->getNext();
2574 while ( iterator != --( poly->constEnd() ) )
2576 if (
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] ) < distance )
2578 distedge = ( *iterator );
2579 nextdistedge = mHalfEdge[( *iterator )]->getNext();
2580 distance =
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] );
2585 if ( nextdistedge == ( *( --poly->end() ) ) )
2587 const int inserta = free->first();
2588 const int insertb = mHalfEdge[inserta]->getDual();
2591 mHalfEdge[inserta]->setNext( ( poly->at( 1 ) ) );
2592 mHalfEdge[inserta]->setPoint( mHalfEdge[mainedge]->getPoint() );
2593 mHalfEdge[insertb]->setNext( nextdistedge );
2594 mHalfEdge[insertb]->setPoint( mHalfEdge[distedge]->getPoint() );
2595 mHalfEdge[distedge]->setNext( inserta );
2596 mHalfEdge[mainedge]->setNext( insertb );
2599 for ( iterator = ( ++( poly->constBegin() ) ); ( *iterator ) != nextdistedge; ++iterator )
2601 polya.append( ( *iterator ) );
2603 polya.prepend( inserta );
2607 for ( iterator = polya.begin(); iterator != polya.end(); ++iterator )
2613 triangulatePolygon( &polya, free, inserta );
2616 else if ( distedge == ( *( ++poly->begin() ) ) )
2618 const int inserta = free->first();
2619 const int insertb = mHalfEdge[inserta]->getDual();
2622 mHalfEdge[inserta]->setNext( ( poly->at( 2 ) ) );
2623 mHalfEdge[inserta]->setPoint( mHalfEdge[distedge]->getPoint() );
2624 mHalfEdge[insertb]->setNext( mainedge );
2625 mHalfEdge[insertb]->setPoint( mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint() );
2626 mHalfEdge[distedge]->setNext( insertb );
2627 mHalfEdge[( *( --poly->end() ) )]->setNext( inserta );
2630 iterator = poly->constBegin();
2632 while ( iterator != poly->constEnd() )
2634 polya.append( ( *iterator ) );
2637 polya.prepend( inserta );
2639 triangulatePolygon( &polya, free, inserta );
2644 const int inserta = free->first();
2645 const int insertb = mHalfEdge[inserta]->getDual();
2648 const int insertc = free->first();
2649 const int insertd = mHalfEdge[insertc]->getDual();
2652 mHalfEdge[inserta]->setNext( ( poly->at( 1 ) ) );
2653 mHalfEdge[inserta]->setPoint( mHalfEdge[mainedge]->getPoint() );
2654 mHalfEdge[insertb]->setNext( insertd );
2655 mHalfEdge[insertb]->setPoint( mHalfEdge[distedge]->getPoint() );
2656 mHalfEdge[insertc]->setNext( nextdistedge );
2657 mHalfEdge[insertc]->setPoint( mHalfEdge[distedge]->getPoint() );
2658 mHalfEdge[insertd]->setNext( mainedge );
2659 mHalfEdge[insertd]->setPoint( mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint() );
2661 mHalfEdge[distedge]->setNext( inserta );
2662 mHalfEdge[mainedge]->setNext( insertb );
2663 mHalfEdge[( *( --poly->end() ) )]->setNext( insertc );
2669 for ( iterator = ++( poly->constBegin() ); ( *iterator ) != nextdistedge; ++iterator )
2671 polya.append( ( *iterator ) );
2673 polya.prepend( inserta );
2676 while ( iterator != poly->constEnd() )
2678 polyb.append( ( *iterator ) );
2681 polyb.prepend( insertc );
2683 triangulatePolygon( &polya, free, inserta );
2684 triangulatePolygon( &polyb, free, insertc );
2697 unsigned int actedge = mEdgeInside;
2705 if ( runs > MAX_BASE_ITERATIONS )
2707 QgsDebugError( QStringLiteral(
"warning, instability detected: Point coordinates: %1//%2" ).arg( x ).arg( y ) );
2711 if (
MathUtils::leftOf(
point, mPointVector[mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[actedge]->getPoint()] ) < ( -
leftOfTresh ) )
2720 else if ( fabs(
MathUtils::leftOf(
point, mPointVector[mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[actedge]->getPoint()] ) ) <=
leftOfTresh )
2723 mEdgeWithPoint = actedge;
2733 actedge = mHalfEdge[actedge]->getDual();
2739 actedge = mHalfEdge[actedge]->getNext();
2740 if ( mHalfEdge[actedge]->getPoint() == -1 )
2746 mEdgeOutside = (
unsigned int ) mHalfEdge[mHalfEdge[actedge]->getNext()]->getNext();
2756 if ( numinstabs > 0 )
2758 QgsDebugError( QStringLiteral(
"numerical instabilities" ) );
2766 mEdgeInside = actedge;
2771bool DualEdgeTriangulation::readFromTAFF( QString filename )
2773 QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
2775 QFile file( filename );
2776 file.open( IO_Raw | IO_ReadOnly );
2777 QBuffer buffer( file.readAll() );
2780 QTextStream textstream( &buffer );
2781 buffer.open( IO_ReadOnly );
2784 int numberofhalfedges;
2788 while ( buff.mid( 0, 4 ) !=
"TRIA" )
2790 buff = textstream.readLine();
2792 while ( buff.mid( 0, 4 ) !=
"NEDG" )
2794 buff = textstream.readLine();
2796 numberofhalfedges = buff.section(
' ', 1, 1 ).toInt();
2797 mHalfEdge.resize( numberofhalfedges );
2800 while ( buff.mid( 0, 4 ) !=
"DATA" )
2805 int nr1, nr2, dual1, dual2, point1, point2, next1, next2, fo1, fo2, b1, b2;
2806 bool forced1, forced2, break1, break2;
2810 QProgressBar *edgebar =
new QProgressBar();
2811 edgebar->setCaption( tr(
"Reading edges…" ) );
2812 edgebar->setTotalSteps( numberofhalfedges / 2 );
2813 edgebar->setMinimumWidth( 400 );
2814 edgebar->move( 500, 500 );
2817 for (
int i = 0; i < numberofhalfedges / 2; i++ )
2819 if ( i % 1000 == 0 )
2821 edgebar->setProgress( i );
2825 textstream >> point1;
2826 textstream >> next1;
2850 textstream >> point2;
2851 textstream >> next2;
2889 mHalfEdge.insert( nr1, hf1 );
2890 mHalfEdge.insert( nr2, hf2 );
2894 edgebar->setProgress( numberofhalfedges / 2 );
2898 for (
int i = 0; i < numberofhalfedges; i++ )
2901 a = mHalfEdge[i]->getPoint();
2902 b = mHalfEdge[mHalfEdge[i]->getDual()]->getPoint();
2903 c = mHalfEdge[mHalfEdge[i]->getNext()]->getPoint();
2904 d = mHalfEdge[mHalfEdge[mHalfEdge[i]->getDual()]->getNext()]->getPoint();
2905 if ( a != -1 && b != -1 &&
c != -1 && d != -1 )
2913 while ( buff.mid( 0, 4 ) !=
"POIN" )
2915 buff = textstream.readLine();
2918 while ( buff.mid( 0, 4 ) !=
"NPTS" )
2920 buff = textstream.readLine();
2923 numberofpoints = buff.section(
' ', 1, 1 ).toInt();
2924 mPointVector.resize( numberofpoints );
2926 while ( buff.mid( 0, 4 ) !=
"DATA" )
2931 QProgressBar *pointbar =
new QProgressBar();
2932 pointbar->setCaption( tr(
"Reading points…" ) );
2933 pointbar->setTotalSteps( numberofpoints );
2934 pointbar->setMinimumWidth( 400 );
2935 pointbar->move( 500, 500 );
2940 for (
int i = 0; i < numberofpoints; i++ )
2942 if ( i % 1000 == 0 )
2944 pointbar->setProgress( i );
2954 mPointVector.insert( i, p );
2970 else if ( x > xMax )
2979 else if ( y > yMax )
2986 pointbar->setProgress( numberofpoints );
2988 QApplication::restoreOverrideCursor();
2992bool DualEdgeTriangulation::saveToTAFF( QString filename )
const
2994 QFile outputfile( filename );
2995 if ( !outputfile.open( IO_WriteOnly ) )
2997 QMessageBox::warning( 0, tr(
"Warning" ), tr(
"File could not be written." ), QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton );
3001 QTextStream outstream( &outputfile );
3002 outstream.precision( 9 );
3005 outstream <<
"TRIA" << std::endl << std::flush;
3006 outstream <<
"NEDG " << mHalfEdge.count() << std::endl << std::flush;
3007 outstream <<
"PANO 1" << std::endl << std::flush;
3008 outstream <<
"DATA ";
3010 bool *cont =
new bool[mHalfEdge.count()];
3011 for (
unsigned int i = 0; i <= mHalfEdge.count() - 1; i++ )
3016 for (
unsigned int i = 0; i < mHalfEdge.count(); i++ )
3023 int dual = mHalfEdge[i]->getDual();
3024 outstream << i <<
" " << mHalfEdge[i]->getPoint() <<
" " << mHalfEdge[i]->getNext() <<
" " << mHalfEdge[i]->getForced() <<
" " << mHalfEdge[i]->getBreak() <<
" ";
3025 outstream << dual <<
" " << mHalfEdge[dual]->getPoint() <<
" " << mHalfEdge[dual]->getNext() <<
" " << mHalfEdge[dual]->getForced() <<
" " << mHalfEdge[dual]->getBreak() <<
" ";
3029 outstream << std::endl << std::flush;
3030 outstream << std::endl << std::flush;
3035 outstream <<
"POIN" << std::endl << std::flush;
3036 outstream <<
"NPTS " << getNumberOfPoints() << std::endl << std::flush;
3037 outstream <<
"PATT 3" << std::endl << std::flush;
3038 outstream <<
"DATA ";
3040 for (
int i = 0; i < getNumberOfPoints(); i++ )
3043 outstream << p->getX() <<
" " << p->getY() <<
" " << p->getZ() <<
" ";
3045 outstream << std::endl << std::flush;
3046 outstream << std::endl << std::flush;
3055 const int edge1 = baseEdgeOfTriangle( p );
3062 edge2 = mHalfEdge[edge1]->getNext();
3063 edge3 = mHalfEdge[edge2]->getNext();
3064 point1 =
point( mHalfEdge[edge1]->getPoint() );
3065 point2 =
point( mHalfEdge[edge2]->getPoint() );
3066 point3 =
point( mHalfEdge[edge3]->getPoint() );
3067 if ( point1 && point2 && point3 )
3070 double dist1, dist2, dist3;
3074 if ( dist1 <= dist2 && dist1 <= dist3 )
3077 if ( swapPossible( edge1 ) )
3079 doOnlySwap( edge1 );
3082 else if ( dist2 <= dist1 && dist2 <= dist3 )
3085 if ( swapPossible( edge2 ) )
3087 doOnlySwap( edge2 );
3090 else if ( dist3 <= dist1 && dist3 <= dist2 )
3093 if ( swapPossible( edge3 ) )
3095 doOnlySwap( edge3 );
3117 const int edge1 = baseEdgeOfTriangle( p );
3120 const int edge2 = mHalfEdge[edge1]->getNext();
3121 const int edge3 = mHalfEdge[edge2]->getNext();
3125 if ( point1 && point2 && point3 )
3131 if ( dist1 <= dist2 && dist1 <= dist3 )
3133 p1 = mHalfEdge[edge1]->getPoint();
3134 p2 = mHalfEdge[mHalfEdge[edge1]->getNext()]->getPoint();
3135 p3 = mHalfEdge[mHalfEdge[edge1]->getDual()]->getPoint();
3136 p4 = mHalfEdge[mHalfEdge[mHalfEdge[edge1]->getDual()]->getNext()]->getPoint();
3138 else if ( dist2 <= dist1 && dist2 <= dist3 )
3140 p1 = mHalfEdge[edge2]->getPoint();
3141 p2 = mHalfEdge[mHalfEdge[edge2]->getNext()]->getPoint();
3142 p3 = mHalfEdge[mHalfEdge[edge2]->getDual()]->getPoint();
3143 p4 = mHalfEdge[mHalfEdge[mHalfEdge[edge2]->getDual()]->getNext()]->getPoint();
3147 p1 = mHalfEdge[edge3]->getPoint();
3148 p2 = mHalfEdge[mHalfEdge[edge3]->getNext()]->getPoint();
3149 p3 = mHalfEdge[mHalfEdge[edge3]->getDual()]->getPoint();
3150 p4 = mHalfEdge[mHalfEdge[mHalfEdge[edge3]->getDual()]->getNext()]->getPoint();
3178 bool *alreadyVisitedEdges =
new bool[mHalfEdge.size()];
3179 if ( !alreadyVisitedEdges )
3185 for (
int i = 0; i < mHalfEdge.size(); ++i )
3187 alreadyVisitedEdges[i] =
false;
3190 for (
int i = 0; i < mHalfEdge.size(); ++i )
3195 HalfEdge *currentEdge = mHalfEdge[i];
3196 if ( currentEdge->
getPoint() != -1 && mHalfEdge[currentEdge->
getDual()]->getPoint() != -1 && !alreadyVisitedEdges[currentEdge->
getDual()] )
3202 QgsPoint *p2 = mPointVector[mHalfEdge[currentEdge->
getDual()]->getPoint()];
3210 QString attributeString;
3215 attributeString = QStringLiteral(
"break line" );
3219 attributeString = QStringLiteral(
"structure line" );
3226 alreadyVisitedEdges[i] =
true;
3229 delete[] alreadyVisitedEdges;
3239 QVector<bool> edgeToTreat( mHalfEdge.count(),
true );
3240 QHash<HalfEdge *, int> edgesHash;
3241 for (
int i = 0; i < mHalfEdge.count(); ++i )
3243 edgesHash.insert( mHalfEdge[i], i );
3252 const int edgeCount = edgeToTreat.count();
3253 for (
int i = 0; i < edgeCount; ++i )
3255 bool containVirtualPoint =
false;
3256 if ( edgeToTreat[i] )
3258 HalfEdge *currentEdge = mHalfEdge[i];
3263 edgeToTreat[edgesHash.value( currentEdge )] =
false;
3264 face.append( currentEdge->
getPoint() );
3265 containVirtualPoint |= currentEdge->
getPoint() == -1;
3266 currentEdge = mHalfEdge.at( currentEdge->
getNext() );
3267 }
while ( currentEdge != firstEdge && !containVirtualPoint && ( !feedback || !feedback->
isCanceled() ) );
3268 if ( !containVirtualPoint )
3269 mesh.
faces.append( face );
3280double QgsDualEdgeTriangulation::swapMinAngle(
int edge )
const
3283 QgsPoint *p2 =
point( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() );
3284 QgsPoint *p3 =
point( mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() );
3285 QgsPoint *p4 =
point( mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() );
3292 if ( angle2 < minangle )
3297 if ( angle3 < minangle )
3302 if ( angle4 < minangle )
3307 if ( angle5 < minangle )
3312 if ( angle6 < minangle )
3320int QgsDualEdgeTriangulation::splitHalfEdge(
int edge,
float position )
3323 if ( position < 0 || position > 1 )
3325 QgsDebugError( QStringLiteral(
"warning, position is not between 0 and 1" ) );
3329 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 );
3332 QgsPoint zvaluepoint( 0, 0, 0 );
3334 p->
setZ( zvaluepoint.z() );
3337 if ( mPointVector.count() >= mPointVector.size() )
3339 mPointVector.resize( mPointVector.count() + 1 );
3341 QgsDebugMsgLevel( QStringLiteral(
"inserting point nr. %1, %2//%3//%4" ).arg( mPointVector.count() ).arg( p->
x() ).arg( p->
y() ).arg( p->
z() ), 2 );
3342 mPointVector.insert( mPointVector.count(), p );
3345 const int dualedge = mHalfEdge[edge]->getDual();
3346 const int edge1 = insertEdge( -10, -10, mPointVector.count() - 1,
false,
false );
3347 const int edge2 = insertEdge( edge1, mHalfEdge[mHalfEdge[edge]->getNext()]->getNext(), mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint(),
false,
false );
3348 const int edge3 = insertEdge( -10, mHalfEdge[mHalfEdge[dualedge]->getNext()]->getNext(), mHalfEdge[mHalfEdge[dualedge]->getNext()]->getPoint(),
false,
false );
3349 const int edge4 = insertEdge( edge3, dualedge, mPointVector.count() - 1,
false,
false );
3350 const int edge5 = insertEdge( -10, mHalfEdge[edge]->getNext(), mHalfEdge[edge]->getPoint(), mHalfEdge[edge]->getBreak(), mHalfEdge[edge]->getForced() );
3351 const int edge6 = insertEdge( edge5, edge3, mPointVector.count() - 1, mHalfEdge[dualedge]->getBreak(), mHalfEdge[dualedge]->getForced() );
3352 mHalfEdge[edge1]->setDual( edge2 );
3353 mHalfEdge[edge1]->setNext( edge5 );
3354 mHalfEdge[edge3]->setDual( edge4 );
3355 mHalfEdge[edge5]->setDual( edge6 );
3358 mHalfEdge[mHalfEdge[edge]->getNext()]->setNext( edge1 );
3359 mHalfEdge[mHalfEdge[dualedge]->getNext()]->setNext( edge4 );
3360 mHalfEdge[edge]->setNext( edge2 );
3361 mHalfEdge[edge]->setPoint( mPointVector.count() - 1 );
3362 mHalfEdge[mHalfEdge[edge3]->getNext()]->setNext( edge6 );
3365 checkSwapRecursively( mHalfEdge[edge5]->getNext(), 0 );
3366 checkSwapRecursively( mHalfEdge[edge2]->getNext(), 0 );
3367 checkSwapRecursively( mHalfEdge[dualedge]->getNext(), 0 );
3368 checkSwapRecursively( mHalfEdge[edge3]->getNext(), 0 );
3372 return mPointVector.count() - 1;
3375bool QgsDualEdgeTriangulation::edgeOnConvexHull(
int edge )
3377 return ( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() == -1 || mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() == -1 );
3380void QgsDualEdgeTriangulation::evaluateInfluenceRegion(
QgsPoint *point,
int edge, QSet<int> &set )
3382 if ( set.find( edge ) == set.end() )
3391 if ( !mHalfEdge[edge]->getForced() && !edgeOnConvexHull( edge ) )
3394 if (
inCircle( *
point, *mPointVector[mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint()], *mPointVector[mHalfEdge[edge]->getPoint()], *mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()] ) )
3396 evaluateInfluenceRegion(
point, mHalfEdge[mHalfEdge[edge]->getDual()]->getNext(), set );
3397 evaluateInfluenceRegion(
point, mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getNext(), set );
3402int QgsDualEdgeTriangulation::firstEdgeOutSide()
3405 while ( ( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() != -1 || mHalfEdge[edge]->getPoint() == -1 || mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() == -1 ) && edge < mHalfEdge.count() )
3410 if ( edge >= mHalfEdge.count() )
3416void QgsDualEdgeTriangulation::removeLastPoint()
3418 if ( mPointVector.isEmpty() )
3420 QgsPoint *p = mPointVector.takeLast();
Represents a half edge in a triangulation.
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.
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...
Q_INVOKABLE 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
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.
Point geometry type, with support for z-dimension and m-values.
void setY(double y)
Sets the point's y-coordinate.
void setX(double x)
Sets the point's x-coordinate.
double distance(double x, double y) const
Returns the Cartesian 2D distance between this point and a specified x, y coordinate.
void setZ(double z)
Sets the point's z-coordinate.
double distanceSquared(double x, double y) const
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.
An interface for interpolator classes for triangulations.
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.
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
QVector< int > QgsMeshFace
List of vertex indexes.
Mesh - vertices, edges and faces.
QVector< QgsMeshVertex > vertices
QVector< QgsMeshFace > faces