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()] ) < ( -
leftOfTresh ) )
346 mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext()]->getNext()]->setPoint( mPointVector.count() - 1 );
348 cwEdge = (
unsigned int ) mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->getNext();
352 const unsigned int edge1 = insertEdge( mHalfEdge[cwEdge]->getNext(), -10, mHalfEdge[cwEdge]->getPoint(),
false,
false );
353 const unsigned int edge2 = insertEdge( mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual(), -10, -1,
false,
false );
354 const unsigned int edge3 = insertEdge( -10, edge1, mPointVector.count() - 1,
false,
false );
357 mHalfEdge[mHalfEdge[mHalfEdge[cwEdge]->getNext()]->getDual()]->setDual( edge2 );
358 mHalfEdge[mHalfEdge[cwEdge]->getNext()]->setDual( edge1 );
359 mHalfEdge[edge1]->setNext( edge2 );
360 mHalfEdge[edge2]->setNext( edge3 );
363 while (
MathUtils::leftOf( *mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getPoint()], mPointVector[mPointVector.count() - 1], mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->getNext()]->getPoint()] ) < ( -
leftOfTresh ) )
366 mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->setPoint( mPointVector.count() - 1 );
368 ccwEdge = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->getNext()]->getNext();
372 const unsigned int edge4 = insertEdge( mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext(), -10, mPointVector.count() - 1,
false,
false );
373 const unsigned int edge5 = insertEdge( edge3, -10, -1,
false,
false );
374 const unsigned int edge6 = insertEdge( mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual(), edge4, mHalfEdge[mHalfEdge[ccwEdge]->getDual()]->getPoint(),
false,
false );
378 mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->getDual()]->setDual( edge6 );
379 mHalfEdge[mHalfEdge[mHalfEdge[ccwEdge]->getNext()]->getNext()]->setDual( edge4 );
380 mHalfEdge[edge4]->setNext( edge5 );
381 mHalfEdge[edge5]->setNext( edge6 );
382 mHalfEdge[edge3]->setDual( edge5 );
385 unsigned int index = ccwEdge;
390 index = mHalfEdge[mHalfEdge[mHalfEdge[index]->getNext()]->getDual()]->getNext();
391 checkSwapRecursively( toswap, 0 );
392 if ( toswap == cwEdge )
398 else if ( number >= 0 )
400 const int nextnumber = mHalfEdge[number]->getNext();
401 const int nextnextnumber = mHalfEdge[mHalfEdge[number]->getNext()]->getNext();
404 const unsigned int edge1 = insertEdge( -10, nextnumber, mHalfEdge[number]->getPoint(),
false,
false );
405 const unsigned int edge2 = insertEdge(
static_cast<int>( edge1 ), -10, mPointVector.count() - 1,
false,
false );
406 const unsigned int edge3 = insertEdge( -10, nextnextnumber, mHalfEdge[nextnumber]->getPoint(),
false,
false );
407 const unsigned int edge4 = insertEdge(
static_cast<int>( edge3 ),
static_cast<int>( edge1 ), mPointVector.count() - 1,
false,
false );
408 const unsigned int edge5 = insertEdge( -10, number, mHalfEdge[nextnextnumber]->getPoint(),
false,
false );
409 const unsigned int edge6 = insertEdge(
static_cast<int>( edge5 ),
static_cast<int>( edge3 ), mPointVector.count() - 1,
false,
false );
412 mHalfEdge.at( edge1 )->setDual(
static_cast<int>( edge2 ) );
413 mHalfEdge.at( edge2 )->setNext(
static_cast<int>( edge5 ) );
414 mHalfEdge.at( edge3 )->setDual(
static_cast<int>( edge4 ) );
415 mHalfEdge.at( edge5 )->setDual(
static_cast<int>( edge6 ) );
416 mHalfEdge.at( number )->setNext(
static_cast<int>( edge2 ) );
417 mHalfEdge.at( nextnumber )->setNext(
static_cast<int>( edge4 ) );
418 mHalfEdge.at( nextnextnumber )->setNext(
static_cast<int>( edge6 ) );
421 checkSwapRecursively( number, 0 );
422 checkSwapRecursively( nextnumber, 0 );
423 checkSwapRecursively( nextnextnumber, 0 );
426 else if ( number == -20 )
431 const int point1 = mHalfEdge[mEdgeWithPoint]->getPoint();
432 const int point2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getDual()]->getPoint();
433 const double distance1 = p.
distance( *mPointVector[point1] );
439 const double distance2 = p.
distance( *mPointVector[point2] );
446 const int edgea = mEdgeWithPoint;
447 const int edgeb = mHalfEdge[mEdgeWithPoint]->getDual();
448 const int edgec = mHalfEdge[edgea]->getNext();
449 const int edged = mHalfEdge[edgec]->getNext();
450 const int edgee = mHalfEdge[edgeb]->getNext();
451 const int edgef = mHalfEdge[edgee]->getNext();
454 const int nedge1 = insertEdge( -10, mHalfEdge[edgea]->getNext(), mHalfEdge[edgea]->getPoint(),
false,
false );
455 const int nedge2 = insertEdge( nedge1, -10, mPointVector.count() - 1,
false,
false );
456 const int nedge3 = insertEdge( -10, edged, mHalfEdge[edgec]->getPoint(),
false,
false );
457 const int nedge4 = insertEdge( nedge3, nedge1, mPointVector.count() - 1,
false,
false );
458 const int nedge5 = insertEdge( -10, edgef, mHalfEdge[edgee]->getPoint(),
false,
false );
459 const int nedge6 = insertEdge( nedge5, edgeb, mPointVector.count() - 1,
false,
false );
462 mHalfEdge[nedge1]->setDual( nedge2 );
463 mHalfEdge[nedge2]->setNext( nedge5 );
464 mHalfEdge[nedge3]->setDual( nedge4 );
465 mHalfEdge[nedge5]->setDual( nedge6 );
466 mHalfEdge[edgea]->setPoint( mPointVector.count() - 1 );
467 mHalfEdge[edgea]->setNext( nedge3 );
468 mHalfEdge[edgec]->setNext( nedge4 );
469 mHalfEdge[edgee]->setNext( nedge6 );
470 mHalfEdge[edgef]->setNext( nedge2 );
473 checkSwapRecursively( edgec, 0 );
474 checkSwapRecursively( edged, 0 );
475 checkSwapRecursively( edgee, 0 );
476 checkSwapRecursively( edgef, 0 );
479 else if ( number == -100 || number == -5 )
485 else if ( number == -25 )
488 QgsPoint *newPoint = mPointVector[mPointVector.count() - 1];
489 QgsPoint *existingPoint = mPointVector[mTwiceInsPoint];
490 existingPoint->
setZ( std::max( newPoint->
z(), existingPoint->
z() ) );
493 return mTwiceInsPoint;
497 return ( mPointVector.count() - 1 );
500int QgsDualEdgeTriangulation::baseEdgeOfPoint(
int point )
502 unsigned int actedge = mEdgeInside;
504 if ( mPointVector.count() < 4 ||
point == -1 || mDimension == 1 )
506 int fromVirtualPoint = -1;
508 for (
int i = 0; i < mHalfEdge.count(); i++ )
510 if ( mHalfEdge[i]->getPoint() ==
point )
512 if ( mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() != -1 )
515 fromVirtualPoint = i;
518 return fromVirtualPoint;
526 if ( control > 1000000 )
532 for (
int i = 0; i < mHalfEdge.count(); i++ )
534 if ( mHalfEdge[i]->getPoint() ==
point && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 )
541 const int fromPoint = mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint();
542 const int toPoint = mHalfEdge[actedge]->getPoint();
544 if ( fromPoint == -1 || toPoint == -1 )
546 for (
int i = 0; i < mHalfEdge.count(); i++ )
548 if ( mHalfEdge[i]->getPoint() ==
point && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 )
556 const double leftOfNumber =
MathUtils::leftOf( *mPointVector[
point], mPointVector[mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[actedge]->getPoint()] );
559 if ( mHalfEdge[actedge]->getPoint() ==
point && mHalfEdge[mHalfEdge[actedge]->getNext()]->getPoint() != -1 )
561 mEdgeInside = actedge;
564 else if ( leftOfNumber <= 0.0 )
566 actedge = mHalfEdge[actedge]->getNext();
570 actedge = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[actedge]->getDual()]->getNext()]->getNext()]->getDual();
575int QgsDualEdgeTriangulation::baseEdgeOfTriangle(
const QgsPoint &point )
577 unsigned int actEdge = mEdgeInside;
578 if ( mHalfEdge.at( actEdge )->getPoint() < 0 )
579 actEdge = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getNext() )->getDual();
580 if ( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint() < 0 )
581 actEdge = mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getDual();
587 int firstEndPoint = 0, secEndPoint = 0, thEndPoint = 0, fouEndPoint = 0;
591 if ( runs > MAX_BASE_ITERATIONS )
597 const double leftOfValue =
MathUtils::leftOf(
point, mPointVector.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint() ), mPointVector.at( mHalfEdge.at( actEdge )->getPoint() ) );
612 firstEndPoint = mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint();
613 secEndPoint = mHalfEdge.at( actEdge )->getPoint();
615 else if ( nulls == 1 )
618 thEndPoint = mHalfEdge.at( mHalfEdge.at( actEdge )->getDual() )->getPoint();
619 fouEndPoint = mHalfEdge.at( actEdge )->getPoint();
622 mEdgeWithPoint = actEdge;
631 actEdge = mHalfEdge.at( actEdge )->getDual();
636 actEdge = mHalfEdge.at( actEdge )->getNext();
637 if ( mHalfEdge.at( actEdge )->getPoint() == -1 )
643 mEdgeOutside = (
unsigned int ) mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
644 mEdgeInside = mHalfEdge.at( mHalfEdge.at( mEdgeOutside )->getDual() )->getNext();
650 if ( numInstabs > 0 )
653 mUnstableEdge = actEdge;
660 if ( firstEndPoint == thEndPoint || firstEndPoint == fouEndPoint )
663 mTwiceInsPoint = firstEndPoint;
666 else if ( secEndPoint == thEndPoint || secEndPoint == fouEndPoint )
669 mTwiceInsPoint = secEndPoint;
681 mEdgeInside = actEdge;
684 nr1 = mHalfEdge.at( actEdge )->getPoint();
685 nr2 = mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getPoint();
686 nr3 = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext() )->getPoint();
687 const double x1 = mPointVector.at( nr1 )->x();
688 const double y1 = mPointVector.at( nr1 )->y();
689 const double x2 = mPointVector.at( nr2 )->x();
690 const double y2 = mPointVector.at( nr2 )->y();
691 const double x3 = mPointVector.at( nr3 )->x();
692 const double y3 = mPointVector.at( nr3 )->y();
695 if ( x1 < x2 && x1 < x3 )
699 else if ( x2 < x1 && x2 < x3 )
701 return mHalfEdge.at( actEdge )->getNext();
703 else if ( x3 < x1 && x3 < x2 )
705 return mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
716 return mHalfEdge.at( actEdge )->getNext();
723 return mHalfEdge.at( actEdge )->getNext();
727 return mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
738 return mHalfEdge.at( mHalfEdge.at( actEdge )->getNext() )->getNext();
746 if ( mTriangleInterpolator )
748 return mTriangleInterpolator->calcNormVec( x, y, result );
759 if ( mTriangleInterpolator )
761 return mTriangleInterpolator->calcPoint( x, y, result );
770bool QgsDualEdgeTriangulation::checkSwapRecursively(
unsigned int edge,
unsigned int recursiveDeep )
772 if ( swapPossible( edge ) )
774 QgsPoint *pta = mPointVector.at( mHalfEdge.at( edge )->getPoint() );
775 QgsPoint *ptb = mPointVector.at( mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getPoint() );
776 QgsPoint *ptc = mPointVector.at( mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getNext() )->getPoint() );
777 QgsPoint *ptd = mPointVector.at( mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext() )->getPoint() );
778 if ( inCircle( *ptd, *pta, *ptb, *ptc ) )
780 doSwapRecursively( edge, recursiveDeep );
787bool QgsDualEdgeTriangulation::isEdgeNeedSwap(
unsigned int edge )
const
789 if ( swapPossible( edge ) )
791 QgsPoint *pta = mPointVector[mHalfEdge[edge]->getPoint()];
792 QgsPoint *ptb = mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()];
793 QgsPoint *ptc = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint()];
794 QgsPoint *ptd = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint()];
795 return inCircle( *ptd, *pta, *ptb, *ptc );
801void QgsDualEdgeTriangulation::doOnlySwap(
unsigned int edge )
803 const unsigned int edge1 = edge;
804 const unsigned int edge2 = mHalfEdge[edge]->getDual();
805 const unsigned int edge3 = mHalfEdge[edge]->getNext();
806 const unsigned int edge4 = mHalfEdge[mHalfEdge[edge]->getNext()]->getNext();
807 const unsigned int edge5 = mHalfEdge[mHalfEdge[edge]->getDual()]->getNext();
808 const unsigned int edge6 = mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getNext();
809 mHalfEdge[edge1]->setNext( edge4 );
810 mHalfEdge[edge2]->setNext( edge6 );
811 mHalfEdge[edge3]->setNext( edge2 );
812 mHalfEdge[edge4]->setNext( edge5 );
813 mHalfEdge[edge5]->setNext( edge1 );
814 mHalfEdge[edge6]->setNext( edge3 );
815 mHalfEdge[edge1]->setPoint( mHalfEdge[edge3]->getPoint() );
816 mHalfEdge[edge2]->setPoint( mHalfEdge[edge5]->getPoint() );
819void QgsDualEdgeTriangulation::doSwapRecursively(
unsigned int edge,
unsigned int recursiveDeep )
821 const unsigned int edge1 = edge;
822 const unsigned int edge2 = mHalfEdge.at( edge )->getDual();
823 const unsigned int edge3 = mHalfEdge.at( edge )->getNext();
824 const unsigned int edge4 = mHalfEdge.at( mHalfEdge.at( edge )->getNext() )->getNext();
825 const unsigned int edge5 = mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext();
826 const unsigned int edge6 = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( edge )->getDual() )->getNext() )->getNext();
827 mHalfEdge.at( edge1 )->setNext( edge4 );
828 mHalfEdge.at( edge2 )->setNext( edge6 );
829 mHalfEdge.at( edge3 )->setNext( edge2 );
830 mHalfEdge.at( edge4 )->setNext( edge5 );
831 mHalfEdge.at( edge5 )->setNext( edge1 );
832 mHalfEdge.at( edge6 )->setNext( edge3 );
833 mHalfEdge.at( edge1 )->setPoint( mHalfEdge.at( edge3 )->getPoint() );
834 mHalfEdge.at( edge2 )->setPoint( mHalfEdge.at( edge5 )->getPoint() );
837 if ( recursiveDeep < 100 )
839 checkSwapRecursively( edge3, recursiveDeep );
840 checkSwapRecursively( edge6, recursiveDeep );
841 checkSwapRecursively( edge4, recursiveDeep );
842 checkSwapRecursively( edge5, recursiveDeep );
846 QStack<int> edgesToSwap;
847 edgesToSwap.push( edge3 );
848 edgesToSwap.push( edge6 );
849 edgesToSwap.push( edge4 );
850 edgesToSwap.push( edge5 );
852 while ( !edgesToSwap.isEmpty() && loopCount < 10000 )
855 const unsigned int e1 = edgesToSwap.pop();
856 if ( isEdgeNeedSwap( e1 ) )
858 const unsigned int e2 = mHalfEdge.at( e1 )->getDual();
859 const unsigned int e3 = mHalfEdge.at( e1 )->getNext();
860 const unsigned int e4 = mHalfEdge.at( mHalfEdge.at( e1 )->getNext() )->getNext();
861 const unsigned int e5 = mHalfEdge.at( mHalfEdge.at( e1 )->getDual() )->getNext();
862 const unsigned int e6 = mHalfEdge.at( mHalfEdge.at( mHalfEdge.at( e1 )->getDual() )->getNext() )->getNext();
863 mHalfEdge.at( e1 )->setNext( e4 );
864 mHalfEdge.at( e2 )->setNext( e6 );
865 mHalfEdge.at( e3 )->setNext( e2 );
866 mHalfEdge.at( e4 )->setNext( e5 );
867 mHalfEdge.at( e5 )->setNext( e1 );
868 mHalfEdge.at( e6 )->setNext( e3 );
869 mHalfEdge.at( e1 )->setPoint( mHalfEdge.at( e3 )->getPoint() );
870 mHalfEdge.at( e2 )->setPoint( mHalfEdge.at( e5 )->getPoint() );
872 edgesToSwap.push( e3 );
873 edgesToSwap.push( e6 );
874 edgesToSwap.push( e4 );
875 edgesToSwap.push( e5 );
882void DualEdgeTriangulation::draw( QPainter *p,
double xlowleft,
double ylowleft,
double xupright,
double yupright,
double width,
double height )
const
885 if ( mPointVector.isEmpty() )
890 p->setPen( mEdgeColor );
892 bool *control =
new bool[mHalfEdge.count()];
893 bool *control2 =
new bool[mHalfEdge.count()];
895 for (
unsigned int i = 0; i <= mHalfEdge.count() - 1; i++ )
901 if ( ( ( xupright - xlowleft ) / width ) > ( ( yupright - ylowleft ) / height ) )
903 double lowerborder = -( height * ( xupright - xlowleft ) / width - yupright );
904 for (
unsigned int i = 0; i < mHalfEdge.count() - 1; i++ )
906 if ( mHalfEdge[i]->getPoint() == -1 || mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() == -1 )
913 if ( mHalfEdge[i]->getPoint() != -1 && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 && mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint() != -1 )
915 p1 = mPointVector[mHalfEdge[i]->getPoint()]->getZ();
916 p2 = mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getZ();
917 p3 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getZ();
918 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 ) )
921 pa.setPoint( 0, ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( xupright - xlowleft )*width, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( xupright - xlowleft )*width );
922 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 );
923 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 );
924 QColor
c( 255, 0, 0 );
926 p->drawPolygon( pa );
931 control2[mHalfEdge[i]->getNext()] =
true;
932 control2[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()] =
true;
939 if ( halfEdgeBBoxTest( i, xlowleft, lowerborder, xupright, yupright ) )
941 if ( mHalfEdge[i]->getBreak() )
943 p->setPen( mBreakEdgeColor );
945 else if ( mHalfEdge[i]->getForced() )
947 p->setPen( mForcedEdgeColor );
951 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 );
953 if ( mHalfEdge[i]->getForced() )
955 p->setPen( mEdgeColor );
961 control[mHalfEdge[i]->getDual()] =
true;
966 double rightborder = width * ( yupright - ylowleft ) / height + xlowleft;
967 for (
unsigned int i = 0; i < mHalfEdge.count() - 1; i++ )
969 if ( mHalfEdge[i]->getPoint() == -1 || mHalfEdge[mHalfEdge[i]->getDual()]->getPoint() == -1 )
976 if ( mHalfEdge[i]->getPoint() != -1 && mHalfEdge[mHalfEdge[i]->getNext()]->getPoint() != -1 && mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint() != -1 )
978 p1 = mPointVector[mHalfEdge[i]->getPoint()]->getZ();
979 p2 = mPointVector[mHalfEdge[mHalfEdge[i]->getNext()]->getPoint()]->getZ();
980 p3 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()]->getPoint()]->getZ();
981 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 ) )
984 pa.setPoint( 0, ( mPointVector[mHalfEdge[i]->getPoint()]->getX() - xlowleft ) / ( yupright - ylowleft )*height, ( yupright - mPointVector[mHalfEdge[i]->getPoint()]->getY() ) / ( yupright - ylowleft )*height );
985 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 );
986 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 );
987 QColor
c( 255, 0, 0 );
989 p->drawPolygon( pa );
994 control2[mHalfEdge[i]->getNext()] =
true;
995 control2[mHalfEdge[mHalfEdge[i]->getNext()]->getNext()] =
true;
1003 if ( halfEdgeBBoxTest( i, xlowleft, ylowleft, rightborder, yupright ) )
1005 if ( mHalfEdge[i]->getBreak() )
1007 p->setPen( mBreakEdgeColor );
1009 else if ( mHalfEdge[i]->getForced() )
1011 p->setPen( mForcedEdgeColor );
1014 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 );
1016 if ( mHalfEdge[i]->getForced() )
1018 p->setPen( mEdgeColor );
1023 control[mHalfEdge[i]->getDual()] =
true;
1035 const int firstedge = baseEdgeOfPoint( p2 );
1039 int nextnextedge = firstedge;
1043 edge = mHalfEdge[nextnextedge]->getDual();
1044 if ( mHalfEdge[edge]->getPoint() == p1 )
1046 theedge = nextnextedge;
1049 nextedge = mHalfEdge[edge]->getNext();
1050 nextnextedge = mHalfEdge[nextedge]->getNext();
1051 }
while ( nextnextedge != firstedge );
1053 if ( theedge == -10 )
1060 return mHalfEdge[mHalfEdge[mHalfEdge[theedge]->getDual()]->getNext()]->getPoint();
1065 const int firstedge = baseEdgeOfPoint( pointno );
1068 if ( firstedge == -1 )
1073 int actedge = firstedge;
1074 int edge, nextedge, nextnextedge;
1077 edge = mHalfEdge[actedge]->getDual();
1078 vlist.append( mHalfEdge[edge]->getPoint() );
1079 nextedge = mHalfEdge[edge]->getNext();
1080 vlist.append( mHalfEdge[nextedge]->getPoint() );
1081 nextnextedge = mHalfEdge[nextedge]->getNext();
1082 vlist.append( mHalfEdge[nextnextedge]->getPoint() );
1083 if ( mHalfEdge[nextnextedge]->getBreak() )
1085 vlist.append( -10 );
1089 vlist.append( -20 );
1091 actedge = nextnextedge;
1092 }
while ( nextnextedge != firstedge );
1099 if ( mPointVector.size() < 3 )
1105 const int edge = baseEdgeOfTriangle(
point );
1111 else if ( edge >= 0 )
1113 const int ptnr1 = mHalfEdge[edge]->getPoint();
1114 const int ptnr2 = mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint();
1115 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint();
1116 p1.
setX( mPointVector[ptnr1]->x() );
1117 p1.
setY( mPointVector[ptnr1]->y() );
1118 p1.
setZ( mPointVector[ptnr1]->z() );
1119 p2.
setX( mPointVector[ptnr2]->x() );
1120 p2.
setY( mPointVector[ptnr2]->y() );
1121 p2.
setZ( mPointVector[ptnr2]->z() );
1122 p3.
setX( mPointVector[ptnr3]->x() );
1123 p3.
setY( mPointVector[ptnr3]->y() );
1124 p3.
setZ( mPointVector[ptnr3]->z() );
1130 else if ( edge == -20 )
1132 const int ptnr1 = mHalfEdge[mEdgeWithPoint]->getPoint();
1133 const int ptnr2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getPoint();
1134 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getNext()]->getPoint();
1135 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1139 p1.
setX( mPointVector[ptnr1]->x() );
1140 p1.
setY( mPointVector[ptnr1]->y() );
1141 p1.
setZ( mPointVector[ptnr1]->z() );
1142 p2.
setX( mPointVector[ptnr2]->x() );
1143 p2.
setY( mPointVector[ptnr2]->y() );
1144 p2.
setZ( mPointVector[ptnr2]->z() );
1145 p3.
setX( mPointVector[ptnr3]->x() );
1146 p3.
setY( mPointVector[ptnr3]->y() );
1147 p3.
setZ( mPointVector[ptnr3]->z() );
1153 else if ( edge == -25 )
1155 const int edge1 = baseEdgeOfPoint( mTwiceInsPoint );
1156 const int edge2 = mHalfEdge[edge1]->getNext();
1157 const int edge3 = mHalfEdge[edge2]->getNext();
1158 const int ptnr1 = mHalfEdge[edge1]->getPoint();
1159 const int ptnr2 = mHalfEdge[edge2]->getPoint();
1160 const int ptnr3 = mHalfEdge[edge3]->getPoint();
1161 p1.
setX( mPointVector[ptnr1]->x() );
1162 p1.
setY( mPointVector[ptnr1]->y() );
1163 p1.
setZ( mPointVector[ptnr1]->z() );
1164 p2.
setX( mPointVector[ptnr2]->x() );
1165 p2.
setY( mPointVector[ptnr2]->y() );
1166 p2.
setZ( mPointVector[ptnr2]->z() );
1167 p3.
setX( mPointVector[ptnr3]->x() );
1168 p3.
setY( mPointVector[ptnr3]->y() );
1169 p3.
setZ( mPointVector[ptnr3]->z() );
1175 else if ( edge == -5 )
1177 const int ptnr1 = mHalfEdge[mUnstableEdge]->getPoint();
1178 const int ptnr2 = mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getPoint();
1179 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getNext()]->getPoint();
1180 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1184 p1.
setX( mPointVector[ptnr1]->x() );
1185 p1.
setY( mPointVector[ptnr1]->y() );
1186 p1.
setZ( mPointVector[ptnr1]->z() );
1187 p2.
setX( mPointVector[ptnr2]->x() );
1188 p2.
setY( mPointVector[ptnr2]->y() );
1189 p2.
setZ( mPointVector[ptnr2]->z() );
1190 p3.
setX( mPointVector[ptnr3]->x() );
1191 p3.
setY( mPointVector[ptnr3]->y() );
1192 p3.
setZ( mPointVector[ptnr3]->z() );
1207 if ( mPointVector.size() < 3 )
1213 const int edge = baseEdgeOfTriangle(
point );
1218 else if ( edge >= 0 )
1220 const int ptnr1 = mHalfEdge[edge]->getPoint();
1221 const int ptnr2 = mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint();
1222 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint();
1223 p1.
setX( mPointVector[ptnr1]->x() );
1224 p1.
setY( mPointVector[ptnr1]->y() );
1225 p1.
setZ( mPointVector[ptnr1]->z() );
1226 p2.
setX( mPointVector[ptnr2]->x() );
1227 p2.
setY( mPointVector[ptnr2]->y() );
1228 p2.
setZ( mPointVector[ptnr2]->z() );
1229 p3.
setX( mPointVector[ptnr3]->x() );
1230 p3.
setY( mPointVector[ptnr3]->y() );
1231 p3.
setZ( mPointVector[ptnr3]->z() );
1234 else if ( edge == -20 )
1236 const int ptnr1 = mHalfEdge[mEdgeWithPoint]->getPoint();
1237 const int ptnr2 = mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getPoint();
1238 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mEdgeWithPoint]->getNext()]->getNext()]->getPoint();
1239 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1243 p1.
setX( mPointVector[ptnr1]->x() );
1244 p1.
setY( mPointVector[ptnr1]->y() );
1245 p1.
setZ( mPointVector[ptnr1]->z() );
1246 p2.
setX( mPointVector[ptnr2]->x() );
1247 p2.
setY( mPointVector[ptnr2]->y() );
1248 p2.
setZ( mPointVector[ptnr2]->z() );
1249 p3.
setX( mPointVector[ptnr3]->x() );
1250 p3.
setY( mPointVector[ptnr3]->y() );
1251 p3.
setZ( mPointVector[ptnr3]->z() );
1254 else if ( edge == -25 )
1256 const int edge1 = baseEdgeOfPoint( mTwiceInsPoint );
1257 const int edge2 = mHalfEdge[edge1]->getNext();
1258 const int edge3 = mHalfEdge[edge2]->getNext();
1259 const int ptnr1 = mHalfEdge[edge1]->getPoint();
1260 const int ptnr2 = mHalfEdge[edge2]->getPoint();
1261 const int ptnr3 = mHalfEdge[edge3]->getPoint();
1262 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1266 p1.
setX( mPointVector[ptnr1]->x() );
1267 p1.
setY( mPointVector[ptnr1]->y() );
1268 p1.
setZ( mPointVector[ptnr1]->z() );
1269 p2.
setX( mPointVector[ptnr2]->x() );
1270 p2.
setY( mPointVector[ptnr2]->y() );
1271 p2.
setZ( mPointVector[ptnr2]->z() );
1272 p3.
setX( mPointVector[ptnr3]->x() );
1273 p3.
setY( mPointVector[ptnr3]->y() );
1274 p3.
setZ( mPointVector[ptnr3]->z() );
1277 else if ( edge == -5 )
1279 const int ptnr1 = mHalfEdge[mUnstableEdge]->getPoint();
1280 const int ptnr2 = mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getPoint();
1281 const int ptnr3 = mHalfEdge[mHalfEdge[mHalfEdge[mUnstableEdge]->getNext()]->getNext()]->getPoint();
1282 if ( ptnr1 == -1 || ptnr2 == -1 || ptnr3 == -1 )
1286 p1.
setX( mPointVector[ptnr1]->x() );
1287 p1.
setY( mPointVector[ptnr1]->y() );
1288 p1.
setZ( mPointVector[ptnr1]->z() );
1289 p2.
setX( mPointVector[ptnr2]->x() );
1290 p2.
setY( mPointVector[ptnr2]->y() );
1291 p2.
setZ( mPointVector[ptnr2]->z() );
1292 p3.
setX( mPointVector[ptnr3]->x() );
1293 p3.
setY( mPointVector[ptnr3]->y() );
1294 p3.
setZ( mPointVector[ptnr3]->z() );
1303unsigned int QgsDualEdgeTriangulation::insertEdge(
int dual,
int next,
int point,
bool mbreak,
bool forced )
1306 mHalfEdge.append( edge );
1307 return mHalfEdge.count() - 1;
1310static bool altitudeTriangleIsSmall(
const QgsPoint &pointBase1,
const QgsPoint &pointBase2,
const QgsPoint &pt3,
double tolerance )
1313 const double x1 = pointBase1.
x();
1314 const double y1 = pointBase1.
y();
1315 const double x2 = pointBase2.
x();
1316 const double y2 = pointBase2.
y();
1317 const double X = pt3.
x();
1318 const double Y = pt3.
y();
1327 t = ( X * ny - Y * nx - x1 * ny + y1 * nx ) / ( ( x2 - x1 ) * ny - ( y2 - y1 ) * nx );
1328 projectedPoint.
setX( x1 + t * ( x2 - x1 ) );
1329 projectedPoint.
setY( y1 + t * ( y2 - y1 ) );
1331 return pt3.
distance( projectedPoint ) < tolerance;
1341 QgsPoint *point1 = mPointVector.at( p1 );
1342 QgsPoint *point2 = mPointVector.at( p2 );
1345 QList<int> crossedEdges;
1348 int pointingEdge = 0;
1350 pointingEdge = baseEdgeOfPoint( p1 );
1352 if ( pointingEdge == -1 )
1358 int actEdge = mHalfEdge[pointingEdge]->getDual();
1359 const int firstActEdge = actEdge;
1366 if ( control > 100 )
1372 if ( mHalfEdge[actEdge]->getPoint() == -1 )
1374 actEdge = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getNext()]->getDual();
1379 if ( mHalfEdge[actEdge]->getPoint() == p2 )
1381 mHalfEdge[actEdge]->setForced(
true );
1383 mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced(
true );
1389 if ( ( point2->
y() - point1->
y() ) / ( mPointVector[mHalfEdge[actEdge]->getPoint()]->y() - point1->
y() ) == ( point2->
x() - point1->
x() ) / ( mPointVector[mHalfEdge[actEdge]->getPoint()]->x() - point1->
x() )
1390 && ( ( point2->
y() - point1->
y() ) >= 0 ) == ( ( mPointVector[mHalfEdge[actEdge]->getPoint()]->y() - point1->
y() ) > 0 )
1391 && ( ( point2->
x() - point1->
x() ) >= 0 ) == ( ( mPointVector[mHalfEdge[actEdge]->getPoint()]->x() - point1->
x() ) > 0 ) )
1394 mHalfEdge[actEdge]->setForced(
true );
1396 mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced(
true );
1398 const int a = insertForcedSegment( mHalfEdge[actEdge]->getPoint(), p2, segmentType );
1403 const int oppositeEdge = mHalfEdge[actEdge]->getNext();
1405 if ( mHalfEdge[oppositeEdge]->getPoint() == -1 || mHalfEdge[mHalfEdge[oppositeEdge]->getDual()]->getPoint() == -1 )
1407 actEdge = mHalfEdge[mHalfEdge[oppositeEdge]->getNext()]->getDual();
1411 QgsPoint *oppositePoint1 = mPointVector[mHalfEdge[oppositeEdge]->getPoint()];
1412 QgsPoint *oppositePoint2 = mPointVector[mHalfEdge[mHalfEdge[oppositeEdge]->getDual()]->getPoint()];
1414 if ( altitudeTriangleIsSmall( *oppositePoint1, *oppositePoint2, *point1, oppositePoint1->
distance( *oppositePoint2 ) / 500 ) )
1420 if (
MathUtils::lineIntersection( point1, point2, mPointVector[mHalfEdge[oppositeEdge]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[oppositeEdge]->getDual()]->getPoint()] ) )
1424 QgsPoint crosspoint( 0, 0, 0 );
1426 p3 = mHalfEdge[mHalfEdge[actEdge]->getNext()]->getPoint();
1427 p4 = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getDual()]->getPoint();
1429 const double dista = crosspoint.distance( *mPointVector[p3] );
1430 const double distb = crosspoint.distance( *mPointVector[p4] );
1431 if ( dista <= distb )
1433 insertForcedSegment( p1, p3, segmentType );
1434 const int e = insertForcedSegment( p3, p2, segmentType );
1437 else if ( distb <= dista )
1439 insertForcedSegment( p1, p4, segmentType );
1440 const int e = insertForcedSegment( p4, p2, segmentType );
1447 QgsPoint crosspoint( 0, 0, 0 );
1449 p3 = mHalfEdge[mHalfEdge[actEdge]->getNext()]->getPoint();
1450 p4 = mHalfEdge[mHalfEdge[mHalfEdge[actEdge]->getNext()]->getDual()]->getPoint();
1452 const double distpart = crosspoint.distance( *mPointVector[p4] );
1453 const double disttot = mPointVector[p3]->distance( *mPointVector[p4] );
1454 const float frac = distpart / disttot;
1456 if ( frac == 0 || frac == 1 )
1461 mHalfEdge[actEdge]->setForced(
true );
1463 mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced(
true );
1465 const int a = insertForcedSegment( p4, p2, segmentType );
1468 else if ( frac == 1 )
1471 mHalfEdge[actEdge]->setForced(
true );
1473 mHalfEdge[mHalfEdge[actEdge]->getDual()]->setForced(
true );
1477 const int a = insertForcedSegment( p3, p2, segmentType );
1488 const int newpoint = splitHalfEdge( mHalfEdge[actEdge]->getNext(), frac );
1489 insertForcedSegment( p1, newpoint, segmentType );
1490 const int e = insertForcedSegment( newpoint, p2, segmentType );
1496 crossedEdges.append( oppositeEdge );
1499 actEdge = mHalfEdge[mHalfEdge[oppositeEdge]->getNext()]->getDual();
1500 }
while ( actEdge != firstActEdge );
1502 if ( crossedEdges.isEmpty() )
1504 int lastEdgeOppositePointIndex = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1507 while ( lastEdgeOppositePointIndex != p2 )
1509 QgsPoint *lastEdgePoint1 = mPointVector[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint()];
1510 QgsPoint *lastEdgePoint2 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint()];
1511 QgsPoint *lastEdgeOppositePoint = mPointVector[lastEdgeOppositePointIndex];
1517 QgsPoint crosspoint( 0, 0, 0 );
1519 p3 = mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint();
1520 p4 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1522 const double dista = crosspoint.distance( *mPointVector[p3] );
1523 const double distb = crosspoint.distance( *mPointVector[p4] );
1524 if ( dista <= distb )
1526 insertForcedSegment( p1, p3, segmentType );
1527 const int e = insertForcedSegment( p3, p2, segmentType );
1530 else if ( distb <= dista )
1532 insertForcedSegment( p1, p4, segmentType );
1533 const int e = insertForcedSegment( p4, p2, segmentType );
1539 QgsPoint crosspoint( 0, 0, 0 );
1541 p3 = mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint();
1542 p4 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1544 const double distpart = crosspoint.distance( *mPointVector[p3] );
1545 const double disttot = mPointVector[p3]->distance( *mPointVector[p4] );
1546 const float frac = distpart / disttot;
1547 if ( frac == 0 || frac == 1 )
1551 const int newpoint = splitHalfEdge( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext(), frac );
1552 insertForcedSegment( p1, newpoint, segmentType );
1553 const int e = insertForcedSegment( newpoint, p2, segmentType );
1557 crossedEdges.append( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext() );
1563 QgsPoint crosspoint( 0, 0, 0 );
1565 p3 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1566 p4 = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint();
1568 const double dista = crosspoint.distance( *mPointVector[p3] );
1569 const double distb = crosspoint.distance( *mPointVector[p4] );
1570 if ( dista <= distb )
1572 insertForcedSegment( p1, p3, segmentType );
1573 const int e = insertForcedSegment( p3, p2, segmentType );
1576 else if ( distb <= dista )
1578 insertForcedSegment( p1, p4, segmentType );
1579 const int e = insertForcedSegment( p4, p2, segmentType );
1585 QgsPoint crosspoint( 0, 0, 0 );
1587 p3 = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1588 p4 = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint();
1590 const double distpart = crosspoint.distance( *mPointVector[p3] );
1591 const double disttot = mPointVector[p3]->distance( *mPointVector[p4] );
1592 const float frac = distpart / disttot;
1593 if ( frac == 0 || frac == 1 )
1597 const int newpoint = splitHalfEdge( mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext(), frac );
1598 insertForcedSegment( p1, newpoint, segmentType );
1599 const int e = insertForcedSegment( newpoint, p2, segmentType );
1603 crossedEdges.append( mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext() );
1610 lastEdgeOppositePointIndex = mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getPoint();
1614 QgsPoint *lastEdgePoint1 = mPointVector[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getPoint()];
1615 QgsPoint *lastEdgePoint2 = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext()]->getNext()]->getPoint()];
1616 QgsPoint *lastEdgeOppositePoint = mPointVector[lastEdgeOppositePointIndex];
1617 if ( altitudeTriangleIsSmall( *lastEdgePoint1, *lastEdgePoint2, *lastEdgeOppositePoint, lastEdgePoint1->
distance( *lastEdgePoint2 ) / 500 ) )
1621 QList<int>::const_iterator iter;
1622 for ( iter = crossedEdges.constBegin(); iter != crossedEdges.constEnd(); ++iter )
1624 mHalfEdge[( *( iter ) )]->setForced(
false );
1625 mHalfEdge[( *( iter ) )]->setBreak(
false );
1626 mHalfEdge[mHalfEdge[( *( iter ) )]->getDual()]->setForced(
false );
1627 mHalfEdge[mHalfEdge[( *( iter ) )]->getDual()]->setBreak(
false );
1632 QList<int> freelist = crossedEdges;
1635 QList<int> leftPolygon;
1636 QList<int> rightPolygon;
1639 const int firstedge = freelist.first();
1640 mHalfEdge[firstedge]->setForced(
true );
1642 leftPolygon.append( firstedge );
1643 const int dualfirstedge = mHalfEdge[freelist.first()]->getDual();
1644 mHalfEdge[dualfirstedge]->setForced(
true );
1646 rightPolygon.append( dualfirstedge );
1647 freelist.pop_front();
1651 QList<int>::const_iterator leftiter;
1652 leftiter = crossedEdges.constEnd();
1656 const int newpoint = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[( *leftiter )]->getDual()]->getNext()]->getNext()]->getPoint();
1657 if ( newpoint != actpointl )
1660 actpointl = newpoint;
1661 const int theedge = mHalfEdge[mHalfEdge[mHalfEdge[( *leftiter )]->getDual()]->getNext()]->getNext();
1662 leftPolygon.append( theedge );
1664 if ( leftiter == crossedEdges.constBegin() )
1672 leftPolygon.append( mHalfEdge[crossedEdges.first()]->getNext() );
1675 QList<int>::const_iterator rightiter;
1677 for ( rightiter = crossedEdges.constBegin(); rightiter != crossedEdges.constEnd(); ++rightiter )
1679 const int newpoint = mHalfEdge[mHalfEdge[mHalfEdge[( *rightiter )]->getNext()]->getNext()]->getPoint();
1680 if ( newpoint != actpointr )
1683 actpointr = newpoint;
1684 const int theedge = mHalfEdge[mHalfEdge[( *rightiter )]->getNext()]->getNext();
1685 rightPolygon.append( theedge );
1691 rightPolygon.append( mHalfEdge[mHalfEdge[crossedEdges.last()]->getDual()]->getNext() );
1692 mHalfEdge[rightPolygon.last()]->setNext( dualfirstedge );
1695 int actedgel = leftPolygon[1];
1696 leftiter = leftPolygon.constBegin();
1698 for ( ; leftiter != leftPolygon.constEnd(); ++leftiter )
1700 mHalfEdge[actedgel]->setNext( ( *leftiter ) );
1701 actedgel = ( *leftiter );
1705 int actedger = rightPolygon[1];
1706 rightiter = rightPolygon.constBegin();
1708 for ( ; rightiter != rightPolygon.constEnd(); ++rightiter )
1710 mHalfEdge[actedger]->setNext( ( *rightiter ) );
1711 actedger = ( *( rightiter ) );
1716 mHalfEdge[leftPolygon.first()]->setNext( ( *( ++( leftiter = leftPolygon.constBegin() ) ) ) );
1717 mHalfEdge[leftPolygon.first()]->setPoint( p2 );
1718 mHalfEdge[leftPolygon.last()]->setNext( firstedge );
1719 mHalfEdge[rightPolygon.first()]->setNext( ( *( ++( rightiter = rightPolygon.constBegin() ) ) ) );
1720 mHalfEdge[rightPolygon.first()]->setPoint( p1 );
1721 mHalfEdge[rightPolygon.last()]->setNext( dualfirstedge );
1723 triangulatePolygon( &leftPolygon, &freelist, firstedge );
1724 triangulatePolygon( &rightPolygon, &freelist, dualfirstedge );
1727 for ( iter = crossedEdges.constBegin(); iter != crossedEdges.constEnd(); ++iter )
1729 checkSwapRecursively( ( *( iter ) ), 0 );
1732 return leftPolygon.first();
1737 mForcedCrossBehavior = b;
1742 mTriangleInterpolator = interpolator;
1748 const double minangle = 0;
1752 bool swapped =
false;
1753 bool *control =
new bool[mHalfEdge.count()];
1755 for (
int i = 0; i <= mHalfEdge.count() - 1; i++ )
1761 for (
int i = 0; i <= mHalfEdge.count() - 1; i++ )
1770 e2 = mHalfEdge[e1]->getNext();
1771 e3 = mHalfEdge[e2]->getNext();
1774 p1 = mHalfEdge[e1]->getPoint();
1775 p2 = mHalfEdge[e2]->getPoint();
1776 p3 = mHalfEdge[e3]->getPoint();
1779 if ( p1 == -1 || p2 == -1 || p3 == -1 )
1787 double el1, el2, el3;
1788 el1 = mPointVector[p1]->z();
1789 el2 = mPointVector[p2]->z();
1790 el3 = mPointVector[p3]->z();
1792 if ( el1 == el2 && el2 == el3 )
1795 if ( swapPossible( ( uint ) e1 ) && mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[e1]->getDual()]->getNext()]->getPoint()]->z() != el1 && swapMinAngle( e1 ) > minangle )
1797 doOnlySwap( ( uint ) e1 );
1800 else if ( swapPossible( ( uint ) e2 ) && mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[e2]->getDual()]->getNext()]->getPoint()]->z() != el2 && swapMinAngle( e2 ) > minangle )
1802 doOnlySwap( ( uint ) e2 );
1805 else if ( swapPossible( ( uint ) e3 ) && mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[e3]->getDual()]->getNext()]->getPoint()]->z() != el3 && swapMinAngle( e3 ) > minangle )
1807 doOnlySwap( ( uint ) e3 );
1837 const double mintol = 17;
1840 std::map<int, double> edge_angle;
1841 std::multimap<double, int> angle_edge;
1842 QSet<int> dontexamine;
1851 const int nhalfedges = mHalfEdge.count();
1853 for (
int i = 0; i < nhalfedges - 1; i++ )
1855 const int next = mHalfEdge[i]->getNext();
1856 const int nextnext = mHalfEdge[next]->getNext();
1858 if ( mHalfEdge[next]->getPoint() != -1 && ( mHalfEdge[i]->getForced() || mHalfEdge[mHalfEdge[mHalfEdge[i]->getDual()]->getNext()]->getPoint() == -1 ) )
1860 if ( !( ( mHalfEdge[next]->getForced() || edgeOnConvexHull( next ) ) || ( mHalfEdge[nextnext]->getForced() || edgeOnConvexHull( nextnext ) ) ) )
1863 while (
MathUtils::inDiametral( mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()], mPointVector[mHalfEdge[i]->getPoint()], mPointVector[mHalfEdge[next]->getPoint()] ) )
1866 const int pointno = splitHalfEdge( i, 0.5 );
1878 for (
int i = 0; i < mHalfEdge.count() - 1; i++ )
1880 p1 = mHalfEdge[mHalfEdge[i]->getDual()]->getPoint();
1881 p2 = mHalfEdge[i]->getPoint();
1882 p3 = mHalfEdge[mHalfEdge[i]->getNext()]->getPoint();
1884 if ( p1 == -1 || p2 == -1 || p3 == -1 )
1888 angle =
MathUtils::angle( mPointVector[p1], mPointVector[p2], mPointVector[p3], mPointVector[p2] );
1890 bool twoforcededges;
1893 twoforcededges = ( mHalfEdge[i]->getForced() || edgeOnConvexHull( i ) ) && ( mHalfEdge[mHalfEdge[i]->getNext()]->getForced() || edgeOnConvexHull( mHalfEdge[i]->getNext() ) );
1895 if ( angle < mintol && !twoforcededges )
1897 edge_angle.insert( std::make_pair( i, angle ) );
1898 angle_edge.insert( std::make_pair( angle, i ) );
1903 for ( std::multimap<double, int>::const_iterator it = angle_edge.begin(); it != angle_edge.end(); ++it )
1909 double minangle = 0;
1912 int minedgenextnext;
1916 while ( !edge_angle.empty() )
1918 minangle = angle_edge.begin()->first;
1920 minedge = angle_edge.begin()->second;
1921 minedgenext = mHalfEdge[minedge]->getNext();
1922 minedgenextnext = mHalfEdge[minedgenext]->getNext();
1925 if ( !
MathUtils::circumcenter( mPointVector[mHalfEdge[minedge]->getPoint()], mPointVector[mHalfEdge[minedgenext]->getPoint()], mPointVector[mHalfEdge[minedgenextnext]->getPoint()], &circumcenter ) )
1927 QgsDebugError( u
"warning, calculation of circumcenter failed"_s );
1929 dontexamine.insert( minedge );
1930 edge_angle.erase( minedge );
1931 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
1932 while ( minedgeiter->second != minedge )
1936 angle_edge.erase( minedgeiter );
1940 if ( !
pointInside( circumcenter.x(), circumcenter.y() ) )
1943 QgsDebugError( u
"put circumcenter %1//%2 on dontexamine list because it is outside the convex hull"_s
1944 .arg( circumcenter.x() )
1945 .arg( circumcenter.y() ) );
1946 dontexamine.insert( minedge );
1947 edge_angle.erase( minedge );
1948 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
1949 while ( minedgeiter->second != minedge )
1953 angle_edge.erase( minedgeiter );
1959 bool encroached =
false;
1962 int numhalfedges = mHalfEdge.count();
1963 for (
int i = 0; i < numhalfedges; i++ )
1965 if ( mHalfEdge[i]->getForced() || edgeOnConvexHull( i ) )
1967 if (
MathUtils::inDiametral( mPointVector[mHalfEdge[i]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[i]->getDual()]->getPoint()], &circumcenter ) )
1972 int pointno = splitHalfEdge( i, 0.5 );
1975 int pointingedge = baseEdgeOfPoint( pointno );
1977 int actedge = pointingedge;
1980 double angle1, angle2, angle3;
1984 ed1 = mHalfEdge[actedge]->getDual();
1985 pt1 = mHalfEdge[ed1]->getPoint();
1986 ed2 = mHalfEdge[ed1]->getNext();
1987 pt2 = mHalfEdge[ed2]->getPoint();
1988 ed3 = mHalfEdge[ed2]->getNext();
1989 pt3 = mHalfEdge[ed3]->getPoint();
1992 if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
1997 angle1 =
MathUtils::angle( mPointVector[pt3], mPointVector[pt1], mPointVector[pt2], mPointVector[pt1] );
1998 angle2 =
MathUtils::angle( mPointVector[pt1], mPointVector[pt2], mPointVector[pt3], mPointVector[pt2] );
1999 angle3 =
MathUtils::angle( mPointVector[pt2], mPointVector[pt3], mPointVector[pt1], mPointVector[pt3] );
2002 bool twoforcededges1, twoforcededges2, twoforcededges3;
2004 if ( ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) && ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) )
2006 twoforcededges1 =
true;
2010 twoforcededges1 =
false;
2013 if ( ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) && ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) )
2015 twoforcededges2 =
true;
2019 twoforcededges2 =
false;
2022 if ( ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) && ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) )
2024 twoforcededges3 =
true;
2028 twoforcededges3 =
false;
2032 QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
2033 if ( ed1iter != dontexamine.end() )
2036 dontexamine.erase( ed1iter );
2041 std::map<int, double>::iterator tempit1;
2042 tempit1 = edge_angle.find( ed1 );
2043 if ( tempit1 != edge_angle.end() )
2046 double angle = tempit1->second;
2047 edge_angle.erase( ed1 );
2048 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2049 while ( tempit2->second != ed1 )
2053 angle_edge.erase( tempit2 );
2057 if ( angle1 < mintol && !twoforcededges1 )
2059 edge_angle.insert( std::make_pair( ed1, angle1 ) );
2060 angle_edge.insert( std::make_pair( angle1, ed1 ) );
2064 QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
2065 if ( ed2iter != dontexamine.end() )
2068 dontexamine.erase( ed2iter );
2073 std::map<int, double>::iterator tempit1;
2074 tempit1 = edge_angle.find( ed2 );
2075 if ( tempit1 != edge_angle.end() )
2078 double angle = tempit1->second;
2079 edge_angle.erase( ed2 );
2080 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2081 while ( tempit2->second != ed2 )
2085 angle_edge.erase( tempit2 );
2089 if ( angle2 < mintol && !twoforcededges2 )
2091 edge_angle.insert( std::make_pair( ed2, angle2 ) );
2092 angle_edge.insert( std::make_pair( angle2, ed2 ) );
2096 QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
2097 if ( ed3iter != dontexamine.end() )
2100 dontexamine.erase( ed3iter );
2105 std::map<int, double>::iterator tempit1;
2106 tempit1 = edge_angle.find( ed3 );
2107 if ( tempit1 != edge_angle.end() )
2110 double angle = tempit1->second;
2111 edge_angle.erase( ed3 );
2112 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2113 while ( tempit2->second != ed3 )
2117 angle_edge.erase( tempit2 );
2121 if ( angle3 < mintol && !twoforcededges3 )
2123 edge_angle.insert( std::make_pair( ed3, angle3 ) );
2124 angle_edge.insert( std::make_pair( angle3, ed3 ) );
2129 while ( actedge != pointingedge );
2137 QSet<int> influenceedges;
2138 int baseedge = baseEdgeOfTriangle( circumcenter );
2139 if ( baseedge == -5 )
2142 edge_angle.erase( minedge );
2143 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
2144 while ( minedgeiter->second != minedge )
2148 angle_edge.erase( minedgeiter );
2151 else if ( baseedge == -25 )
2154 edge_angle.erase( minedge );
2155 std::multimap<double, int>::iterator minedgeiter = angle_edge.find( minangle );
2156 while ( minedgeiter->second != minedge )
2160 angle_edge.erase( minedgeiter );
2163 else if ( baseedge == -20 )
2165 baseedge = mEdgeWithPoint;
2168 evaluateInfluenceRegion( &circumcenter, baseedge, influenceedges );
2169 evaluateInfluenceRegion( &circumcenter, mHalfEdge[baseedge]->getNext(), influenceedges );
2170 evaluateInfluenceRegion( &circumcenter, mHalfEdge[mHalfEdge[baseedge]->getNext()]->getNext(), influenceedges );
2172 for ( QSet<int>::iterator it = influenceedges.begin(); it != influenceedges.end(); ++it )
2174 if ( ( mHalfEdge[*it]->getForced() || edgeOnConvexHull( *it ) ) &&
MathUtils::inDiametral( mPointVector[mHalfEdge[*it]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[*it]->getDual()]->getPoint()], &circumcenter ) )
2178 const int pointno = splitHalfEdge( *it, 0.5 );
2182 const int pointingedge = baseEdgeOfPoint( pointno );
2184 int actedge = pointingedge;
2187 double angle1, angle2, angle3;
2191 ed1 = mHalfEdge[actedge]->getDual();
2192 pt1 = mHalfEdge[ed1]->getPoint();
2193 ed2 = mHalfEdge[ed1]->getNext();
2194 pt2 = mHalfEdge[ed2]->getPoint();
2195 ed3 = mHalfEdge[ed2]->getNext();
2196 pt3 = mHalfEdge[ed3]->getPoint();
2199 if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
2204 angle1 =
MathUtils::angle( mPointVector[pt3], mPointVector[pt1], mPointVector[pt2], mPointVector[pt1] );
2205 angle2 =
MathUtils::angle( mPointVector[pt1], mPointVector[pt2], mPointVector[pt3], mPointVector[pt2] );
2206 angle3 =
MathUtils::angle( mPointVector[pt2], mPointVector[pt3], mPointVector[pt1], mPointVector[pt3] );
2209 bool twoforcededges1, twoforcededges2, twoforcededges3;
2212 twoforcededges1 = ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) && ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) );
2214 twoforcededges2 = ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) && ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) );
2216 twoforcededges3 = ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) && ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) );
2220 const QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
2221 if ( ed1iter != dontexamine.end() )
2224 dontexamine.erase( ed1iter );
2229 std::map<int, double>::iterator tempit1;
2230 tempit1 = edge_angle.find( ed1 );
2231 if ( tempit1 != edge_angle.end() )
2234 const double angle = tempit1->second;
2235 edge_angle.erase( ed1 );
2236 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2237 while ( tempit2->second != ed1 )
2241 angle_edge.erase( tempit2 );
2245 if ( angle1 < mintol && !twoforcededges1 )
2247 edge_angle.insert( std::make_pair( ed1, angle1 ) );
2248 angle_edge.insert( std::make_pair( angle1, ed1 ) );
2252 const QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
2253 if ( ed2iter != dontexamine.end() )
2256 dontexamine.erase( ed2iter );
2261 std::map<int, double>::iterator tempit1;
2262 tempit1 = edge_angle.find( ed2 );
2263 if ( tempit1 != edge_angle.end() )
2266 const double angle = tempit1->second;
2267 edge_angle.erase( ed2 );
2268 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2269 while ( tempit2->second != ed2 )
2273 angle_edge.erase( tempit2 );
2277 if ( angle2 < mintol && !twoforcededges2 )
2279 edge_angle.insert( std::make_pair( ed2, angle2 ) );
2280 angle_edge.insert( std::make_pair( angle2, ed2 ) );
2284 const QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
2285 if ( ed3iter != dontexamine.end() )
2288 dontexamine.erase( ed3iter );
2293 std::map<int, double>::iterator tempit1;
2294 tempit1 = edge_angle.find( ed3 );
2295 if ( tempit1 != edge_angle.end() )
2298 const double angle = tempit1->second;
2299 edge_angle.erase( ed3 );
2300 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2301 while ( tempit2->second != ed3 )
2305 angle_edge.erase( tempit2 );
2309 if ( angle3 < mintol && !twoforcededges3 )
2311 edge_angle.insert( std::make_pair( ed3, angle3 ) );
2312 angle_edge.insert( std::make_pair( angle3, ed3 ) );
2316 }
while ( actedge != pointingedge );
2329 calcPoint( circumcenter.x(), circumcenter.y(), p );
2332 if ( pointno == -100 || pointno == mTwiceInsPoint )
2334 if ( pointno == -100 )
2336 QgsDebugError( u
"put circumcenter %1//%2 on dontexamine list because of numerical instabilities"_s
2337 .arg( circumcenter.x() )
2338 .arg( circumcenter.y() ) );
2340 else if ( pointno == mTwiceInsPoint )
2342 QgsDebugError( u
"put circumcenter %1//%2 on dontexamine list because it is already inserted"_s
2343 .arg( circumcenter.x() )
2344 .arg( circumcenter.y() ) );
2347 for (
int i = 0; i < mPointVector.count(); i++ )
2349 if ( mPointVector[i]->x() == circumcenter.x() && mPointVector[i]->y() == circumcenter.y() )
2356 QgsDebugError( u
"point is not present in the triangulation"_s );
2360 dontexamine.insert( minedge );
2361 edge_angle.erase( minedge );
2362 std::multimap<double, int>::iterator minedgeiter = angle_edge.lower_bound( minangle );
2363 while ( minedgeiter->second != minedge )
2367 angle_edge.erase( minedgeiter );
2376 const int pointingedge = baseEdgeOfPoint( pointno );
2378 int actedge = pointingedge;
2381 double angle1, angle2, angle3;
2385 ed1 = mHalfEdge[actedge]->getDual();
2386 pt1 = mHalfEdge[ed1]->getPoint();
2387 ed2 = mHalfEdge[ed1]->getNext();
2388 pt2 = mHalfEdge[ed2]->getPoint();
2389 ed3 = mHalfEdge[ed2]->getNext();
2390 pt3 = mHalfEdge[ed3]->getPoint();
2393 if ( pt1 == -1 || pt2 == -1 || pt3 == -1 )
2398 angle1 =
MathUtils::angle( mPointVector[pt3], mPointVector[pt1], mPointVector[pt2], mPointVector[pt1] );
2399 angle2 =
MathUtils::angle( mPointVector[pt1], mPointVector[pt2], mPointVector[pt3], mPointVector[pt2] );
2400 angle3 =
MathUtils::angle( mPointVector[pt2], mPointVector[pt3], mPointVector[pt1], mPointVector[pt3] );
2403 bool twoforcededges1, twoforcededges2, twoforcededges3;
2405 twoforcededges1 = ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) ) && ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) );
2407 twoforcededges2 = ( mHalfEdge[ed2]->getForced() || edgeOnConvexHull( ed2 ) ) && ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) );
2409 twoforcededges3 = ( mHalfEdge[ed3]->getForced() || edgeOnConvexHull( ed3 ) ) && ( mHalfEdge[ed1]->getForced() || edgeOnConvexHull( ed1 ) );
2413 const QSet<int>::iterator ed1iter = dontexamine.find( ed1 );
2414 if ( ed1iter != dontexamine.end() )
2417 dontexamine.erase( ed1iter );
2422 std::map<int, double>::iterator tempit1;
2423 tempit1 = edge_angle.find( ed1 );
2424 if ( tempit1 != edge_angle.end() )
2427 const double angle = tempit1->second;
2428 edge_angle.erase( ed1 );
2429 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2430 while ( tempit2->second != ed1 )
2434 angle_edge.erase( tempit2 );
2438 if ( angle1 < mintol && !twoforcededges1 )
2440 edge_angle.insert( std::make_pair( ed1, angle1 ) );
2441 angle_edge.insert( std::make_pair( angle1, ed1 ) );
2446 const QSet<int>::iterator ed2iter = dontexamine.find( ed2 );
2447 if ( ed2iter != dontexamine.end() )
2450 dontexamine.erase( ed2iter );
2455 std::map<int, double>::iterator tempit1;
2456 tempit1 = edge_angle.find( ed2 );
2457 if ( tempit1 != edge_angle.end() )
2460 const double angle = tempit1->second;
2461 edge_angle.erase( ed2 );
2462 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2463 while ( tempit2->second != ed2 )
2467 angle_edge.erase( tempit2 );
2471 if ( angle2 < mintol && !twoforcededges2 )
2473 edge_angle.insert( std::make_pair( ed2, angle2 ) );
2474 angle_edge.insert( std::make_pair( angle2, ed2 ) );
2478 const QSet<int>::iterator ed3iter = dontexamine.find( ed3 );
2479 if ( ed3iter != dontexamine.end() )
2482 dontexamine.erase( ed3iter );
2487 std::map<int, double>::iterator tempit1;
2488 tempit1 = edge_angle.find( ed3 );
2489 if ( tempit1 != edge_angle.end() )
2492 const double angle = tempit1->second;
2493 edge_angle.erase( ed3 );
2494 std::multimap<double, int>::iterator tempit2 = angle_edge.lower_bound( angle );
2495 while ( tempit2->second != ed3 )
2499 angle_edge.erase( tempit2 );
2503 if ( angle3 < mintol && !twoforcededges3 )
2505 edge_angle.insert( std::make_pair( ed3, angle3 ) );
2506 angle_edge.insert( std::make_pair( angle3, ed3 ) );
2510 }
while ( actedge != pointingedge );
2516 for ( QSet<int>::iterator it = dontexamine.begin(); it != dontexamine.end(); ++it )
2524bool QgsDualEdgeTriangulation::swapPossible(
unsigned int edge )
const
2527 if ( mHalfEdge[edge]->getForced() )
2533 if ( mHalfEdge[edge]->getPoint() == -1 || mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() == -1 || mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() == -1 || mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() == -1 )
2538 QgsPoint *pta = mPointVector[mHalfEdge[edge]->getPoint()];
2539 QgsPoint *ptb = mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()];
2540 QgsPoint *ptc = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getNext()]->getNext()]->getPoint()];
2541 QgsPoint *ptd = mPointVector[mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint()];
2561void QgsDualEdgeTriangulation::triangulatePolygon( QList<int> *poly, QList<int> *free,
int mainedge )
2565 if ( poly->count() == 3 )
2571 QList<int>::const_iterator iterator = ++( poly->constBegin() );
2572 double distance =
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] );
2573 int distedge = ( *iterator );
2574 int nextdistedge = mHalfEdge[( *iterator )]->getNext();
2577 while ( iterator != --( poly->constEnd() ) )
2579 if (
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] ) < distance )
2581 distedge = ( *iterator );
2582 nextdistedge = mHalfEdge[( *iterator )]->getNext();
2583 distance =
MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] );
2588 if ( nextdistedge == ( *( --poly->end() ) ) )
2590 const int inserta = free->first();
2591 const int insertb = mHalfEdge[inserta]->getDual();
2594 mHalfEdge[inserta]->setNext( ( poly->at( 1 ) ) );
2595 mHalfEdge[inserta]->setPoint( mHalfEdge[mainedge]->getPoint() );
2596 mHalfEdge[insertb]->setNext( nextdistedge );
2597 mHalfEdge[insertb]->setPoint( mHalfEdge[distedge]->getPoint() );
2598 mHalfEdge[distedge]->setNext( inserta );
2599 mHalfEdge[mainedge]->setNext( insertb );
2602 for ( iterator = ( ++( poly->constBegin() ) ); ( *iterator ) != nextdistedge; ++iterator )
2604 polya.append( ( *iterator ) );
2606 polya.prepend( inserta );
2610 for ( iterator = polya.begin(); iterator != polya.end(); ++iterator )
2616 triangulatePolygon( &polya, free, inserta );
2619 else if ( distedge == ( *( ++poly->begin() ) ) )
2621 const int inserta = free->first();
2622 const int insertb = mHalfEdge[inserta]->getDual();
2625 mHalfEdge[inserta]->setNext( ( poly->at( 2 ) ) );
2626 mHalfEdge[inserta]->setPoint( mHalfEdge[distedge]->getPoint() );
2627 mHalfEdge[insertb]->setNext( mainedge );
2628 mHalfEdge[insertb]->setPoint( mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint() );
2629 mHalfEdge[distedge]->setNext( insertb );
2630 mHalfEdge[( *( --poly->end() ) )]->setNext( inserta );
2633 iterator = poly->constBegin();
2635 while ( iterator != poly->constEnd() )
2637 polya.append( ( *iterator ) );
2640 polya.prepend( inserta );
2642 triangulatePolygon( &polya, free, inserta );
2647 const int inserta = free->first();
2648 const int insertb = mHalfEdge[inserta]->getDual();
2651 const int insertc = free->first();
2652 const int insertd = mHalfEdge[insertc]->getDual();
2655 mHalfEdge[inserta]->setNext( ( poly->at( 1 ) ) );
2656 mHalfEdge[inserta]->setPoint( mHalfEdge[mainedge]->getPoint() );
2657 mHalfEdge[insertb]->setNext( insertd );
2658 mHalfEdge[insertb]->setPoint( mHalfEdge[distedge]->getPoint() );
2659 mHalfEdge[insertc]->setNext( nextdistedge );
2660 mHalfEdge[insertc]->setPoint( mHalfEdge[distedge]->getPoint() );
2661 mHalfEdge[insertd]->setNext( mainedge );
2662 mHalfEdge[insertd]->setPoint( mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint() );
2664 mHalfEdge[distedge]->setNext( inserta );
2665 mHalfEdge[mainedge]->setNext( insertb );
2666 mHalfEdge[( *( --poly->end() ) )]->setNext( insertc );
2672 for ( iterator = ++( poly->constBegin() ); ( *iterator ) != nextdistedge; ++iterator )
2674 polya.append( ( *iterator ) );
2676 polya.prepend( inserta );
2679 while ( iterator != poly->constEnd() )
2681 polyb.append( ( *iterator ) );
2684 polyb.prepend( insertc );
2686 triangulatePolygon( &polya, free, inserta );
2687 triangulatePolygon( &polyb, free, insertc );
2700 unsigned int actedge = mEdgeInside;
2708 if ( runs > MAX_BASE_ITERATIONS )
2710 QgsDebugError( u
"warning, instability detected: Point coordinates: %1//%2"_s.arg( x ).arg( y ) );
2714 if (
MathUtils::leftOf(
point, mPointVector[mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[actedge]->getPoint()] ) < ( -
leftOfTresh ) )
2723 else if ( fabs(
MathUtils::leftOf(
point, mPointVector[mHalfEdge[mHalfEdge[actedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[actedge]->getPoint()] ) ) <=
leftOfTresh )
2726 mEdgeWithPoint = actedge;
2736 actedge = mHalfEdge[actedge]->getDual();
2742 actedge = mHalfEdge[actedge]->getNext();
2743 if ( mHalfEdge[actedge]->getPoint() == -1 )
2749 mEdgeOutside = (
unsigned int ) mHalfEdge[mHalfEdge[actedge]->getNext()]->getNext();
2759 if ( numinstabs > 0 )
2769 mEdgeInside = actedge;
2774bool DualEdgeTriangulation::readFromTAFF( QString filename )
2776 QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
2778 QFile file( filename );
2779 file.open( IO_Raw | IO_ReadOnly );
2780 QBuffer buffer( file.readAll() );
2783 QTextStream textstream( &buffer );
2784 buffer.open( IO_ReadOnly );
2787 int numberofhalfedges;
2791 while ( buff.mid( 0, 4 ) !=
"TRIA" )
2793 buff = textstream.readLine();
2795 while ( buff.mid( 0, 4 ) !=
"NEDG" )
2797 buff = textstream.readLine();
2799 numberofhalfedges = buff.section(
' ', 1, 1 ).toInt();
2800 mHalfEdge.resize( numberofhalfedges );
2803 while ( buff.mid( 0, 4 ) !=
"DATA" )
2808 int nr1, nr2, dual1, dual2, point1, point2, next1, next2, fo1, fo2, b1, b2;
2809 bool forced1, forced2, break1, break2;
2813 QProgressBar *edgebar =
new QProgressBar();
2814 edgebar->setCaption( tr(
"Reading edges…" ) );
2815 edgebar->setTotalSteps( numberofhalfedges / 2 );
2816 edgebar->setMinimumWidth( 400 );
2817 edgebar->move( 500, 500 );
2820 for (
int i = 0; i < numberofhalfedges / 2; i++ )
2822 if ( i % 1000 == 0 )
2824 edgebar->setProgress( i );
2828 textstream >> point1;
2829 textstream >> next1;
2853 textstream >> point2;
2854 textstream >> next2;
2892 mHalfEdge.insert( nr1, hf1 );
2893 mHalfEdge.insert( nr2, hf2 );
2897 edgebar->setProgress( numberofhalfedges / 2 );
2901 for (
int i = 0; i < numberofhalfedges; i++ )
2904 a = mHalfEdge[i]->getPoint();
2905 b = mHalfEdge[mHalfEdge[i]->getDual()]->getPoint();
2906 c = mHalfEdge[mHalfEdge[i]->getNext()]->getPoint();
2907 d = mHalfEdge[mHalfEdge[mHalfEdge[i]->getDual()]->getNext()]->getPoint();
2908 if ( a != -1 && b != -1 &&
c != -1 && d != -1 )
2916 while ( buff.mid( 0, 4 ) !=
"POIN" )
2918 buff = textstream.readLine();
2921 while ( buff.mid( 0, 4 ) !=
"NPTS" )
2923 buff = textstream.readLine();
2926 numberofpoints = buff.section(
' ', 1, 1 ).toInt();
2927 mPointVector.resize( numberofpoints );
2929 while ( buff.mid( 0, 4 ) !=
"DATA" )
2934 QProgressBar *pointbar =
new QProgressBar();
2935 pointbar->setCaption( tr(
"Reading points…" ) );
2936 pointbar->setTotalSteps( numberofpoints );
2937 pointbar->setMinimumWidth( 400 );
2938 pointbar->move( 500, 500 );
2943 for (
int i = 0; i < numberofpoints; i++ )
2945 if ( i % 1000 == 0 )
2947 pointbar->setProgress( i );
2957 mPointVector.insert( i, p );
2973 else if ( x > xMax )
2982 else if ( y > yMax )
2989 pointbar->setProgress( numberofpoints );
2991 QApplication::restoreOverrideCursor();
2995bool DualEdgeTriangulation::saveToTAFF( QString filename )
const
2997 QFile outputfile( filename );
2998 if ( !outputfile.open( IO_WriteOnly ) )
3000 QMessageBox::warning( 0, tr(
"Warning" ), tr(
"File could not be written." ), QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton );
3004 QTextStream outstream( &outputfile );
3005 outstream.precision( 9 );
3008 outstream <<
"TRIA" << std::endl << std::flush;
3009 outstream <<
"NEDG " << mHalfEdge.count() << std::endl << std::flush;
3010 outstream <<
"PANO 1" << std::endl << std::flush;
3011 outstream <<
"DATA ";
3013 bool *cont =
new bool[mHalfEdge.count()];
3014 for (
unsigned int i = 0; i <= mHalfEdge.count() - 1; i++ )
3019 for (
unsigned int i = 0; i < mHalfEdge.count(); i++ )
3026 int dual = mHalfEdge[i]->getDual();
3027 outstream << i <<
" " << mHalfEdge[i]->getPoint() <<
" " << mHalfEdge[i]->getNext() <<
" " << mHalfEdge[i]->getForced() <<
" " << mHalfEdge[i]->getBreak() <<
" ";
3028 outstream << dual <<
" " << mHalfEdge[dual]->getPoint() <<
" " << mHalfEdge[dual]->getNext() <<
" " << mHalfEdge[dual]->getForced() <<
" " << mHalfEdge[dual]->getBreak() <<
" ";
3032 outstream << std::endl << std::flush;
3033 outstream << std::endl << std::flush;
3038 outstream <<
"POIN" << std::endl << std::flush;
3039 outstream <<
"NPTS " << getNumberOfPoints() << std::endl << std::flush;
3040 outstream <<
"PATT 3" << std::endl << std::flush;
3041 outstream <<
"DATA ";
3043 for (
int i = 0; i < getNumberOfPoints(); i++ )
3046 outstream << p->getX() <<
" " << p->getY() <<
" " << p->getZ() <<
" ";
3048 outstream << std::endl << std::flush;
3049 outstream << std::endl << std::flush;
3058 const int edge1 = baseEdgeOfTriangle( p );
3065 edge2 = mHalfEdge[edge1]->getNext();
3066 edge3 = mHalfEdge[edge2]->getNext();
3067 point1 =
point( mHalfEdge[edge1]->getPoint() );
3068 point2 =
point( mHalfEdge[edge2]->getPoint() );
3069 point3 =
point( mHalfEdge[edge3]->getPoint() );
3070 if ( point1 && point2 && point3 )
3073 double dist1, dist2, dist3;
3077 if ( dist1 <= dist2 && dist1 <= dist3 )
3080 if ( swapPossible( edge1 ) )
3082 doOnlySwap( edge1 );
3085 else if ( dist2 <= dist1 && dist2 <= dist3 )
3088 if ( swapPossible( edge2 ) )
3090 doOnlySwap( edge2 );
3093 else if ( dist3 <= dist1 && dist3 <= dist2 )
3096 if ( swapPossible( edge3 ) )
3098 doOnlySwap( edge3 );
3120 const int edge1 = baseEdgeOfTriangle( p );
3123 const int edge2 = mHalfEdge[edge1]->getNext();
3124 const int edge3 = mHalfEdge[edge2]->getNext();
3128 if ( point1 && point2 && point3 )
3134 if ( dist1 <= dist2 && dist1 <= dist3 )
3136 p1 = mHalfEdge[edge1]->getPoint();
3137 p2 = mHalfEdge[mHalfEdge[edge1]->getNext()]->getPoint();
3138 p3 = mHalfEdge[mHalfEdge[edge1]->getDual()]->getPoint();
3139 p4 = mHalfEdge[mHalfEdge[mHalfEdge[edge1]->getDual()]->getNext()]->getPoint();
3141 else if ( dist2 <= dist1 && dist2 <= dist3 )
3143 p1 = mHalfEdge[edge2]->getPoint();
3144 p2 = mHalfEdge[mHalfEdge[edge2]->getNext()]->getPoint();
3145 p3 = mHalfEdge[mHalfEdge[edge2]->getDual()]->getPoint();
3146 p4 = mHalfEdge[mHalfEdge[mHalfEdge[edge2]->getDual()]->getNext()]->getPoint();
3150 p1 = mHalfEdge[edge3]->getPoint();
3151 p2 = mHalfEdge[mHalfEdge[edge3]->getNext()]->getPoint();
3152 p3 = mHalfEdge[mHalfEdge[edge3]->getDual()]->getPoint();
3153 p4 = mHalfEdge[mHalfEdge[mHalfEdge[edge3]->getDual()]->getNext()]->getPoint();
3181 bool *alreadyVisitedEdges =
new bool[mHalfEdge.size()];
3182 if ( !alreadyVisitedEdges )
3188 for (
int i = 0; i < mHalfEdge.size(); ++i )
3190 alreadyVisitedEdges[i] =
false;
3193 for (
int i = 0; i < mHalfEdge.size(); ++i )
3198 HalfEdge *currentEdge = mHalfEdge[i];
3199 if ( currentEdge->
getPoint() != -1 && mHalfEdge[currentEdge->
getDual()]->getPoint() != -1 && !alreadyVisitedEdges[currentEdge->
getDual()] )
3205 QgsPoint *p2 = mPointVector[mHalfEdge[currentEdge->
getDual()]->getPoint()];
3213 QString attributeString;
3218 attributeString = u
"break line"_s;
3222 attributeString = u
"structure line"_s;
3229 alreadyVisitedEdges[i] =
true;
3232 delete[] alreadyVisitedEdges;
3242 QVector<bool> edgeToTreat( mHalfEdge.count(),
true );
3243 QHash<HalfEdge *, int> edgesHash;
3244 for (
int i = 0; i < mHalfEdge.count(); ++i )
3246 edgesHash.insert( mHalfEdge[i], i );
3255 const int edgeCount = edgeToTreat.count();
3256 for (
int i = 0; i < edgeCount; ++i )
3258 bool containVirtualPoint =
false;
3259 if ( edgeToTreat[i] )
3261 HalfEdge *currentEdge = mHalfEdge[i];
3266 edgeToTreat[edgesHash.value( currentEdge )] =
false;
3267 face.append( currentEdge->
getPoint() );
3268 containVirtualPoint |= currentEdge->
getPoint() == -1;
3269 currentEdge = mHalfEdge.at( currentEdge->
getNext() );
3270 }
while ( currentEdge != firstEdge && !containVirtualPoint && ( !feedback || !feedback->
isCanceled() ) );
3271 if ( !containVirtualPoint )
3272 mesh.
faces.append( face );
3283double QgsDualEdgeTriangulation::swapMinAngle(
int edge )
const
3286 QgsPoint *p2 =
point( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() );
3287 QgsPoint *p3 =
point( mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() );
3288 QgsPoint *p4 =
point( mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() );
3295 if ( angle2 < minangle )
3300 if ( angle3 < minangle )
3305 if ( angle4 < minangle )
3310 if ( angle5 < minangle )
3315 if ( angle6 < minangle )
3323int QgsDualEdgeTriangulation::splitHalfEdge(
int edge,
float position )
3326 if ( position < 0 || position > 1 )
3328 QgsDebugError( u
"warning, position is not between 0 and 1"_s );
3332 QgsPoint *p =
new QgsPoint( mPointVector[mHalfEdge[edge]->getPoint()]->x() * position + mPointVector[mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint()]->x() * ( 1 - position ), mPointVector[mHalfEdge[edge]->getPoint()]->y() * position + mPointVector[mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint()]->y() * ( 1 - position ), 0 );
3335 QgsPoint zvaluepoint( 0, 0, 0 );
3337 p->
setZ( zvaluepoint.z() );
3340 if ( mPointVector.count() >= mPointVector.size() )
3342 mPointVector.resize( mPointVector.count() + 1 );
3344 QgsDebugMsgLevel( u
"inserting point nr. %1, %2//%3//%4"_s.arg( mPointVector.count() ).arg( p->
x() ).arg( p->
y() ).arg( p->
z() ), 2 );
3345 mPointVector.insert( mPointVector.count(), p );
3348 const int dualedge = mHalfEdge[edge]->getDual();
3349 const int edge1 = insertEdge( -10, -10, mPointVector.count() - 1,
false,
false );
3350 const int edge2 = insertEdge( edge1, mHalfEdge[mHalfEdge[edge]->getNext()]->getNext(), mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint(),
false,
false );
3351 const int edge3 = insertEdge( -10, mHalfEdge[mHalfEdge[dualedge]->getNext()]->getNext(), mHalfEdge[mHalfEdge[dualedge]->getNext()]->getPoint(),
false,
false );
3352 const int edge4 = insertEdge( edge3, dualedge, mPointVector.count() - 1,
false,
false );
3353 const int edge5 = insertEdge( -10, mHalfEdge[edge]->getNext(), mHalfEdge[edge]->getPoint(), mHalfEdge[edge]->getBreak(), mHalfEdge[edge]->getForced() );
3354 const int edge6 = insertEdge( edge5, edge3, mPointVector.count() - 1, mHalfEdge[dualedge]->getBreak(), mHalfEdge[dualedge]->getForced() );
3355 mHalfEdge[edge1]->setDual( edge2 );
3356 mHalfEdge[edge1]->setNext( edge5 );
3357 mHalfEdge[edge3]->setDual( edge4 );
3358 mHalfEdge[edge5]->setDual( edge6 );
3361 mHalfEdge[mHalfEdge[edge]->getNext()]->setNext( edge1 );
3362 mHalfEdge[mHalfEdge[dualedge]->getNext()]->setNext( edge4 );
3363 mHalfEdge[edge]->setNext( edge2 );
3364 mHalfEdge[edge]->setPoint( mPointVector.count() - 1 );
3365 mHalfEdge[mHalfEdge[edge3]->getNext()]->setNext( edge6 );
3368 checkSwapRecursively( mHalfEdge[edge5]->getNext(), 0 );
3369 checkSwapRecursively( mHalfEdge[edge2]->getNext(), 0 );
3370 checkSwapRecursively( mHalfEdge[dualedge]->getNext(), 0 );
3371 checkSwapRecursively( mHalfEdge[edge3]->getNext(), 0 );
3375 return mPointVector.count() - 1;
3378bool QgsDualEdgeTriangulation::edgeOnConvexHull(
int edge )
3380 return ( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() == -1 || mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getPoint() == -1 );
3383void QgsDualEdgeTriangulation::evaluateInfluenceRegion(
QgsPoint *point,
int edge, QSet<int> &set )
3385 if ( set.find( edge ) == set.end() )
3394 if ( !mHalfEdge[edge]->getForced() && !edgeOnConvexHull( edge ) )
3397 if (
inCircle( *
point, *mPointVector[mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint()], *mPointVector[mHalfEdge[edge]->getPoint()], *mPointVector[mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint()] ) )
3399 evaluateInfluenceRegion(
point, mHalfEdge[mHalfEdge[edge]->getDual()]->getNext(), set );
3400 evaluateInfluenceRegion(
point, mHalfEdge[mHalfEdge[mHalfEdge[edge]->getDual()]->getNext()]->getNext(), set );
3405int QgsDualEdgeTriangulation::firstEdgeOutSide()
3408 while ( ( mHalfEdge[mHalfEdge[edge]->getNext()]->getPoint() != -1 || mHalfEdge[edge]->getPoint() == -1 || mHalfEdge[mHalfEdge[edge]->getDual()]->getPoint() == -1 ) && edge < mHalfEdge.count() )
3413 if ( edge >= mHalfEdge.count() )
3419void QgsDualEdgeTriangulation::removeLastPoint()
3421 if ( mPointVector.isEmpty() )
3423 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