30using namespace Qt::StringLiterals;
36 const double x2 = point2.
x() - point1.
x();
37 const double y2 = point2.
y() - point1.
y();
38 const double x3 = point3.
x() - point1.
x();
39 const double y3 = point3.
y() - point1.
y();
41 const double denom = x2 * y3 - y2 * x3;
47 frac = ( x2 * ( x2 - x3 ) + y2 * ( y2 - y3 ) ) / denom;
48 const double cx = ( x3 + frac * y3 ) / 2;
49 const double cy = ( y3 - frac * x3 ) / 2;
50 const double squaredRadius = ( cx * cx + cy * cy );
51 const QgsPoint center( cx + point1.
x(), cy + point1.
y() );
58 qDeleteAll( mPointVector );
59 qDeleteAll( mHalfEdge );
66 for (
int i = 0; i < mHalfEdge.count(); i++ )
68 const int a = mHalfEdge[mHalfEdge[i]->getDual()]->getDual();
69 const int b = mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getNext();
85 int currentpoint = -10;
92 if ( actpoint != -100 )
98 if ( actpoint == -100 )
103 for ( ; i < points.size(); ++i )
105 currentpoint =
addPoint( points.at( i ) );
106 if ( currentpoint != -100 && actpoint != -100 && currentpoint != actpoint )
108 insertForcedSegment( actpoint, currentpoint, lineType );
110 actpoint = currentpoint;
117 if ( mPointVector.isEmpty() )
126 mXMin = std::min( p.
x(), mXMin );
127 mXMax = std::max( p.
x(), mXMax );
128 mYMin = std::min( p.
y(), mYMin );
129 mYMax = std::max( p.
y(), mYMax );
133 mPointVector.append(
new QgsPoint( p ) );
136 if ( mDimension == -1 )
138 const unsigned int zedge = insertEdge( -10, -10, -1,
false,
false );
139 const unsigned int fedge = insertEdge(
static_cast<int>( zedge ),
static_cast<int>( zedge ), 0,
false,
false );
140 ( mHalfEdge.at( zedge ) )->setDual(
static_cast<int>( fedge ) );
141 ( mHalfEdge.at( zedge ) )->setNext(
static_cast<int>( fedge ) );
144 else if ( mDimension == 0 )
147 if ( p.
x() == mPointVector[0]->x() && p.
y() == mPointVector[0]->y() )
154 const unsigned int edgeFromPoint0ToPoint1 = insertEdge( -10, -10, 1,
false,
false );
155 const unsigned int edgeFromPoint1ToPoint0 = insertEdge( edgeFromPoint0ToPoint1, -10, 0,
false,
false );
156 const unsigned int edgeFromVirtualToPoint1Side1 = insertEdge( -10, -10, 1,
false,
false );
157 const unsigned int edgeFromPoint1ToVirtualSide1 = insertEdge( edgeFromVirtualToPoint1Side1, 1, -1,
false,
false );
158 const unsigned int edgeFromVirtualToPoint1Side2 = insertEdge( -10, edgeFromPoint1ToPoint0, 1,
false,
false );
159 const unsigned int edgeFromPoint1ToVirtualSide2 = insertEdge( edgeFromVirtualToPoint1Side2, edgeFromVirtualToPoint1Side1, -1,
false,
false );
160 const unsigned int edgeFromVirtualToPoint0Side2 = insertEdge( -10, -10, 0,
false,
false );
161 const unsigned int edgeFromPoint0ToVirtualSide2 = insertEdge( edgeFromVirtualToPoint0Side2, edgeFromVirtualToPoint1Side2, -1,
false,
false );
162 mHalfEdge.at( edgeFromPoint1ToPoint0 )->setNext( edgeFromPoint0ToVirtualSide2 );
163 mHalfEdge.at( edgeFromPoint0ToPoint1 )->setDual( edgeFromPoint1ToPoint0 );
164 mHalfEdge.at( edgeFromPoint0ToPoint1 )->setNext( edgeFromPoint1ToVirtualSide1 );
165 mHalfEdge.at( edgeFromVirtualToPoint1Side1 )->setDual( edgeFromPoint1ToVirtualSide1 );
166 mHalfEdge.at( edgeFromVirtualToPoint1Side1 )->setNext( edgeFromPoint1ToVirtualSide2 );
167 mHalfEdge.at( 0 )->setNext(
static_cast<int>( edgeFromVirtualToPoint0Side2 ) );
168 mHalfEdge.at( 1 )->setNext(
static_cast<int>( edgeFromPoint0ToPoint1 ) );
169 mHalfEdge.at( edgeFromVirtualToPoint1Side2 )->setDual( edgeFromPoint1ToVirtualSide2 );
170 mHalfEdge.at( edgeFromVirtualToPoint0Side2 )->setDual( edgeFromPoint0ToVirtualSide2 );
171 mHalfEdge.at( edgeFromVirtualToPoint0Side2 )->setNext( 0 );
173 mEdgeOutside = edgeFromPoint0ToPoint1;
176 else if ( mDimension == 1 )
178 if ( mEdgeOutside < 0 || mHalfEdge[mEdgeOutside]->getPoint() < 0 || mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint() < 0 )
179 mEdgeOutside = firstEdgeOutSide();
180 if ( mEdgeOutside < 0 || mHalfEdge[mEdgeOutside]->getPoint() < 0 || mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint() < 0 )
183 const double leftOfNumber =
MathUtils::leftOf( p, mPointVector[mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint()], mPointVector[mHalfEdge[mEdgeOutside]->getPoint()] );
189 int closestEdge = -1;
190 double distance = std::numeric_limits<double>::max();
191 const int firstEdge = mEdgeOutside;
194 const int point1 = mHalfEdge[mEdgeOutside]->getPoint();
195 const int point2 = mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint();
196 const double distance1 = p.
distance( *mPointVector[point1] );
202 const double distance2 = p.
distance( *mPointVector[point2] );
209 const double edgeLength = mPointVector[point1]->distance( *mPointVector[point2] );
211 if ( distance1 < edgeLength && distance2 < edgeLength )
214 const int newPoint = mPointVector.count() - 1;
217 const int edgeFromNewPointToPoint1 = mEdgeOutside;
218 const int edgeFromNewPointToPoint2 = mHalfEdge[mEdgeOutside]->getDual();
220 const int edgeFromPoint1ToVirtualSide2 = mHalfEdge[edgeFromNewPointToPoint1]->getNext();
221 const int edgeFromVirtualToPoint1Side1 = mHalfEdge[mHalfEdge[edgeFromNewPointToPoint2]->getNext()]->getNext();
222 const int edgeFromPoint2ToVirtualSide1 = mHalfEdge[edgeFromNewPointToPoint2]->getNext();
223 const int edgeFromVirtualToPoint2Side2 = mHalfEdge[mHalfEdge[edgeFromNewPointToPoint1]->getNext()]->getNext();
225 const int edgeFromVirtualToNewPointSide1 = insertEdge( -10, edgeFromNewPointToPoint2, newPoint,
false,
false );
226 const int edgeFromNewPointToVirtualSide1 = insertEdge( edgeFromVirtualToNewPointSide1, edgeFromVirtualToPoint1Side1, -1,
false,
false );
227 const int edgeFromVirtualToNewPointSide2 = insertEdge( -10, edgeFromNewPointToPoint1, newPoint,
false,
false );
228 const int edgeFromNewPointToVirtualSide2 = insertEdge( edgeFromVirtualToNewPointSide2, edgeFromVirtualToPoint2Side2, -1,
false,
false );
229 const int edgeFromPoint1ToNewPoint = insertEdge( edgeFromNewPointToPoint1, edgeFromNewPointToVirtualSide1, newPoint,
false,
false );
230 const int edgeFromPoint2ToNewPoint = insertEdge( edgeFromNewPointToPoint2, edgeFromNewPointToVirtualSide2, newPoint,
false,
false );
231 mHalfEdge.at( edgeFromVirtualToNewPointSide1 )->setDual( edgeFromNewPointToVirtualSide1 );
232 mHalfEdge.at( edgeFromVirtualToNewPointSide2 )->setDual( edgeFromNewPointToVirtualSide2 );
234 mHalfEdge.at( edgeFromPoint1ToVirtualSide2 )->setNext( edgeFromVirtualToNewPointSide2 );
235 mHalfEdge.at( edgeFromVirtualToPoint1Side1 )->setNext( edgeFromPoint1ToNewPoint );
236 mHalfEdge.at( edgeFromPoint2ToVirtualSide1 )->setNext( edgeFromVirtualToNewPointSide1 );
237 mHalfEdge.at( edgeFromVirtualToPoint2Side2 )->setNext( edgeFromPoint2ToNewPoint );
238 mHalfEdge.at( edgeFromNewPointToPoint1 )->setDual( edgeFromPoint1ToNewPoint );
239 mHalfEdge.at( edgeFromNewPointToPoint2 )->setDual( edgeFromPoint2ToNewPoint );
244 if ( distance1 < distance )
246 closestEdge = mEdgeOutside;
247 distance = distance1;
249 else if ( distance2 < distance )
251 closestEdge = mHalfEdge[mEdgeOutside]->getDual();
252 distance = distance2;
255 mEdgeOutside = mHalfEdge[mHalfEdge[mHalfEdge[mEdgeOutside]->getNext()]->getDual()]->getNext();
256 }
while ( mEdgeOutside != firstEdge && mHalfEdge[mEdgeOutside]->getPoint() != -1 && mHalfEdge[mHalfEdge[mEdgeOutside]->getDual()]->getPoint() != -1 );
258 if ( closestEdge < 0 )
262 const int extremePoint = mHalfEdge[closestEdge]->getPoint();
263 const int newPoint = mPointVector.count() - 1;
265 const int edgeFromExtremeToOpposite = mHalfEdge[closestEdge]->getDual();
267 const int edgeFromVirtualToExtremeSide1 = mHalfEdge[mHalfEdge[closestEdge]->getNext()]->getDual();
268 const int edgeFromVirtualToExtremeSide2 = mHalfEdge[mHalfEdge[mHalfEdge[closestEdge]->getDual()]->getNext()]->getNext();
269 const int edgeFromExtremeToVirtualSide2 = mHalfEdge[edgeFromVirtualToExtremeSide2]->getDual();
271 const int edgeFromExtremeToNewPoint = insertEdge( -10, -10, newPoint,
false,
false );
272 const int edgeFromNewPointToExtreme = insertEdge( edgeFromExtremeToNewPoint, edgeFromExtremeToVirtualSide2, extremePoint,
false,
false );
273 const int edgeFromNewPointToVirtualSide1 = insertEdge( -10, edgeFromVirtualToExtremeSide1, -1,
false,
false );
274 const int edgeFromVirtualToNewPointSide1 = insertEdge( edgeFromNewPointToVirtualSide1, -10, newPoint,
false,
false );
275 const int edgeFromNewPointToVirtualSide2 = insertEdge( -10, edgeFromVirtualToNewPointSide1, -1,
false,
false );
276 const int edgeFromVirtualToNewPointSide2 = insertEdge( edgeFromNewPointToVirtualSide2, edgeFromNewPointToExtreme, newPoint,
false,
false );
277 mHalfEdge.at( edgeFromExtremeToNewPoint )->setDual( edgeFromNewPointToExtreme );
278 mHalfEdge.at( edgeFromExtremeToNewPoint )->setNext( edgeFromNewPointToVirtualSide1 );
279 mHalfEdge.at( edgeFromNewPointToVirtualSide1 )->setDual( edgeFromVirtualToNewPointSide1 );
280 mHalfEdge.at( edgeFromNewPointToVirtualSide2 )->setDual( edgeFromVirtualToNewPointSide2 );
281 mHalfEdge.at( edgeFromVirtualToNewPointSide1 )->setNext( edgeFromNewPointToVirtualSide2 );
283 mHalfEdge.at( edgeFromVirtualToExtremeSide1 )->setNext( edgeFromExtremeToNewPoint );
284 mHalfEdge.at( edgeFromVirtualToExtremeSide2 )->setNext( edgeFromExtremeToOpposite );
285 mHalfEdge.at( edgeFromExtremeToVirtualSide2 )->setNext( edgeFromVirtualToNewPointSide2 );
292 mEdgeOutside = mHalfEdge[mEdgeOutside]->getDual();
295 const int newPoint = mPointVector.count() - 1;
298 int cwEdge = mEdgeOutside;
299 while ( mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext()]->getPoint() != -1 )
301 mHalfEdge[mHalfEdge[cwEdge]->getNext()]->setPoint( newPoint );
302 cwEdge = mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext();
305 const int edgeFromLastCwPointToVirtualPoint = mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext();
306 const int edgeFromLastCwPointToNewPointPoint = mHalfEdge[cwEdge]->getNext();
307 const int edgeFromNewPointPointToLastCwPoint = mHalfEdge[edgeFromLastCwPointToNewPointPoint]->getDual();
309 const int edgeFromNewPointtoVirtualPoint = insertEdge( -10, -10, -1,
false,
false );
310 const int edgeFromVirtualPointToNewPoint = insertEdge( edgeFromNewPointtoVirtualPoint, edgeFromNewPointPointToLastCwPoint, newPoint,
false,
false );
311 mHalfEdge.at( edgeFromLastCwPointToNewPointPoint )->setPoint( newPoint );
312 mHalfEdge.at( edgeFromNewPointtoVirtualPoint )->setDual( edgeFromVirtualPointToNewPoint );
313 mHalfEdge.at( edgeFromLastCwPointToVirtualPoint )->setNext( edgeFromVirtualPointToNewPoint );
316 int ccwEdge = mEdgeOutside;
317 while ( mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getNext()]->getDual()]->getNext()]->getPoint() != -1 )
319 mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->setPoint( newPoint );
320 ccwEdge = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getNext()]->getDual()]->getNext()]->getDual();
323 const int edgeToLastCcwPoint = mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getNext()]->getDual();
324 const int edgeFromLastCcwPointToNewPoint = mHalfEdge[edgeToLastCcwPoint]->getNext();
325 mHalfEdge.at( edgeFromNewPointtoVirtualPoint )->setNext( edgeToLastCcwPoint );
326 mHalfEdge.at( edgeFromLastCcwPointToNewPoint )->setNext( edgeFromNewPointtoVirtualPoint );
327 mHalfEdge.at( edgeFromLastCcwPointToNewPoint )->setPoint( newPoint );
331 const int number = baseEdgeOfTriangle( p );
336 unsigned int cwEdge = mEdgeOutside;
337 unsigned int ccwEdge = mEdgeOutside;
340 mHalfEdge[mHalfEdge[mEdgeOutside]->getNext()]->setPoint( mPointVector.count() - 1 );
343 while (
MathUtils::leftOf( *mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext()]->getPoint()], &p, mPointVector[mHalfEdge[cwEdge]->getPoint()] )
347 mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext()]->getNext()]->setPoint( mPointVector.count() - 1 );
349 cwEdge = (
unsigned int ) mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext();
353 const unsigned int edge1 = insertEdge( mHalfEdge[cwEdge]->getNext(), -10, mHalfEdge[cwEdge]->getPoint(),
false,
false );
354 const unsigned int edge2 = insertEdge( mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual(), -10, -1,
false,
false );
355 const unsigned int edge3 = insertEdge( -10, edge1, mPointVector.count() - 1,
false,
false );
358 mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->setDual( edge2 );
359 mHalfEdge[mHalfEdge[cwEdge]->getNext()]->setDual( edge1 );
360 mHalfEdge[edge1]->setNext( edge2 );
361 mHalfEdge[edge2]->setNext( edge3 );
365 *mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getPoint()],
366 mPointVector[mPointVector.count() - 1],
367 mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->getNext()]->getPoint()]
372 mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->setPoint( mPointVector.count() - 1 );
374 ccwEdge = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->getNext()]->getNext();
378 const unsigned int edge4 = insertEdge( mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext(), -10, mPointVector.count() - 1,
false,
false );
379 const unsigned int edge5 = insertEdge( edge3, -10, -1,
false,
false );
380 const unsigned int edge6
381 = insertEdge( mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual(), edge4, mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getPoint(),
false,
false );
385 mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->setDual( edge6 );
386 mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->setDual( edge4 );
387 mHalfEdge[edge4]->setNext( edge5 );
388 mHalfEdge[edge5]->setNext( edge6 );
389 mHalfEdge[edge3]->setDual( edge5 );
392 unsigned int index = ccwEdge;
397 index = mHalfEdge[mHalfEdge[mHalfEdge[index]->getNext()]->getDual()]->getNext();
398 checkSwapRecursively( toswap, 0 );
399 if ( toswap == cwEdge )
405 else if ( number >= 0 )
407 const int nextnumber = mHalfEdge[number]->getNext();
408 const int nextnextnumber = mHalfEdge[mHalfEdge[number]->getNext()]->getNext();
411 const unsigned int edge1 = insertEdge( -10, nextnumber, mHalfEdge[number]->getPoint(),
false,
false );
412 const unsigned int edge2 = insertEdge(
static_cast<int>( edge1 ), -10, mPointVector.count() - 1,
false,
false );
413 const unsigned int edge3 = insertEdge( -10, nextnextnumber, mHalfEdge[nextnumber]->getPoint(),
false,
false );
414 const unsigned int edge4 = insertEdge(
static_cast<int>( edge3 ),
static_cast<int>( edge1 ), mPointVector.count() - 1,
false,
false );
415 const unsigned int edge5 = insertEdge( -10, number, mHalfEdge[nextnextnumber]->getPoint(),
false,
false );
416 const unsigned int edge6 = insertEdge(
static_cast<int>( edge5 ),
static_cast<int>( edge3 ), mPointVector.count() - 1,
false,
false );
419 mHalfEdge.at( edge1 )->setDual(
static_cast<int>( edge2 ) );
420 mHalfEdge.at( edge2 )->setNext(
static_cast<int>( edge5 ) );
421 mHalfEdge.at( edge3 )->setDual(
static_cast<int>( edge4 ) );
422 mHalfEdge.at( edge5 )->setDual(
static_cast<int>( edge6 ) );
423 mHalfEdge.at( number )->setNext(
static_cast<int>( edge2 ) );
424 mHalfEdge.at( nextnumber )->setNext(
static_cast<int>( edge4 ) );
425 mHalfEdge.at( nextnextnumber )->setNext(
static_cast<int>( edge6 ) );
428 checkSwapRecursively( number, 0 );
429 checkSwapRecursively( nextnumber, 0 );
430 checkSwapRecursively( nextnextnumber, 0 );
433 else if ( number == -20 )
438 const int point1 = mHalfEdge[mEdgeWithPoint]->getPoint();
439 const int point2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getDual()]->getPoint();
440 const double distance1 = p.
distance( *mPointVector[point1] );
446 const double distance2 = p.
distance( *mPointVector[point2] );
453 const int edgea = mEdgeWithPoint;
454 const int edgeb = mHalfEdge[mEdgeWithPoint]->getDual();
455 const int edgec = mHalfEdge[edgea]->getNext();
456 const int edged = mHalfEdge[edgec]->getNext();
457 const int edgee = mHalfEdge[edgeb]->getNext();
458 const int edgef = mHalfEdge[edgee]->getNext();
461 const int nedge1 = insertEdge( -10, mHalfEdge[edgea]->getNext(), mHalfEdge[edgea]->getPoint(),
false,
false );
462 const int nedge2 = insertEdge( nedge1, -10, mPointVector.count() - 1,
false,
false );
463 const int nedge3 = insertEdge( -10, edged, mHalfEdge[edgec]->getPoint(),
false,
false );
464 const int nedge4 = insertEdge( nedge3, nedge1, mPointVector.count() - 1,
false,
false );
465 const int nedge5 = insertEdge( -10, edgef, mHalfEdge[edgee]->getPoint(),
false,
false );
466 const int nedge6 = insertEdge( nedge5, edgeb, mPointVector.count() - 1,
false,
false );
469 mHalfEdge[nedge1]->setDual( nedge2 );
470 mHalfEdge[nedge2]->setNext( nedge5 );
471 mHalfEdge[nedge3]->setDual( nedge4 );
472 mHalfEdge[nedge5]->setDual( nedge6 );
473 mHalfEdge[edgea]->setPoint( mPointVector.count() - 1 );
474 mHalfEdge[edgea]->setNext( nedge3 );
475 mHalfEdge[edgec]->setNext( nedge4 );
476 mHalfEdge[edgee]->setNext( nedge6 );
477 mHalfEdge[edgef]->setNext( nedge2 );
480 checkSwapRecursively( edgec, 0 );
481 checkSwapRecursively( edged, 0 );
482 checkSwapRecursively( edgee, 0 );
483 checkSwapRecursively( edgef, 0 );
486 else if ( number == -100 || number == -5 )
492 else if ( number == -25 )
495 QgsPoint *newPoint = mPointVector[mPointVector.count() - 1];
496 QgsPoint *existingPoint = mPointVector[mTwiceInsPoint];
497 existingPoint->
setZ( std::max( newPoint->
z(), existingPoint->
z() ) );
500 return mTwiceInsPoint;
504 return ( mPointVector.count() - 1 );
507int QgsDualEdgeTriangulation::baseEdgeOfPoint(
int point )
509 unsigned int actedge = mEdgeInside;
511 if ( mPointVector.count() < 4 ||
point == -1 || mDimension == 1 )
513 int fromVirtualPoint = -1;
515 for (
int i = 0; i < mHalfEdge.count(); i++ )
517 if ( mHalfEdge[i]->getPoint() ==
point )
519 if ( mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() != -1 )
522 fromVirtualPoint = i;
525 return fromVirtualPoint;
533 if ( control > 1000000 )
539 for (
int i = 0; i < mHalfEdge.count(); i++ )
541 if ( mHalfEdge[i]->getPoint() ==
point && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 )
548 const int fromPoint = mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint();
549 const int toPoint = mHalfEdge[actedge]->getPoint();
551 if ( fromPoint == -1 || toPoint == -1 )
553 for (
int i = 0; i < mHalfEdge.count(); i++ )
555 if ( mHalfEdge[i]->getPoint() ==
point && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 )
563 const double leftOfNumber =
MathUtils::leftOf( *mPointVector[
point], mPointVector[mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[actedge]->getPoint()] );
566 if ( mHalfEdge[actedge]->getPoint() ==
point && mHalfEdge[mHalfEdge[actedge]->getNext()]->getPoint() != -1 )
568 mEdgeInside = actedge;
571 else if ( leftOfNumber <= 0.0 )
573 actedge = mHalfEdge[actedge]->getNext();
577 actedge = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[actedge]->getDual()]->getNext()]->getNext()]->getDual();
582int QgsDualEdgeTriangulation::baseEdgeOfTriangle(
const QgsPoint &point )
584 unsigned int actEdge = mEdgeInside;
585 if ( mHalfEdge.at( actEdge )->getPoint() < 0 )
586 actEdge = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getNext() )->getDual();
587 if ( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint() < 0 )
588 actEdge = mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getDual();
594 int firstEndPoint = 0, secEndPoint = 0, thEndPoint = 0, fouEndPoint = 0;
598 if ( runs > MAX_BASE_ITERATIONS )
604 const double leftOfValue =
MathUtils::leftOf(
point, mPointVector.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint() ), mPointVector.at( mHalfEdge.at( actEdge )->getPoint() ) );
619 firstEndPoint = mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint();
620 secEndPoint = mHalfEdge.at( actEdge )->getPoint();
622 else if ( nulls == 1 )
625 thEndPoint = mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint();
626 fouEndPoint = mHalfEdge.at( actEdge )->getPoint();
629 mEdgeWithPoint = actEdge;
638 actEdge = mHalfEdge.at( actEdge )->getDual();
643 actEdge = mHalfEdge.at( actEdge )->getNext();
644 if ( mHalfEdge.at( actEdge )->getPoint() == -1 )
650 mEdgeOutside = (
unsigned int ) mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
651 mEdgeInside = mHalfEdge.at( mHalfEdge.at( mEdgeOutside )->getDual() )->getNext();
657 if ( numInstabs > 0 )
660 mUnstableEdge = actEdge;
667 if ( firstEndPoint == thEndPoint || firstEndPoint == fouEndPoint )
670 mTwiceInsPoint = firstEndPoint;
673 else if ( secEndPoint == thEndPoint || secEndPoint == fouEndPoint )
676 mTwiceInsPoint = secEndPoint;
688 mEdgeInside = actEdge;
691 nr1 = mHalfEdge.at( actEdge )->getPoint();
692 nr2 = mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getPoint();
693 nr3 = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext() )->getPoint();
694 const double x1 = mPointVector.at( nr1 )->x();
695 const double y1 = mPointVector.at( nr1 )->y();
696 const double x2 = mPointVector.at( nr2 )->x();
697 const double y2 = mPointVector.at( nr2 )->y();
698 const double x3 = mPointVector.at( nr3 )->x();
699 const double y3 = mPointVector.at( nr3 )->y();
702 if ( x1 < x2 && x1 < x3 )
706 else if ( x2 < x1 && x2 < x3 )
708 return mHalfEdge.at( actEdge )->getNext();
710 else if ( x3 < x1 && x3 < x2 )
712 return mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
723 return mHalfEdge.at( actEdge )->getNext();
730 return mHalfEdge.at( actEdge )->getNext();
734 return mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
745 return mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
753 if ( mTriangleInterpolator )
755 return mTriangleInterpolator->calcNormVec( x, y, result );
766 if ( mTriangleInterpolator )
768 return mTriangleInterpolator->calcPoint( x, y, result );
777bool QgsDualEdgeTriangulation::checkSwapRecursively(
unsigned int edge,
unsigned int recursiveDeep )
779 if ( swapPossible( edge ) )
781 QgsPoint *pta = mPointVector.at( mHalfEdge.at( edge )->getPoint() );
782 QgsPoint *ptb = mPointVector.at( mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getPoint() );
783 QgsPoint *ptc = mPointVector.at( mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getNext() )->getPoint() );
784 QgsPoint *ptd = mPointVector.at( mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext() )->getPoint() );
785 if ( inCircle( *ptd, *pta, *ptb, *ptc ) )
787 doSwapRecursively( edge, recursiveDeep );
794bool QgsDualEdgeTriangulation::isEdgeNeedSwap(
unsigned int edge )
const
796 if ( swapPossible( edge ) )
798 QgsPoint *pta = mPointVector[mHalfEdge[edge]->getPoint()];
799 QgsPoint *ptb = mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()];
800 QgsPoint *ptc = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint()];
801 QgsPoint *ptd = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint()];
802 return inCircle( *ptd, *pta, *ptb, *ptc );
808void QgsDualEdgeTriangulation::doOnlySwap(
unsigned int edge )
810 const unsigned int edge1 = edge;
811 const unsigned int edge2 = mHalfEdge[edge]->getDual();
812 const unsigned int edge3 = mHalfEdge[edge]->getNext();
813 const unsigned int edge4 = mHalfEdge[mHalfEdge[edge]->getNext()]->getNext();
814 const unsigned int edge5 = mHalfEdge[mHalfEdge[edge]->getDual()]->getNext();
815 const unsigned int edge6 = mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getNext();
816 mHalfEdge[edge1]->setNext( edge4 );
817 mHalfEdge[edge2]->setNext( edge6 );
818 mHalfEdge[edge3]->setNext( edge2 );
819 mHalfEdge[edge4]->setNext( edge5 );
820 mHalfEdge[edge5]->setNext( edge1 );
821 mHalfEdge[edge6]->setNext( edge3 );
822 mHalfEdge[edge1]->setPoint( mHalfEdge[edge3]->getPoint() );
823 mHalfEdge[edge2]->setPoint( mHalfEdge[edge5]->getPoint() );
826void QgsDualEdgeTriangulation::doSwapRecursively(
unsigned int edge,
unsigned int recursiveDeep )
828 const unsigned int edge1 = edge;
829 const unsigned int edge2 = mHalfEdge.at( edge )->getDual();
830 const unsigned int edge3 = mHalfEdge.at( edge )->getNext();
831 const unsigned int edge4 = mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getNext();
832 const unsigned int edge5 = mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext();
833 const unsigned int edge6 = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext() )->getNext();
834 mHalfEdge.at( edge1 )->setNext( edge4 );
835 mHalfEdge.at( edge2 )->setNext( edge6 );
836 mHalfEdge.at( edge3 )->setNext( edge2 );
837 mHalfEdge.at( edge4 )->setNext( edge5 );
838 mHalfEdge.at( edge5 )->setNext( edge1 );
839 mHalfEdge.at( edge6 )->setNext( edge3 );
840 mHalfEdge.at( edge1 )->setPoint( mHalfEdge.at( edge3 )->getPoint() );
841 mHalfEdge.at( edge2 )->setPoint( mHalfEdge.at( edge5 )->getPoint() );
844 if ( recursiveDeep < 100 )
846 checkSwapRecursively( edge3, recursiveDeep );
847 checkSwapRecursively( edge6, recursiveDeep );
848 checkSwapRecursively( edge4, recursiveDeep );
849 checkSwapRecursively( edge5, recursiveDeep );
853 QStack<int> edgesToSwap;
854 edgesToSwap.push( edge3 );
855 edgesToSwap.push( edge6 );
856 edgesToSwap.push( edge4 );
857 edgesToSwap.push( edge5 );
859 while ( !edgesToSwap.isEmpty() && loopCount < 10000 )
862 const unsigned int e1 = edgesToSwap.pop();
863 if ( isEdgeNeedSwap( e1 ) )
865 const unsigned int e2 = mHalfEdge.at( e1 )->getDual();
866 const unsigned int e3 = mHalfEdge.at( e1 )->getNext();
867 const unsigned int e4 = mHalfEdge.at( mHalfEdge.at( e1 )->getNext() )->getNext();
868 const unsigned int e5 = mHalfEdge.at( mHalfEdge.at( e1 )->getDual() )->getNext();
869 const unsigned int e6 = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( e1 )->getDual() )->getNext() )->getNext();
870 mHalfEdge.at( e1 )->setNext( e4 );
871 mHalfEdge.at( e2 )->setNext( e6 );
872 mHalfEdge.at( e3 )->setNext( e2 );
873 mHalfEdge.at( e4 )->setNext( e5 );
874 mHalfEdge.at( e5 )->setNext( e1 );
875 mHalfEdge.at( e6 )->setNext( e3 );
876 mHalfEdge.at( e1 )->setPoint( mHalfEdge.at( e3 )->getPoint() );
877 mHalfEdge.at( e2 )->setPoint( mHalfEdge.at( e5 )->getPoint() );
879 edgesToSwap.push( e3 );
880 edgesToSwap.push( e6 );
881 edgesToSwap.push( e4 );
882 edgesToSwap.push( e5 );
889void DualEdgeTriangulation::draw( QPainter *p,
double xlowleft,
double ylowleft,
double xupright,
double yupright,
double width,
double height )
const
892 if ( mPointVector.isEmpty() )
897 p->setPen( mEdgeColor );
899 bool *control =
new bool[mHalfEdge.count()];
900 bool *control2 =
new bool[mHalfEdge.count()];
902 for (
unsigned int i = 0; i <= mHalfEdge.count() - 1; i++ )
908 if ( ( ( xupright - xlowleft ) / width ) > ( ( yupright - ylowleft ) / height ) )
910 double lowerborder = -( height * ( xupright - xlowleft ) / width - yupright );
911 for (
unsigned int i = 0; i < mHalfEdge.count() - 1; i++ )
913 if ( mHalfEdge[i]->getPoint() == -1 || mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() == -1 )
920 if ( mHalfEdge[i]->getPoint() != -1 && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 && mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint() != -1 )
922 p1 = mPointVector[mHalfEdge[i]->getPoint()]->getZ();
923 p2 = mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getZ();
924 p3 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getZ();
925 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 ) )
928 pa.setPoint( 0, ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( xupright - xlowleft )*width );
929 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 );
930 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 );
931 QColor
c( 255, 0, 0 );
933 p->drawPolygon( pa );
938 control2[mHalfEdge[i]->getNext()] =
true;
939 control2[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()] =
true;
946 if ( halfEdgeBBoxTest( i, xlowleft, lowerborder, xupright, yupright ) )
948 if ( mHalfEdge[i]->getBreak() )
950 p->setPen( mBreakEdgeColor );
952 else if ( mHalfEdge[i]->getForced() )
954 p->setPen( mForcedEdgeColor );
958 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 );
960 if ( mHalfEdge[i]->getForced() )
962 p->setPen( mEdgeColor );
968 control[mHalfEdge[i]->getDual()] =
true;
973 double rightborder = width * ( yupright - ylowleft ) / height + xlowleft;
974 for (
unsigned int i = 0; i < mHalfEdge.count() - 1; i++ )
976 if ( mHalfEdge[i]->getPoint() == -1 || mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() == -1 )
983 if ( mHalfEdge[i]->getPoint() != -1 && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 && mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint() != -1 )
985 p1 = mPointVector[mHalfEdge[i]->getPoint()]->getZ();
986 p2 = mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getZ();
987 p3 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getZ();
988 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 ) )
991 pa.setPoint( 0, ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( yupright - ylowleft )*height );
992 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 );
993 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 );
994 QColor
c( 255, 0, 0 );
996 p->drawPolygon( pa );
1001 control2[mHalfEdge[i]->getNext()] =
true;
1002 control2[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()] =
true;
1010 if ( halfEdgeBBoxTest( i, xlowleft, ylowleft, rightborder, yupright ) )
1012 if ( mHalfEdge[i]->getBreak() )
1014 p->setPen( mBreakEdgeColor );
1016 else if ( mHalfEdge[i]->getForced() )
1018 p->setPen( mForcedEdgeColor );
1021 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 );
1023 if ( mHalfEdge[i]->getForced() )
1025 p->setPen( mEdgeColor );
1030 control[mHalfEdge[i]->getDual()] =
true;
1042 const int firstedge = baseEdgeOfPoint( p2 );
1046 int nextnextedge = firstedge;
1050 edge = mHalfEdge[nextnextedge]->getDual();
1051 if ( mHalfEdge[edge]->getPoint() == p1 )
1053 theedge = nextnextedge;
1056 nextedge = mHalfEdge[edge]->getNext();
1057 nextnextedge = mHalfEdge[nextedge]->getNext();
1058 }
while ( nextnextedge != firstedge );
1060 if ( theedge == -10 )
1067 return mHalfEdge[mHalfEdge[mHalfEdge[theedge]->getDual()]->getNext()]->getPoint();
1072 const int firstedge = baseEdgeOfPoint( pointno );
1075 if ( firstedge == -1 )
1080 int actedge = firstedge;
1081 int edge, nextedge, nextnextedge;
1084 edge = mHalfEdge[actedge]->getDual();
1085 vlist.append( mHalfEdge[edge]->getPoint() );
1086 nextedge = mHalfEdge[edge]->getNext();
1087 vlist.append( mHalfEdge[nextedge]->getPoint() );
1088 nextnextedge = mHalfEdge[nextedge]->getNext();
1089 vlist.append( mHalfEdge[nextnextedge]->getPoint() );
1090 if ( mHalfEdge[nextnextedge]->getBreak() )
1092 vlist.append( -10 );
1096 vlist.append( -20 );
1098 actedge = nextnextedge;
1099 }
while ( nextnextedge != firstedge );
1106 if ( mPointVector.size() < 3 )
1112 const int edge = baseEdgeOfTriangle(
point );
1118 else if ( edge >= 0 )
1120 const int ptnr1 = mHalfEdge[edge]->getPoint();
1121 const int ptnr2 = mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint();
1122 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint();
1123 p1.
setX( mPointVector[ptnr1]->x() );
1124 p1.
setY( mPointVector[ptnr1]->y() );
1125 p1.
setZ( mPointVector[ptnr1]->z() );
1126 p2.
setX( mPointVector[ptnr2]->x() );
1127 p2.
setY( mPointVector[ptnr2]->y() );
1128 p2.
setZ( mPointVector[ptnr2]->z() );
1129 p3.
setX( mPointVector[ptnr3]->x() );
1130 p3.
setY( mPointVector[ptnr3]->y() );
1131 p3.
setZ( mPointVector[ptnr3]->z() );
1137 else if ( edge == -20 )
1139 const int ptnr1 = mHalfEdge[mEdgeWithPoint]->getPoint();
1140 const int ptnr2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getPoint();
1141 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getNext()]->getPoint();
1142 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1146 p1.
setX( mPointVector[ptnr1]->x() );
1147 p1.
setY( mPointVector[ptnr1]->y() );
1148 p1.
setZ( mPointVector[ptnr1]->z() );
1149 p2.
setX( mPointVector[ptnr2]->x() );
1150 p2.
setY( mPointVector[ptnr2]->y() );
1151 p2.
setZ( mPointVector[ptnr2]->z() );
1152 p3.
setX( mPointVector[ptnr3]->x() );
1153 p3.
setY( mPointVector[ptnr3]->y() );
1154 p3.
setZ( mPointVector[ptnr3]->z() );
1160 else if ( edge == -25 )
1162 const int edge1 = baseEdgeOfPoint( mTwiceInsPoint );
1163 const int edge2 = mHalfEdge[edge1]->getNext();
1164 const int edge3 = mHalfEdge[edge2]->getNext();
1165 const int ptnr1 = mHalfEdge[edge1]->getPoint();
1166 const int ptnr2 = mHalfEdge[edge2]->getPoint();
1167 const int ptnr3 = mHalfEdge[edge3]->getPoint();
1168 p1.
setX( mPointVector[ptnr1]->x() );
1169 p1.
setY( mPointVector[ptnr1]->y() );
1170 p1.
setZ( mPointVector[ptnr1]->z() );
1171 p2.
setX( mPointVector[ptnr2]->x() );
1172 p2.
setY( mPointVector[ptnr2]->y() );
1173 p2.
setZ( mPointVector[ptnr2]->z() );
1174 p3.
setX( mPointVector[ptnr3]->x() );
1175 p3.
setY( mPointVector[ptnr3]->y() );
1176 p3.
setZ( mPointVector[ptnr3]->z() );
1182 else if ( edge == -5 )
1184 const int ptnr1 = mHalfEdge[mUnstableEdge]->getPoint();
1185 const int ptnr2 = mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getPoint();
1186 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getNext()]->getPoint();
1187 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1191 p1.
setX( mPointVector[ptnr1]->x() );
1192 p1.
setY( mPointVector[ptnr1]->y() );
1193 p1.
setZ( mPointVector[ptnr1]->z() );
1194 p2.
setX( mPointVector[ptnr2]->x() );
1195 p2.
setY( mPointVector[ptnr2]->y() );
1196 p2.
setZ( mPointVector[ptnr2]->z() );
1197 p3.
setX( mPointVector[ptnr3]->x() );
1198 p3.
setY( mPointVector[ptnr3]->y() );
1199 p3.
setZ( mPointVector[ptnr3]->z() );
1214 if ( mPointVector.size() < 3 )
1220 const int edge = baseEdgeOfTriangle(
point );
1225 else if ( edge >= 0 )
1227 const int ptnr1 = mHalfEdge[edge]->getPoint();
1228 const int ptnr2 = mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint();
1229 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint();
1230 p1.
setX( mPointVector[ptnr1]->x() );
1231 p1.
setY( mPointVector[ptnr1]->y() );
1232 p1.
setZ( mPointVector[ptnr1]->z() );
1233 p2.
setX( mPointVector[ptnr2]->x() );
1234 p2.
setY( mPointVector[ptnr2]->y() );
1235 p2.
setZ( mPointVector[ptnr2]->z() );
1236 p3.
setX( mPointVector[ptnr3]->x() );
1237 p3.
setY( mPointVector[ptnr3]->y() );
1238 p3.
setZ( mPointVector[ptnr3]->z() );
1241 else if ( edge == -20 )
1243 const int ptnr1 = mHalfEdge[mEdgeWithPoint]->getPoint();
1244 const int ptnr2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getPoint();
1245 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getNext()]->getPoint();
1246 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1250 p1.
setX( mPointVector[ptnr1]->x() );
1251 p1.
setY( mPointVector[ptnr1]->y() );
1252 p1.
setZ( mPointVector[ptnr1]->z() );
1253 p2.
setX( mPointVector[ptnr2]->x() );
1254 p2.
setY( mPointVector[ptnr2]->y() );
1255 p2.
setZ( mPointVector[ptnr2]->z() );
1256 p3.
setX( mPointVector[ptnr3]->x() );
1257 p3.
setY( mPointVector[ptnr3]->y() );
1258 p3.
setZ( mPointVector[ptnr3]->z() );
1261 else if ( edge == -25 )
1263 const int edge1 = baseEdgeOfPoint( mTwiceInsPoint );
1264 const int edge2 = mHalfEdge[edge1]->getNext();
1265 const int edge3 = mHalfEdge[edge2]->getNext();
1266 const int ptnr1 = mHalfEdge[edge1]->getPoint();
1267 const int ptnr2 = mHalfEdge[edge2]->getPoint();
1268 const int ptnr3 = mHalfEdge[edge3]->getPoint();
1269 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1273 p1.
setX( mPointVector[ptnr1]->x() );
1274 p1.
setY( mPointVector[ptnr1]->y() );
1275 p1.
setZ( mPointVector[ptnr1]->z() );
1276 p2.
setX( mPointVector[ptnr2]->x() );
1277 p2.
setY( mPointVector[ptnr2]->y() );
1278 p2.
setZ( mPointVector[ptnr2]->z() );
1279 p3.
setX( mPointVector[ptnr3]->x() );
1280 p3.
setY( mPointVector[ptnr3]->y() );
1281 p3.
setZ( mPointVector[ptnr3]->z() );
1284 else if ( edge == -5 )
1286 const int ptnr1 = mHalfEdge[mUnstableEdge]->getPoint();
1287 const int ptnr2 = mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getPoint();
1288 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getNext()]->getPoint();
1289 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1293 p1.
setX( mPointVector[ptnr1]->x() );
1294 p1.
setY( mPointVector[ptnr1]->y() );
1295 p1.
setZ( mPointVector[ptnr1]->z() );
1296 p2.
setX( mPointVector[ptnr2]->x() );
1297 p2.
setY( mPointVector[ptnr2]->y() );
1298 p2.
setZ( mPointVector[ptnr2]->z() );
1299 p3.
setX( mPointVector[ptnr3]->x() );
1300 p3.
setY( mPointVector[ptnr3]->y() );
1301 p3.
setZ( mPointVector[ptnr3]->z() );
1310unsigned int QgsDualEdgeTriangulation::insertEdge(
int dual,
int next,
int point,
bool mbreak,
bool forced )
1313 mHalfEdge.append( edge );
1314 return mHalfEdge.count() - 1;
1317static bool altitudeTriangleIsSmall(
const QgsPoint &pointBase1,
const QgsPoint &pointBase2,
const QgsPoint &pt3,
double tolerance )
1320 const double x1 = pointBase1.
x();
1321 const double y1 = pointBase1.
y();
1322 const double x2 = pointBase2.
x();
1323 const double y2 = pointBase2.
y();
1324 const double X = pt3.
x();
1325 const double Y = pt3.
y();
1334 t = ( X * ny - Y * nx - x1 * ny + y1 * nx ) / ( ( x2 - x1 ) * ny - ( y2 - y1 ) * nx );
1335 projectedPoint.
setX( x1 + t * ( x2 - x1 ) );
1336 projectedPoint.
setY( y1 + t * ( y2 - y1 ) );
1338 return pt3.
distance( projectedPoint ) < tolerance;
1348 QgsPoint *point1 = mPointVector.at( p1 );
1349 QgsPoint *point2 = mPointVector.at( p2 );
1352 QList<int> crossedEdges;
1355 int pointingEdge = 0;
1357 pointingEdge = baseEdgeOfPoint( p1 );
1359 if ( pointingEdge == -1 )
1365 int actEdge = mHalfEdge[pointingEdge]->getDual();
1366 const int firstActEdge = actEdge;
1373 if ( control > 100 )
1379 if ( mHalfEdge[actEdge]->getPoint() == -1 )
1381 actEdge = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getNext()]->getDual();
1386 if ( mHalfEdge[actEdge]->getPoint() == p2 )
1388 mHalfEdge[actEdge]->setForced(
true );
1390 mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced(
true );
1396 if ( ( point2->
y() - point1->
y() ) / ( mPointVector[mHalfEdge[actEdge]->getPoint()]->y() - point1->
y() )
1397 == ( point2->
x() - point1->
x() ) / ( mPointVector[mHalfEdge[actEdge]->getPoint()]->x() - point1->
x() )
1398 && ( ( point2->
y() - point1->
y() ) >= 0 ) == ( ( mPointVector[mHalfEdge[actEdge]->getPoint()]->y() - point1->
y() ) > 0 )
1399 && ( ( point2->
x() - point1->
x() ) >= 0 ) == ( ( mPointVector[mHalfEdge[actEdge]->getPoint()]->x() - point1->
x() ) > 0 ) )
1402 mHalfEdge[actEdge]->setForced(
true );
1404 mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced(
true );
1406 const int a = insertForcedSegment( mHalfEdge[actEdge]->getPoint(), p2, segmentType );
1411 const int oppositeEdge = mHalfEdge[actEdge]->getNext();
1413 if ( mHalfEdge[oppositeEdge]->getPoint() == -1 || mHalfEdge[mHalfEdge[oppositeEdge]->getDual()]->getPoint() == -1 )
1415 actEdge = mHalfEdge[mHalfEdge[oppositeEdge]->getNext()]->getDual();
1419 QgsPoint *oppositePoint1 = mPointVector[mHalfEdge[oppositeEdge]->getPoint()];
1420 QgsPoint *oppositePoint2 = mPointVector[mHalfEdge[mHalfEdge[oppositeEdge]->getDual()]->getPoint()];
1422 if ( altitudeTriangleIsSmall( *oppositePoint1, *oppositePoint2, *point1, oppositePoint1->
distance( *oppositePoint2 ) / 500 ) )
1428 if (
MathUtils::lineIntersection( point1, point2, mPointVector[mHalfEdge[oppositeEdge]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[oppositeEdge]->getDual()]->getPoint()] ) )
1430 if ( mHalfEdge[mHalfEdge[actEdge]->getNext()]->getForced()
1433 QgsPoint crosspoint( 0, 0, 0 );
1435 p3 = mHalfEdge[mHalfEdge[actEdge]->getNext()]->getPoint();
1436 p4 = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getDual()]->getPoint();
1438 const double dista = crosspoint.distance( *mPointVector[p3] );
1439 const double distb = crosspoint.distance( *mPointVector[p4] );
1440 if ( dista <= distb )
1442 insertForcedSegment( p1, p3, segmentType );
1443 const int e = insertForcedSegment( p3, p2, segmentType );
1446 else if ( distb <= dista )
1448 insertForcedSegment( p1, p4, segmentType );
1449 const int e = insertForcedSegment( p4, p2, segmentType );
1454 if ( mHalfEdge[mHalfEdge[actEdge]->getNext()]->getForced()
1457 QgsPoint crosspoint( 0, 0, 0 );
1459 p3 = mHalfEdge[mHalfEdge[actEdge]->getNext()]->getPoint();
1460 p4 = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getDual()]->getPoint();
1462 const double distpart = crosspoint.distance( *mPointVector[p4] );
1463 const double disttot = mPointVector[p3]->distance( *mPointVector[p4] );
1464 const float frac = distpart / disttot;
1466 if ( frac == 0 || frac == 1 )
1471 mHalfEdge[actEdge]->setForced(
true );
1473 mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced(
true );
1475 const int a = insertForcedSegment( p4, p2, segmentType );
1478 else if ( frac == 1 )
1481 mHalfEdge[actEdge]->setForced(
true );
1483 mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced(
true );
1487 const int a = insertForcedSegment( p3, p2, segmentType );
1498 const int newpoint = splitHalfEdge( mHalfEdge[actEdge]->getNext(), frac );
1499 insertForcedSegment( p1, newpoint, segmentType );
1500 const int e = insertForcedSegment( newpoint, p2, segmentType );
1506 crossedEdges.append( oppositeEdge );
1509 actEdge = mHalfEdge[mHalfEdge[oppositeEdge]->getNext()]->getDual();
1510 }
while ( actEdge != firstActEdge );
1512 if ( crossedEdges.isEmpty() )
1514 int lastEdgeOppositePointIndex = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1517 while ( lastEdgeOppositePointIndex != p2 )
1519 QgsPoint *lastEdgePoint1 = mPointVector[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint()];
1520 QgsPoint *lastEdgePoint2 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint()];
1521 QgsPoint *lastEdgeOppositePoint = mPointVector[lastEdgeOppositePointIndex];
1525 if ( mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getForced()
1526 && mForcedCrossBehavior
1529 QgsPoint crosspoint( 0, 0, 0 );
1531 p3 = mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint();
1532 p4 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1534 const double dista = crosspoint.distance( *mPointVector[p3] );
1535 const double distb = crosspoint.distance( *mPointVector[p4] );
1536 if ( dista <= distb )
1538 insertForcedSegment( p1, p3, segmentType );
1539 const int e = insertForcedSegment( p3, p2, segmentType );
1542 else if ( distb <= dista )
1544 insertForcedSegment( p1, p4, segmentType );
1545 const int e = insertForcedSegment( p4, p2, segmentType );
1549 else if ( mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getForced()
1552 QgsPoint crosspoint( 0, 0, 0 );
1554 p3 = mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint();
1555 p4 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1557 const double distpart = crosspoint.distance( *mPointVector[p3] );
1558 const double disttot = mPointVector[p3]->distance( *mPointVector[p4] );
1559 const float frac = distpart / disttot;
1560 if ( frac == 0 || frac == 1 )
1564 const int newpoint = splitHalfEdge( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext(), frac );
1565 insertForcedSegment( p1, newpoint, segmentType );
1566 const int e = insertForcedSegment( newpoint, p2, segmentType );
1570 crossedEdges.append( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext() );
1574 if ( mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getForced()
1575 && mForcedCrossBehavior
1578 QgsPoint crosspoint( 0, 0, 0 );
1580 p3 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1581 p4 = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint();
1583 const double dista = crosspoint.distance( *mPointVector[p3] );
1584 const double distb = crosspoint.distance( *mPointVector[p4] );
1585 if ( dista <= distb )
1587 insertForcedSegment( p1, p3, segmentType );
1588 const int e = insertForcedSegment( p3, p2, segmentType );
1591 else if ( distb <= dista )
1593 insertForcedSegment( p1, p4, segmentType );
1594 const int e = insertForcedSegment( p4, p2, segmentType );
1598 else if ( mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getForced()
1601 QgsPoint crosspoint( 0, 0, 0 );
1603 p3 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1604 p4 = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint();
1606 const double distpart = crosspoint.distance( *mPointVector[p3] );
1607 const double disttot = mPointVector[p3]->distance( *mPointVector[p4] );
1608 const float frac = distpart / disttot;
1609 if ( frac == 0 || frac == 1 )
1613 const int newpoint = splitHalfEdge( mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext(), frac );
1614 insertForcedSegment( p1, newpoint, segmentType );
1615 const int e = insertForcedSegment( newpoint, p2, segmentType );
1619 crossedEdges.append( mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext() );
1626 lastEdgeOppositePointIndex = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1630 QgsPoint *lastEdgePoint1 = mPointVector[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint()];
1631 QgsPoint *lastEdgePoint2 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint()];
1632 QgsPoint *lastEdgeOppositePoint = mPointVector[lastEdgeOppositePointIndex];
1633 if ( altitudeTriangleIsSmall( *lastEdgePoint1, *lastEdgePoint2, *lastEdgeOppositePoint, lastEdgePoint1->
distance( *lastEdgePoint2 ) / 500 ) )
1637 QList<int>::const_iterator iter;
1638 for ( iter = crossedEdges.constBegin(); iter != crossedEdges.constEnd(); ++iter )
1640 mHalfEdge[( *( iter ) )]->setForced(
false );
1641 mHalfEdge[( *( iter ) )]->setBreak(
false );
1642 mHalfEdge[mHalfEdge[( *( iter ) )]->getDual()]->setForced(
false );
1643 mHalfEdge[mHalfEdge[( *( iter ) )]->getDual()]->setBreak(
false );
1648 QList<int> freelist = crossedEdges;
1651 QList<int> leftPolygon;
1652 QList<int> rightPolygon;
1655 const int firstedge = freelist.first();
1656 mHalfEdge[firstedge]->setForced(
true );
1658 leftPolygon.append( firstedge );
1659 const int dualfirstedge = mHalfEdge[freelist.first()]->getDual();
1660 mHalfEdge[dualfirstedge]->setForced(
true );
1662 rightPolygon.append( dualfirstedge );
1663 freelist.pop_front();
1667 QList<int>::const_iterator leftiter;
1668 leftiter = crossedEdges.constEnd();
1672 const int newpoint = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[( *leftiter )]->getDual()]->getNext()]->getNext()]->getPoint();
1673 if ( newpoint != actpointl )
1676 actpointl = newpoint;
1677 const int theedge = mHalfEdge[mHalfEdge[mHalfEdge[( *leftiter )]->getDual()]->getNext()]->getNext();
1678 leftPolygon.append( theedge );
1680 if ( leftiter == crossedEdges.constBegin() )
1688 leftPolygon.append( mHalfEdge[crossedEdges.first()]->getNext() );
1691 QList<int>::const_iterator rightiter;
1693 for ( rightiter = crossedEdges.constBegin(); rightiter != crossedEdges.constEnd(); ++rightiter )
1695 const int newpoint = mHalfEdge[mHalfEdge[mHalfEdge[( *rightiter )]->getNext()]->getNext()]->getPoint();
1696 if ( newpoint != actpointr )
1699 actpointr = newpoint;
1700 const int theedge = mHalfEdge[mHalfEdge[( *rightiter )]->getNext()]->getNext();
1701 rightPolygon.append( theedge );
1707 rightPolygon.append( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext() );
1708 mHalfEdge[rightPolygon.last()]->setNext( dualfirstedge );
1711 int actedgel = leftPolygon[1];
1712 leftiter = leftPolygon.constBegin();
1714 for ( ; leftiter != leftPolygon.constEnd(); ++leftiter )
1716 mHalfEdge[actedgel]->setNext( ( *leftiter ) );
1717 actedgel = ( *leftiter );
1721 int actedger = rightPolygon[1];
1722 rightiter = rightPolygon.constBegin();
1724 for ( ; rightiter != rightPolygon.constEnd(); ++rightiter )
1726 mHalfEdge[actedger]->setNext( ( *rightiter ) );
1727 actedger = ( *( rightiter ) );
1732 mHalfEdge[leftPolygon.first()]->setNext( ( *( ++( leftiter = leftPolygon.constBegin() ) ) ) );
1733 mHalfEdge[leftPolygon.first()]->setPoint( p2 );
1734 mHalfEdge[leftPolygon.last()]->setNext( firstedge );
1735 mHalfEdge[rightPolygon.first()]->setNext( ( *( ++( rightiter = rightPolygon.constBegin() ) ) ) );
1736 mHalfEdge[rightPolygon.first()]->setPoint( p1 );
1737 mHalfEdge[rightPolygon.last()]->setNext( dualfirstedge );
1739 triangulatePolygon( &leftPolygon, &freelist, firstedge );
1740 triangulatePolygon( &rightPolygon, &freelist, dualfirstedge );
1743 for ( iter = crossedEdges.constBegin(); iter != crossedEdges.constEnd(); ++iter )
1745 checkSwapRecursively( ( *( iter ) ), 0 );
1748 return leftPolygon.first();
1753 mForcedCrossBehavior = b;
1758 mTriangleInterpolator = interpolator;
1764 const double minangle = 0;
1768 bool swapped =
false;
1769 bool *control =
new bool[mHalfEdge.count()];
1771 for (
int i = 0; i <= mHalfEdge.count() - 1; i++ )
1777 for (
int i = 0; i <= mHalfEdge.count() - 1; i++ )
1786 e2 = mHalfEdge[e1]->getNext();
1787 e3 = mHalfEdge[e2]->getNext();
1790 p1 = mHalfEdge[e1]->getPoint();
1791 p2 = mHalfEdge[e2]->getPoint();
1792 p3 = mHalfEdge[e3]->getPoint();
1795 if ( p1 == -1 || p2 == -1 || p3 == -1 )
1803 double el1, el2, el3;
1804 el1 = mPointVector[p1]->z();
1805 el2 = mPointVector[p2]->z();
1806 el3 = mPointVector[p3]->z();
1808 if ( el1 == el2 && el2 == el3 )
1811 if ( swapPossible( ( uint ) e1 ) && mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[e1]->getDual()]->getNext()]->getPoint()]->z() != el1 && swapMinAngle( e1 ) > minangle )
1813 doOnlySwap( ( uint ) e1 );
1816 else if ( swapPossible( ( uint ) e2 ) && mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[e2]->getDual()]->getNext()]->getPoint()]->z() != el2 && swapMinAngle( e2 ) > minangle )
1818 doOnlySwap( ( uint ) e2 );
1821 else if ( swapPossible( ( uint ) e3 ) && mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[e3]->getDual()]->getNext()]->getPoint()]->z() != el3 && swapMinAngle( e3 ) > minangle )
1823 doOnlySwap( ( uint ) e3 );
1853 const double mintol = 17;
1856 std::map<int, double> edge_angle;
1857 std::multimap<double, int> angle_edge;
1858 QSet<int> dontexamine;
1867 const int nhalfedges = mHalfEdge.count();
1869 for (
int i = 0; i < nhalfedges - 1; i++ )
1871 const int next = mHalfEdge[i]->getNext();
1872 const int nextnext = mHalfEdge[next]->getNext();
1874 if ( mHalfEdge[next]->getPoint() != -1
1875 && ( mHalfEdge[i]->getForced() || mHalfEdge[mHalfEdge[mHalfEdge[i]->getDual()]->getNext()]->getPoint() == -1 ) )
1877 if ( !( ( mHalfEdge[next]->getForced() || edgeOnConvexHull( next ) )
1878 || ( mHalfEdge[nextnext]->getForced() || edgeOnConvexHull( nextnext ) ) ) )
1881 while (
MathUtils::inDiametral( mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()], mPointVector[mHalfEdge[i]->getPoint()], mPointVector[mHalfEdge[next]->getPoint()] ) )
1884 const int pointno = splitHalfEdge( i, 0.5 );
1896 for (
int i = 0; i < mHalfEdge.count() - 1; i++ )
1898 p1 = mHalfEdge[mHalfEdge[i]->getDual()]->getPoint();
1899 p2 = mHalfEdge[i]->getPoint();
1900 p3 = mHalfEdge[mHalfEdge[i]->getNext()]->getPoint();
1902 if ( p1 == -1 || p2 == -1 || p3 == -1 )
1906 angle =
MathUtils::angle( mPointVector[p1], mPointVector[p2], mPointVector[p3], mPointVector[p2] );
1908 bool twoforcededges;
1911 twoforcededges = ( mHalfEdge[i]->getForced() || edgeOnConvexHull( i ) ) && ( mHalfEdge[mHalfEdge[i]->getNext()]->getForced() || edgeOnConvexHull( mHalfEdge[i]->getNext() ) );
1913 if ( angle < mintol && !twoforcededges )
1915 edge_angle.insert( std::make_pair( i, angle ) );
1916 angle_edge.insert( std::make_pair( angle, i ) );
1921 for ( std::multimap<double, int>::const_iterator it = angle_edge.begin(); it != angle_edge.end(); ++it )
1927 double minangle = 0;
1930 int minedgenextnext;
1934 while ( !edge_angle.empty() )
1936 minangle = angle_edge.begin()->first;
1938 minedge = angle_edge.begin()->second;
1939 minedgenext = mHalfEdge[minedge]->getNext();
1940 minedgenextnext = mHalfEdge[minedgenext]->getNext();
1943 if ( !
MathUtils::circumcenter( mPointVector[mHalfEdge[minedge]->getPoint()], mPointVector[mHalfEdge[minedgenext]->getPoint()], mPointVector[mHalfEdge[minedgenextnext]->getPoint()], &circumcenter ) )
1945 QgsDebugError( u
"warning, calculation of circumcenter failed"_s );
1947 dontexamine.insert( minedge );
1948 edge_angle.erase( minedge );
1949 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
1950 while ( minedgeiter->second != minedge )
1954 angle_edge.erase( minedgeiter );
1958 if ( !
pointInside( circumcenter.x(), circumcenter.y() ) )
1961 QgsDebugError( u
"put circumcenter %1//%2 on dontexamine list because it is outside the convex hull"_s.arg( circumcenter.x() ).arg( circumcenter.y() ) );
1962 dontexamine.insert( minedge );
1963 edge_angle.erase( minedge );
1964 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
1965 while ( minedgeiter->second != minedge )
1969 angle_edge.erase( minedgeiter );
1975 bool encroached =
false;
1978 int numhalfedges = mHalfEdge.count();
1979 for (
int i = 0; i < numhalfedges; i++ )
1981 if ( mHalfEdge[i]->getForced() || edgeOnConvexHull( i ) )
1983 if (
MathUtils::inDiametral( mPointVector[mHalfEdge[i]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()], &circumcenter ) )
1988 int pointno = splitHalfEdge( i, 0.5 );
1991 int pointingedge = baseEdgeOfPoint( pointno );
1993 int actedge = pointingedge;
1996 double angle1, angle2, angle3;
2000 ed1 = mHalfEdge[actedge]->getDual();
2001 pt1 = mHalfEdge[ed1]->getPoint();
2002 ed2 = mHalfEdge[ed1]->getNext();
2003 pt2 = mHalfEdge[ed2]->getPoint();
2004 ed3 = mHalfEdge[ed2]->getNext();
2005 pt3 = mHalfEdge[ed3]->getPoint();
2008 if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
2013 angle1 =
MathUtils::angle( mPointVector[pt3], mPointVector[pt1], mPointVector[pt2], mPointVector[pt1] );
2014 angle2 =
MathUtils::angle( mPointVector[pt1], mPointVector[pt2], mPointVector[pt3], mPointVector[pt2] );
2015 angle3 =
MathUtils::angle( mPointVector[pt2], mPointVector[pt3], mPointVector[pt1], mPointVector[pt3] );
2018 bool twoforcededges1, twoforcededges2, twoforcededges3;
2020 if ( ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) && ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) )
2022 twoforcededges1 =
true;
2026 twoforcededges1 =
false;
2029 if ( ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) && ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) )
2031 twoforcededges2 =
true;
2035 twoforcededges2 =
false;
2038 if ( ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) && ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) )
2040 twoforcededges3 =
true;
2044 twoforcededges3 =
false;
2048 QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
2049 if ( ed1iter != dontexamine.end() )
2052 dontexamine.erase( ed1iter );
2057 std::map<int, double>::iterator tempit1;
2058 tempit1 = edge_angle.find( ed1 );
2059 if ( tempit1 != edge_angle.end() )
2062 double angle = tempit1->second;
2063 edge_angle.erase( ed1 );
2064 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2065 while ( tempit2->second != ed1 )
2069 angle_edge.erase( tempit2 );
2073 if ( angle1 < mintol && !twoforcededges1 )
2075 edge_angle.insert( std::make_pair( ed1, angle1 ) );
2076 angle_edge.insert( std::make_pair( angle1, ed1 ) );
2080 QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
2081 if ( ed2iter != dontexamine.end() )
2084 dontexamine.erase( ed2iter );
2089 std::map<int, double>::iterator tempit1;
2090 tempit1 = edge_angle.find( ed2 );
2091 if ( tempit1 != edge_angle.end() )
2094 double angle = tempit1->second;
2095 edge_angle.erase( ed2 );
2096 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2097 while ( tempit2->second != ed2 )
2101 angle_edge.erase( tempit2 );
2105 if ( angle2 < mintol && !twoforcededges2 )
2107 edge_angle.insert( std::make_pair( ed2, angle2 ) );
2108 angle_edge.insert( std::make_pair( angle2, ed2 ) );
2112 QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
2113 if ( ed3iter != dontexamine.end() )
2116 dontexamine.erase( ed3iter );
2121 std::map<int, double>::iterator tempit1;
2122 tempit1 = edge_angle.find( ed3 );
2123 if ( tempit1 != edge_angle.end() )
2126 double angle = tempit1->second;
2127 edge_angle.erase( ed3 );
2128 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2129 while ( tempit2->second != ed3 )
2133 angle_edge.erase( tempit2 );
2137 if ( angle3 < mintol && !twoforcededges3 )
2139 edge_angle.insert( std::make_pair( ed3, angle3 ) );
2140 angle_edge.insert( std::make_pair( angle3, ed3 ) );
2145 while ( actedge != pointingedge );
2153 QSet<int> influenceedges;
2154 int baseedge = baseEdgeOfTriangle( circumcenter );
2155 if ( baseedge == -5 )
2158 edge_angle.erase( minedge );
2159 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
2160 while ( minedgeiter->second != minedge )
2164 angle_edge.erase( minedgeiter );
2167 else if ( baseedge == -25 )
2170 edge_angle.erase( minedge );
2171 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
2172 while ( minedgeiter->second != minedge )
2176 angle_edge.erase( minedgeiter );
2179 else if ( baseedge == -20 )
2181 baseedge = mEdgeWithPoint;
2184 evaluateInfluenceRegion( &circumcenter, baseedge, influenceedges );
2185 evaluateInfluenceRegion( &circumcenter, mHalfEdge[baseedge]->getNext(), influenceedges );
2186 evaluateInfluenceRegion( &circumcenter, mHalfEdge[mHalfEdge[baseedge]->getNext()]->getNext(), influenceedges );
2188 for ( QSet<int>::iterator it = influenceedges.begin(); it != influenceedges.end(); ++it )
2190 if ( ( mHalfEdge[*it]->getForced() || edgeOnConvexHull( *it ) )
2191 &&
MathUtils::inDiametral( mPointVector[mHalfEdge[*it]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[*it]->getDual()]->getPoint()], &circumcenter ) )
2195 const int pointno = splitHalfEdge( *it, 0.5 );
2199 const int pointingedge = baseEdgeOfPoint( pointno );
2201 int actedge = pointingedge;
2204 double angle1, angle2, angle3;
2208 ed1 = mHalfEdge[actedge]->getDual();
2209 pt1 = mHalfEdge[ed1]->getPoint();
2210 ed2 = mHalfEdge[ed1]->getNext();
2211 pt2 = mHalfEdge[ed2]->getPoint();
2212 ed3 = mHalfEdge[ed2]->getNext();
2213 pt3 = mHalfEdge[ed3]->getPoint();
2216 if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
2221 angle1 =
MathUtils::angle( mPointVector[pt3], mPointVector[pt1], mPointVector[pt2], mPointVector[pt1] );
2222 angle2 =
MathUtils::angle( mPointVector[pt1], mPointVector[pt2], mPointVector[pt3], mPointVector[pt2] );
2223 angle3 =
MathUtils::angle( mPointVector[pt2], mPointVector[pt3], mPointVector[pt1], mPointVector[pt3] );
2226 bool twoforcededges1, twoforcededges2, twoforcededges3;
2229 twoforcededges1 = ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) && ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) );
2231 twoforcededges2 = ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) && ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) );
2233 twoforcededges3 = ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) && ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) );
2237 const QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
2238 if ( ed1iter != dontexamine.end() )
2241 dontexamine.erase( ed1iter );
2246 std::map<int, double>::iterator tempit1;
2247 tempit1 = edge_angle.find( ed1 );
2248 if ( tempit1 != edge_angle.end() )
2251 const double angle = tempit1->second;
2252 edge_angle.erase( ed1 );
2253 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2254 while ( tempit2->second != ed1 )
2258 angle_edge.erase( tempit2 );
2262 if ( angle1 < mintol && !twoforcededges1 )
2264 edge_angle.insert( std::make_pair( ed1, angle1 ) );
2265 angle_edge.insert( std::make_pair( angle1, ed1 ) );
2269 const QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
2270 if ( ed2iter != dontexamine.end() )
2273 dontexamine.erase( ed2iter );
2278 std::map<int, double>::iterator tempit1;
2279 tempit1 = edge_angle.find( ed2 );
2280 if ( tempit1 != edge_angle.end() )
2283 const double angle = tempit1->second;
2284 edge_angle.erase( ed2 );
2285 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2286 while ( tempit2->second != ed2 )
2290 angle_edge.erase( tempit2 );
2294 if ( angle2 < mintol && !twoforcededges2 )
2296 edge_angle.insert( std::make_pair( ed2, angle2 ) );
2297 angle_edge.insert( std::make_pair( angle2, ed2 ) );
2301 const QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
2302 if ( ed3iter != dontexamine.end() )
2305 dontexamine.erase( ed3iter );
2310 std::map<int, double>::iterator tempit1;
2311 tempit1 = edge_angle.find( ed3 );
2312 if ( tempit1 != edge_angle.end() )
2315 const double angle = tempit1->second;
2316 edge_angle.erase( ed3 );
2317 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2318 while ( tempit2->second != ed3 )
2322 angle_edge.erase( tempit2 );
2326 if ( angle3 < mintol && !twoforcededges3 )
2328 edge_angle.insert( std::make_pair( ed3, angle3 ) );
2329 angle_edge.insert( std::make_pair( angle3, ed3 ) );
2333 }
while ( actedge != pointingedge );
2346 calcPoint( circumcenter.x(), circumcenter.y(), p );
2349 if ( pointno == -100 || pointno == mTwiceInsPoint )
2351 if ( pointno == -100 )
2353 QgsDebugError( u
"put circumcenter %1//%2 on dontexamine list because of numerical instabilities"_s.arg( circumcenter.x() ).arg( circumcenter.y() ) );
2355 else if ( pointno == mTwiceInsPoint )
2357 QgsDebugError( u
"put circumcenter %1//%2 on dontexamine list because it is already inserted"_s.arg( circumcenter.x() ).arg( circumcenter.y() ) );
2360 for (
int i = 0; i < mPointVector.count(); i++ )
2362 if ( mPointVector[i]->x() == circumcenter.x() && mPointVector[i]->y() == circumcenter.y() )
2369 QgsDebugError( u
"point is not present in the triangulation"_s );
2373 dontexamine.insert( minedge );
2374 edge_angle.erase( minedge );
2375 std::multimap<double, int>::iterator minedgeiter = angle_edge.lower_bound( minangle );
2376 while ( minedgeiter->second != minedge )
2380 angle_edge.erase( minedgeiter );
2389 const int pointingedge = baseEdgeOfPoint( pointno );
2391 int actedge = pointingedge;
2394 double angle1, angle2, angle3;
2398 ed1 = mHalfEdge[actedge]->getDual();
2399 pt1 = mHalfEdge[ed1]->getPoint();
2400 ed2 = mHalfEdge[ed1]->getNext();
2401 pt2 = mHalfEdge[ed2]->getPoint();
2402 ed3 = mHalfEdge[ed2]->getNext();
2403 pt3 = mHalfEdge[ed3]->getPoint();
2406 if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
2411 angle1 =
MathUtils::angle( mPointVector[pt3], mPointVector[pt1], mPointVector[pt2], mPointVector[pt1] );
2412 angle2 =
MathUtils::angle( mPointVector[pt1], mPointVector[pt2], mPointVector[pt3], mPointVector[pt2] );
2413 angle3 =
MathUtils::angle( mPointVector[pt2], mPointVector[pt3], mPointVector[pt1], mPointVector[pt3] );
2416 bool twoforcededges1, twoforcededges2, twoforcededges3;
2418 twoforcededges1 = ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) && ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) );
2420 twoforcededges2 = ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) && ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) );
2422 twoforcededges3 = ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) && ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) );
2426 const QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
2427 if ( ed1iter != dontexamine.end() )
2430 dontexamine.erase( ed1iter );
2435 std::map<int, double>::iterator tempit1;
2436 tempit1 = edge_angle.find( ed1 );
2437 if ( tempit1 != edge_angle.end() )
2440 const double angle = tempit1->second;
2441 edge_angle.erase( ed1 );
2442 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2443 while ( tempit2->second != ed1 )
2447 angle_edge.erase( tempit2 );
2451 if ( angle1 < mintol && !twoforcededges1 )
2453 edge_angle.insert( std::make_pair( ed1, angle1 ) );
2454 angle_edge.insert( std::make_pair( angle1, ed1 ) );
2459 const QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
2460 if ( ed2iter != dontexamine.end() )
2463 dontexamine.erase( ed2iter );
2468 std::map<int, double>::iterator tempit1;
2469 tempit1 = edge_angle.find( ed2 );
2470 if ( tempit1 != edge_angle.end() )
2473 const double angle = tempit1->second;
2474 edge_angle.erase( ed2 );
2475 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2476 while ( tempit2->second != ed2 )
2480 angle_edge.erase( tempit2 );
2484 if ( angle2 < mintol && !twoforcededges2 )
2486 edge_angle.insert( std::make_pair( ed2, angle2 ) );
2487 angle_edge.insert( std::make_pair( angle2, ed2 ) );
2491 const QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
2492 if ( ed3iter != dontexamine.end() )
2495 dontexamine.erase( ed3iter );
2500 std::map<int, double>::iterator tempit1;
2501 tempit1 = edge_angle.find( ed3 );
2502 if ( tempit1 != edge_angle.end() )
2505 const double angle = tempit1->second;
2506 edge_angle.erase( ed3 );
2507 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2508 while ( tempit2->second != ed3 )
2512 angle_edge.erase( tempit2 );
2516 if ( angle3 < mintol && !twoforcededges3 )
2518 edge_angle.insert( std::make_pair( ed3, angle3 ) );
2519 angle_edge.insert( std::make_pair( angle3, ed3 ) );
2523 }
while ( actedge != pointingedge );
2529 for ( QSet<int>::iterator it = dontexamine.begin(); it != dontexamine.end(); ++it )
2537bool QgsDualEdgeTriangulation::swapPossible(
unsigned int edge )
const
2540 if ( mHalfEdge[edge]->getForced() )
2546 if ( mHalfEdge[edge]->getPoint() == -1
2547 || mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() == -1
2548 || mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() == -1
2549 || mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() == -1 )
2554 QgsPoint *pta = mPointVector[mHalfEdge[edge]->getPoint()];
2555 QgsPoint *ptb = mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()];
2556 QgsPoint *ptc = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint()];
2557 QgsPoint *ptd = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint()];
2577void QgsDualEdgeTriangulation::triangulatePolygon( QList<int> *poly, QList<int> *free,
int mainedge )
2581 if ( poly->count() == 3 )
2587 QList<int>::const_iterator iterator = ++( poly->constBegin() );
2589 =
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] );
2590 int distedge = ( *iterator );
2591 int nextdistedge = mHalfEdge[( *iterator )]->getNext();
2594 while ( iterator != --( poly->constEnd() ) )
2596 if (
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] )
2599 distedge = ( *iterator );
2600 nextdistedge = mHalfEdge[( *iterator )]->getNext();
2602 distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] );
2607 if ( nextdistedge == ( *( --poly->end() ) ) )
2609 const int inserta = free->first();
2610 const int insertb = mHalfEdge[inserta]->getDual();
2613 mHalfEdge[inserta]->setNext( ( poly->at( 1 ) ) );
2614 mHalfEdge[inserta]->setPoint( mHalfEdge[mainedge]->getPoint() );
2615 mHalfEdge[insertb]->setNext( nextdistedge );
2616 mHalfEdge[insertb]->setPoint( mHalfEdge[distedge]->getPoint() );
2617 mHalfEdge[distedge]->setNext( inserta );
2618 mHalfEdge[mainedge]->setNext( insertb );
2621 for ( iterator = ( ++( poly->constBegin() ) ); ( *iterator ) != nextdistedge; ++iterator )
2623 polya.append( ( *iterator ) );
2625 polya.prepend( inserta );
2629 for ( iterator = polya.begin(); iterator != polya.end(); ++iterator )
2635 triangulatePolygon( &polya, free, inserta );
2638 else if ( distedge == ( *( ++poly->begin() ) ) )
2640 const int inserta = free->first();
2641 const int insertb = mHalfEdge[inserta]->getDual();
2644 mHalfEdge[inserta]->setNext( ( poly->at( 2 ) ) );
2645 mHalfEdge[inserta]->setPoint( mHalfEdge[distedge]->getPoint() );
2646 mHalfEdge[insertb]->setNext( mainedge );
2647 mHalfEdge[insertb]->setPoint( mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint() );
2648 mHalfEdge[distedge]->setNext( insertb );
2649 mHalfEdge[( *( --poly->end() ) )]->setNext( inserta );
2652 iterator = poly->constBegin();
2654 while ( iterator != poly->constEnd() )
2656 polya.append( ( *iterator ) );
2659 polya.prepend( inserta );
2661 triangulatePolygon( &polya, free, inserta );
2666 const int inserta = free->first();
2667 const int insertb = mHalfEdge[inserta]->getDual();
2670 const int insertc = free->first();
2671 const int insertd = mHalfEdge[insertc]->getDual();
2674 mHalfEdge[inserta]->setNext( ( poly->at( 1 ) ) );
2675 mHalfEdge[inserta]->setPoint( mHalfEdge[mainedge]->getPoint() );
2676 mHalfEdge[insertb]->setNext( insertd );
2677 mHalfEdge[insertb]->setPoint( mHalfEdge[distedge]->getPoint() );
2678 mHalfEdge[insertc]->setNext( nextdistedge );
2679 mHalfEdge[insertc]->setPoint( mHalfEdge[distedge]->getPoint() );
2680 mHalfEdge[insertd]->setNext( mainedge );
2681 mHalfEdge[insertd]->setPoint( mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint() );
2683 mHalfEdge[distedge]->setNext( inserta );
2684 mHalfEdge[mainedge]->setNext( insertb );
2685 mHalfEdge[( *( --poly->end() ) )]->setNext( insertc );
2691 for ( iterator = ++( poly->constBegin() ); ( *iterator ) != nextdistedge; ++iterator )
2693 polya.append( ( *iterator ) );
2695 polya.prepend( inserta );
2698 while ( iterator != poly->constEnd() )
2700 polyb.append( ( *iterator ) );
2703 polyb.prepend( insertc );
2705 triangulatePolygon( &polya, free, inserta );
2706 triangulatePolygon( &polyb, free, insertc );
2719 unsigned int actedge = mEdgeInside;
2727 if ( runs > MAX_BASE_ITERATIONS )
2729 QgsDebugError( u
"warning, instability detected: Point coordinates: %1//%2"_s.arg( x ).arg( y ) );
2733 if (
MathUtils::leftOf(
point, mPointVector[mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[actedge]->getPoint()] ) < ( -
leftOfTresh ) )
2742 else if ( fabs(
MathUtils::leftOf(
point, mPointVector[mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[actedge]->getPoint()] ) )
2746 mEdgeWithPoint = actedge;
2756 actedge = mHalfEdge[actedge]->getDual();
2762 actedge = mHalfEdge[actedge]->getNext();
2763 if ( mHalfEdge[actedge]->getPoint() == -1 )
2769 mEdgeOutside = (
unsigned int ) mHalfEdge[mHalfEdge[actedge]->getNext()]->getNext();
2779 if ( numinstabs > 0 )
2789 mEdgeInside = actedge;
2794bool DualEdgeTriangulation::readFromTAFF( QString filename )
2796 QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
2798 QFile file( filename );
2799 file.open( IO_Raw | IO_ReadOnly );
2800 QBuffer buffer( file.readAll() );
2803 QTextStream textstream( &buffer );
2804 buffer.open( IO_ReadOnly );
2807 int numberofhalfedges;
2811 while ( buff.mid( 0, 4 ) !=
"TRIA" )
2813 buff = textstream.readLine();
2815 while ( buff.mid( 0, 4 ) !=
"NEDG" )
2817 buff = textstream.readLine();
2819 numberofhalfedges = buff.section(
' ', 1, 1 ).toInt();
2820 mHalfEdge.resize( numberofhalfedges );
2823 while ( buff.mid( 0, 4 ) !=
"DATA" )
2828 int nr1, nr2, dual1, dual2, point1, point2, next1, next2, fo1, fo2, b1, b2;
2829 bool forced1, forced2, break1, break2;
2833 QProgressBar *edgebar =
new QProgressBar();
2834 edgebar->setCaption( tr(
"Reading edges…" ) );
2835 edgebar->setTotalSteps( numberofhalfedges / 2 );
2836 edgebar->setMinimumWidth( 400 );
2837 edgebar->move( 500, 500 );
2840 for (
int i = 0; i < numberofhalfedges / 2; i++ )
2842 if ( i % 1000 == 0 )
2844 edgebar->setProgress( i );
2848 textstream >> point1;
2849 textstream >> next1;
2873 textstream >> point2;
2874 textstream >> next2;
2912 mHalfEdge.insert( nr1, hf1 );
2913 mHalfEdge.insert( nr2, hf2 );
2917 edgebar->setProgress( numberofhalfedges / 2 );
2921 for (
int i = 0; i < numberofhalfedges; i++ )
2924 a = mHalfEdge[i]->getPoint();
2925 b = mHalfEdge[mHalfEdge[i]->getDual()]->getPoint();
2926 c = mHalfEdge[mHalfEdge[i]->getNext()]->getPoint();
2927 d = mHalfEdge[mHalfEdge[mHalfEdge[i]->getDual()]->getNext()]->getPoint();
2928 if ( a != -1 && b != -1 &&
c != -1 && d != -1 )
2936 while ( buff.mid( 0, 4 ) !=
"POIN" )
2938 buff = textstream.readLine();
2941 while ( buff.mid( 0, 4 ) !=
"NPTS" )
2943 buff = textstream.readLine();
2946 numberofpoints = buff.section(
' ', 1, 1 ).toInt();
2947 mPointVector.resize( numberofpoints );
2949 while ( buff.mid( 0, 4 ) !=
"DATA" )
2954 QProgressBar *pointbar =
new QProgressBar();
2955 pointbar->setCaption( tr(
"Reading points…" ) );
2956 pointbar->setTotalSteps( numberofpoints );
2957 pointbar->setMinimumWidth( 400 );
2958 pointbar->move( 500, 500 );
2963 for (
int i = 0; i < numberofpoints; i++ )
2965 if ( i % 1000 == 0 )
2967 pointbar->setProgress( i );
2977 mPointVector.insert( i, p );
2993 else if ( x > xMax )
3002 else if ( y > yMax )
3009 pointbar->setProgress( numberofpoints );
3011 QApplication::restoreOverrideCursor();
3015bool DualEdgeTriangulation::saveToTAFF( QString filename )
const
3017 QFile outputfile( filename );
3018 if ( !outputfile.open( IO_WriteOnly ) )
3020 QMessageBox::warning( 0, tr(
"Warning" ), tr(
"File could not be written." ), QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton );
3024 QTextStream outstream( &outputfile );
3025 outstream.precision( 9 );
3028 outstream <<
"TRIA" << std::endl << std::flush;
3029 outstream <<
"NEDG " << mHalfEdge.count() << std::endl << std::flush;
3030 outstream <<
"PANO 1" << std::endl << std::flush;
3031 outstream <<
"DATA ";
3033 bool *cont =
new bool[mHalfEdge.count()];
3034 for (
unsigned int i = 0; i <= mHalfEdge.count() - 1; i++ )
3039 for (
unsigned int i = 0; i < mHalfEdge.count(); i++ )
3046 int dual = mHalfEdge[i]->getDual();
3047 outstream << i <<
" " << mHalfEdge[i]->getPoint() <<
" " << mHalfEdge[i]->getNext() <<
" " << mHalfEdge[i]->getForced() <<
" " << mHalfEdge[i]->getBreak() <<
" ";
3048 outstream << dual <<
" " << mHalfEdge[dual]->getPoint() <<
" " << mHalfEdge[dual]->getNext() <<
" " << mHalfEdge[dual]->getForced() <<
" " << mHalfEdge[dual]->getBreak() <<
" ";
3052 outstream << std::endl << std::flush;
3053 outstream << std::endl << std::flush;
3058 outstream <<
"POIN" << std::endl << std::flush;
3059 outstream <<
"NPTS " << getNumberOfPoints() << std::endl << std::flush;
3060 outstream <<
"PATT 3" << std::endl << std::flush;
3061 outstream <<
"DATA ";
3063 for (
int i = 0; i < getNumberOfPoints(); i++ )
3066 outstream << p->getX() <<
" " << p->getY() <<
" " << p->getZ() <<
" ";
3068 outstream << std::endl << std::flush;
3069 outstream << std::endl << std::flush;
3078 const int edge1 = baseEdgeOfTriangle( p );
3085 edge2 = mHalfEdge[edge1]->getNext();
3086 edge3 = mHalfEdge[edge2]->getNext();
3087 point1 =
point( mHalfEdge[edge1]->getPoint() );
3088 point2 =
point( mHalfEdge[edge2]->getPoint() );
3089 point3 =
point( mHalfEdge[edge3]->getPoint() );
3090 if ( point1 && point2 && point3 )
3093 double dist1, dist2, dist3;
3097 if ( dist1 <= dist2 && dist1 <= dist3 )
3100 if ( swapPossible( edge1 ) )
3102 doOnlySwap( edge1 );
3105 else if ( dist2 <= dist1 && dist2 <= dist3 )
3108 if ( swapPossible( edge2 ) )
3110 doOnlySwap( edge2 );
3113 else if ( dist3 <= dist1 && dist3 <= dist2 )
3116 if ( swapPossible( edge3 ) )
3118 doOnlySwap( edge3 );
3140 const int edge1 = baseEdgeOfTriangle( p );
3143 const int edge2 = mHalfEdge[edge1]->getNext();
3144 const int edge3 = mHalfEdge[edge2]->getNext();
3148 if ( point1 && point2 && point3 )
3154 if ( dist1 <= dist2 && dist1 <= dist3 )
3156 p1 = mHalfEdge[edge1]->getPoint();
3157 p2 = mHalfEdge[mHalfEdge[edge1]->getNext()]->getPoint();
3158 p3 = mHalfEdge[mHalfEdge[edge1]->getDual()]->getPoint();
3159 p4 = mHalfEdge[mHalfEdge[mHalfEdge[edge1]->getDual()]->getNext()]->getPoint();
3161 else if ( dist2 <= dist1 && dist2 <= dist3 )
3163 p1 = mHalfEdge[edge2]->getPoint();
3164 p2 = mHalfEdge[mHalfEdge[edge2]->getNext()]->getPoint();
3165 p3 = mHalfEdge[mHalfEdge[edge2]->getDual()]->getPoint();
3166 p4 = mHalfEdge[mHalfEdge[mHalfEdge[edge2]->getDual()]->getNext()]->getPoint();
3170 p1 = mHalfEdge[edge3]->getPoint();
3171 p2 = mHalfEdge[mHalfEdge[edge3]->getNext()]->getPoint();
3172 p3 = mHalfEdge[mHalfEdge[edge3]->getDual()]->getPoint();
3173 p4 = mHalfEdge[mHalfEdge[mHalfEdge[edge3]->getDual()]->getNext()]->getPoint();
3201 bool *alreadyVisitedEdges =
new bool[mHalfEdge.size()];
3202 if ( !alreadyVisitedEdges )
3208 for (
int i = 0; i < mHalfEdge.size(); ++i )
3210 alreadyVisitedEdges[i] =
false;
3213 for (
int i = 0; i < mHalfEdge.size(); ++i )
3218 HalfEdge *currentEdge = mHalfEdge[i];
3219 if ( currentEdge->
getPoint() != -1 && mHalfEdge[currentEdge->
getDual()]->getPoint() != -1 && !alreadyVisitedEdges[currentEdge->
getDual()] )
3225 QgsPoint *p2 = mPointVector[mHalfEdge[currentEdge->
getDual()]->getPoint()];
3233 QString attributeString;
3238 attributeString = u
"break line"_s;
3242 attributeString = u
"structure line"_s;
3249 alreadyVisitedEdges[i] =
true;
3252 delete[] alreadyVisitedEdges;
3262 QVector<bool> edgeToTreat( mHalfEdge.count(),
true );
3263 QHash<HalfEdge *, int> edgesHash;
3264 for (
int i = 0; i < mHalfEdge.count(); ++i )
3266 edgesHash.insert( mHalfEdge[i], i );
3275 const int edgeCount = edgeToTreat.count();
3276 for (
int i = 0; i < edgeCount; ++i )
3278 bool containVirtualPoint =
false;
3279 if ( edgeToTreat[i] )
3281 HalfEdge *currentEdge = mHalfEdge[i];
3286 edgeToTreat[edgesHash.value( currentEdge )] =
false;
3287 face.append( currentEdge->
getPoint() );
3288 containVirtualPoint |= currentEdge->
getPoint() == -1;
3289 currentEdge = mHalfEdge.at( currentEdge->
getNext() );
3290 }
while ( currentEdge != firstEdge && !containVirtualPoint && ( !feedback || !feedback->
isCanceled() ) );
3291 if ( !containVirtualPoint )
3292 mesh.
faces.append( face );
3303double QgsDualEdgeTriangulation::swapMinAngle(
int edge )
const
3306 QgsPoint *p2 =
point( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() );
3307 QgsPoint *p3 =
point( mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() );
3308 QgsPoint *p4 =
point( mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() );
3315 if ( angle2 < minangle )
3320 if ( angle3 < minangle )
3325 if ( angle4 < minangle )
3330 if ( angle5 < minangle )
3335 if ( angle6 < minangle )
3343int QgsDualEdgeTriangulation::splitHalfEdge(
int edge,
float position )
3346 if ( position < 0 || position > 1 )
3348 QgsDebugError( u
"warning, position is not between 0 and 1"_s );
3352 QgsPoint *p =
new QgsPoint(
3353 mPointVector[mHalfEdge[edge]->getPoint()]->x() * position + mPointVector[mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint()]->x() * ( 1 - position ),
3354 mPointVector[mHalfEdge[edge]->getPoint()]->y() * position + mPointVector[mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint()]->y() * ( 1 - position ),
3359 QgsPoint zvaluepoint( 0, 0, 0 );
3361 p->
setZ( zvaluepoint.z() );
3364 if ( mPointVector.count() >= mPointVector.size() )
3366 mPointVector.resize( mPointVector.count() + 1 );
3368 QgsDebugMsgLevel( u
"inserting point nr. %1, %2//%3//%4"_s.arg( mPointVector.count() ).arg( p->
x() ).arg( p->
y() ).arg( p->
z() ), 2 );
3369 mPointVector.insert( mPointVector.count(), p );
3372 const int dualedge = mHalfEdge[edge]->getDual();
3373 const int edge1 = insertEdge( -10, -10, mPointVector.count() - 1,
false,
false );
3374 const int edge2 = insertEdge( edge1, mHalfEdge[mHalfEdge[edge]->getNext()]->getNext(), mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint(),
false,
false );
3375 const int edge3 = insertEdge( -10, mHalfEdge[mHalfEdge[dualedge]->getNext()]->getNext(), mHalfEdge[mHalfEdge[dualedge]->getNext()]->getPoint(),
false,
false );
3376 const int edge4 = insertEdge( edge3, dualedge, mPointVector.count() - 1,
false,
false );
3377 const int edge5 = insertEdge( -10, mHalfEdge[edge]->getNext(), mHalfEdge[edge]->getPoint(), mHalfEdge[edge]->getBreak(), mHalfEdge[edge]->getForced() );
3378 const int edge6 = insertEdge( edge5, edge3, mPointVector.count() - 1, mHalfEdge[dualedge]->getBreak(), mHalfEdge[dualedge]->getForced() );
3379 mHalfEdge[edge1]->setDual( edge2 );
3380 mHalfEdge[edge1]->setNext( edge5 );
3381 mHalfEdge[edge3]->setDual( edge4 );
3382 mHalfEdge[edge5]->setDual( edge6 );
3385 mHalfEdge[mHalfEdge[edge]->getNext()]->setNext( edge1 );
3386 mHalfEdge[mHalfEdge[dualedge]->getNext()]->setNext( edge4 );
3387 mHalfEdge[edge]->setNext( edge2 );
3388 mHalfEdge[edge]->setPoint( mPointVector.count() - 1 );
3389 mHalfEdge[mHalfEdge[edge3]->getNext()]->setNext( edge6 );
3392 checkSwapRecursively( mHalfEdge[edge5]->getNext(), 0 );
3393 checkSwapRecursively( mHalfEdge[edge2]->getNext(), 0 );
3394 checkSwapRecursively( mHalfEdge[dualedge]->getNext(), 0 );
3395 checkSwapRecursively( mHalfEdge[edge3]->getNext(), 0 );
3399 return mPointVector.count() - 1;
3402bool QgsDualEdgeTriangulation::edgeOnConvexHull(
int edge )
3404 return ( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() == -1 || mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() == -1 );
3407void QgsDualEdgeTriangulation::evaluateInfluenceRegion(
QgsPoint *point,
int edge, QSet<int> &set )
3409 if ( set.find( edge ) == set.end() )
3418 if ( !mHalfEdge[edge]->getForced() && !edgeOnConvexHull( edge ) )
3421 if (
inCircle( *
point, *mPointVector[mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint()], *mPointVector[mHalfEdge[edge]->getPoint()], *mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()] ) )
3423 evaluateInfluenceRegion(
point, mHalfEdge[mHalfEdge[edge]->getDual()]->getNext(), set );
3424 evaluateInfluenceRegion(
point, mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getNext(), set );
3429int QgsDualEdgeTriangulation::firstEdgeOutSide()
3432 while ( ( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() != -1 || mHalfEdge[edge]->getPoint() == -1 || mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() == -1 ) && edge < mHalfEdge.count() )
3437 if ( edge >= mHalfEdge.count() )
3443void QgsDualEdgeTriangulation::removeLastPoint()
3445 if ( mPointVector.isEmpty() )
3447 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