@@ -487,27 +487,32 @@ void QgsCircularString::setPoints( const QgsPointSequence &points )
487
487
488
488
void QgsCircularString::segmentize ( const QgsPointV2& p1, const QgsPointV2& p2, const QgsPointV2& p3, QgsPointSequence &points, double tolerance, SegmentationToleranceType toleranceType ) const
489
489
{
490
+ bool clockwise = false ;
491
+ int segSide = segmentSide ( p1, p3, p2 );
492
+ if ( segSide == -1 )
493
+ {
494
+ clockwise = true ;
495
+ }
496
+
497
+ QgsPointV2 circlePoint1 = clockwise ? p3 : p1;
498
+ QgsPointV2 circlePoint2 = p2;
499
+ QgsPointV2 circlePoint3 = clockwise ? p1 : p3 ;
500
+
490
501
// adapted code from postgis
491
502
double radius = 0 ;
492
503
double centerX = 0 ;
493
504
double centerY = 0 ;
494
- QgsGeometryUtils::circleCenterRadius ( p1, p2, p3, radius, centerX, centerY );
495
- int segSide = segmentSide ( p1, p3, p2 );
505
+ QgsGeometryUtils::circleCenterRadius ( circlePoint1, circlePoint2, circlePoint3, radius, centerX, centerY );
496
506
497
- if ( p1 != p3 && ( radius < 0 || qgsDoubleNear ( segSide, 0.0 ) ) ) // points are colinear
507
+
508
+ if ( circlePoint1 != circlePoint3 && ( radius < 0 || qgsDoubleNear ( segSide, 0.0 ) ) ) // points are colinear
498
509
{
499
510
points.append ( p1 );
500
511
points.append ( p2 );
501
512
points.append ( p3 );
502
513
return ;
503
514
}
504
515
505
- bool clockwise = false ;
506
- if ( segSide == -1 )
507
- {
508
- clockwise = true ;
509
- }
510
-
511
516
double increment = tolerance; // one segment per degree
512
517
if ( toleranceType == QgsAbstractGeometry::MaximumDifference )
513
518
{
@@ -516,27 +521,15 @@ void QgsCircularString::segmentize( const QgsPointV2& p1, const QgsPointV2& p2,
516
521
}
517
522
518
523
// angles of pt1, pt2, pt3
519
- double a1 = atan2 ( p1 .y () - centerY, p1 .x () - centerX );
520
- double a2 = atan2 ( p2 .y () - centerY, p2 .x () - centerX );
521
- double a3 = atan2 ( p3 .y () - centerY, p3 .x () - centerX );
524
+ double a1 = atan2 ( circlePoint1 .y () - centerY, circlePoint1 .x () - centerX );
525
+ double a2 = atan2 ( circlePoint2 .y () - centerY, circlePoint2 .x () - centerX );
526
+ double a3 = atan2 ( circlePoint3 .y () - centerY, circlePoint3 .x () - centerX );
522
527
523
- if ( clockwise )
524
- {
525
- increment *= -1 ;
526
- /* Adjust a3 down so we can decrement from a1 to a3 cleanly */
527
- if ( a3 >= a1 )
528
- a3 -= 2.0 * M_PI;
529
- if ( a2 > a1 )
530
- a2 -= 2.0 * M_PI;
531
- }
532
- else
533
- {
534
- /* Adjust a3 up so we can increment from a1 to a3 cleanly */
535
- if ( a3 <= a1 )
536
- a3 += 2.0 * M_PI;
537
- if ( a2 < a1 )
538
- a2 += 2.0 * M_PI;
539
- }
528
+ /* Adjust a3 up so we can increment from a1 to a3 cleanly */
529
+ if ( a3 <= a1 )
530
+ a3 += 2.0 * M_PI;
531
+ if ( a2 < a1 )
532
+ a2 += 2.0 * M_PI;
540
533
541
534
bool hasZ = is3D ();
542
535
bool hasM = isMeasure ();
@@ -545,8 +538,9 @@ void QgsCircularString::segmentize( const QgsPointV2& p1, const QgsPointV2& p2,
545
538
double z = 0 ;
546
539
double m = 0 ;
547
540
548
- points.append ( p1 );
549
- if ( p2 != p3 && p1 != p2 ) // draw straight line segment if two points have the same position
541
+ QList<QgsPointV2> stringPoints;
542
+ stringPoints.insert ( clockwise ? 0 : stringPoints.size (), circlePoint1 );
543
+ if ( circlePoint2 != circlePoint3 && circlePoint1 != circlePoint2 ) // draw straight line segment if two points have the same position
550
544
{
551
545
QgsWkbTypes::Type pointWkbType = QgsWkbTypes::Point ;
552
546
if ( hasZ )
@@ -556,16 +550,16 @@ void QgsCircularString::segmentize( const QgsPointV2& p1, const QgsPointV2& p2,
556
550
557
551
// make sure the curve point p2 is part of the segmentized vertices. But only if p1 != p3
558
552
bool addP2 = true ;
559
- if ( qgsDoubleNear ( p1 .x (), p3 .x () ) && qgsDoubleNear ( p1 .y (), p3 .y () ) )
553
+ if ( qgsDoubleNear ( circlePoint1 .x (), circlePoint3 .x () ) && qgsDoubleNear ( circlePoint1 .y (), circlePoint3 .y () ) )
560
554
{
561
555
addP2 = false ;
562
556
}
563
557
564
- for ( double angle = a1 + increment; clockwise ? angle > a3 : angle < a3; angle += increment )
558
+ for ( double angle = a1 + increment; angle < a3; angle += increment )
565
559
{
566
- if (( addP2 && clockwise && angle < a2 ) || ( addP2 && !clockwise && angle > a2 ) )
560
+ if (( addP2 && angle > a2 ) )
567
561
{
568
- points. append ( p2 );
562
+ stringPoints. insert ( clockwise ? 0 : stringPoints. size (), circlePoint2 );
569
563
addP2 = false ;
570
564
}
571
565
@@ -574,23 +568,24 @@ void QgsCircularString::segmentize( const QgsPointV2& p1, const QgsPointV2& p2,
574
568
575
569
if ( !hasZ && !hasM )
576
570
{
577
- points. append ( QgsPointV2 ( x, y ) );
571
+ stringPoints. insert ( clockwise ? 0 : stringPoints. size (), QgsPointV2 ( x, y ) );
578
572
continue ;
579
573
}
580
574
581
575
if ( hasZ )
582
576
{
583
- z = interpolateArc ( angle, a1, a2, a3, p1 .z (), p2 .z (), p3 .z () );
577
+ z = interpolateArc ( angle, a1, a2, a3, circlePoint1 .z (), circlePoint2 .z (), circlePoint3 .z () );
584
578
}
585
579
if ( hasM )
586
580
{
587
- m = interpolateArc ( angle, a1, a2, a3, p1 .m (), p2 .m (), p3 .m () );
581
+ m = interpolateArc ( angle, a1, a2, a3, circlePoint1 .m (), circlePoint2 .m (), circlePoint3 .m () );
588
582
}
589
583
590
- points. append ( QgsPointV2 ( pointWkbType, x, y, z, m ) );
584
+ stringPoints. insert ( clockwise ? 0 : stringPoints. size (), QgsPointV2 ( pointWkbType, x, y, z, m ) );
591
585
}
592
586
}
593
- points.append ( p3 );
587
+ stringPoints.insert ( clockwise ? 0 : stringPoints.size (), circlePoint3 );
588
+ points.append ( stringPoints );
594
589
}
595
590
596
591
int QgsCircularString::segmentSide ( const QgsPointV2& pt1, const QgsPointV2& pt3, const QgsPointV2& pt2 ) const
0 commit comments