@@ -475,51 +475,44 @@ void QgsCircularStringV2::setPoints( const QgsPointSequenceV2 &points )
475
475
476
476
void QgsCircularStringV2::segmentize ( const QgsPointV2& p1, const QgsPointV2& p2, const QgsPointV2& p3, QgsPointSequenceV2 &points ) const
477
477
{
478
+ bool clockwise = false ;
479
+ int segSide = segmentSide ( p1, p3, p2 );
480
+ if ( segSide == -1 )
481
+ {
482
+ clockwise = true ;
483
+ }
484
+
485
+ QgsPointV2 circlePoint1 = clockwise ? p3 : p1;
486
+ QgsPointV2 circlePoint2 = p2;
487
+ QgsPointV2 circlePoint3 = clockwise ? p1 : p3 ;
488
+
478
489
// adapted code from postgis
479
490
double radius = 0 ;
480
491
double centerX = 0 ;
481
492
double centerY = 0 ;
482
- QgsGeometryUtils::circleCenterRadius ( p1, p2, p3, radius, centerX, centerY );
483
- int segSide = segmentSide ( p1, p3, p2 );
493
+ QgsGeometryUtils::circleCenterRadius ( circlePoint1, circlePoint2, circlePoint3, radius, centerX, centerY );
484
494
485
- if ( p1 != p3 && ( radius < 0 || qgsDoubleNear ( segSide, 0.0 ) ) ) // points are colinear
495
+
496
+ if ( circlePoint1 != circlePoint3 && ( radius < 0 || qgsDoubleNear ( segSide, 0.0 ) ) ) // points are colinear
486
497
{
487
498
points.append ( p1 );
488
499
points.append ( p2 );
489
500
points.append ( p3 );
490
501
return ;
491
502
}
492
503
493
- bool clockwise = false ;
494
- if ( segSide == -1 )
495
- {
496
- clockwise = true ;
497
- }
498
-
499
504
double increment = fabs ( M_PI_2 / 90 ); // one segment per degree
500
505
501
506
// angles of pt1, pt2, pt3
502
- double a1 = atan2 ( p1 .y () - centerY, p1 .x () - centerX );
503
- double a2 = atan2 ( p2 .y () - centerY, p2 .x () - centerX );
504
- double a3 = atan2 ( p3 .y () - centerY, p3 .x () - centerX );
507
+ double a1 = atan2 ( circlePoint1 .y () - centerY, circlePoint1 .x () - centerX );
508
+ double a2 = atan2 ( circlePoint2 .y () - centerY, circlePoint2 .x () - centerX );
509
+ double a3 = atan2 ( circlePoint3 .y () - centerY, circlePoint3 .x () - centerX );
505
510
506
- if ( clockwise )
507
- {
508
- increment *= -1 ;
509
- /* Adjust a3 down so we can decrement from a1 to a3 cleanly */
510
- if ( a3 >= a1 )
511
- a3 -= 2.0 * M_PI;
512
- if ( a2 > a1 )
513
- a2 -= 2.0 * M_PI;
514
- }
515
- else
516
- {
517
- /* Adjust a3 up so we can increment from a1 to a3 cleanly */
518
- if ( a3 <= a1 )
519
- a3 += 2.0 * M_PI;
520
- if ( a2 < a1 )
521
- a2 += 2.0 * M_PI;
522
- }
511
+ /* Adjust a3 up so we can increment from a1 to a3 cleanly */
512
+ if ( a3 <= a1 )
513
+ a3 += 2.0 * M_PI;
514
+ if ( a2 < a1 )
515
+ a2 += 2.0 * M_PI;
523
516
524
517
bool hasZ = is3D ();
525
518
bool hasM = isMeasure ();
@@ -528,39 +521,54 @@ void QgsCircularStringV2::segmentize( const QgsPointV2& p1, const QgsPointV2& p2
528
521
double z = 0 ;
529
522
double m = 0 ;
530
523
531
- points.append ( p1 );
532
- if ( p2 != p3 && p1 != p2 ) // draw straight line segment if two points have the same position
524
+ QList<QgsPointV2> stringPoints;
525
+ stringPoints.insert ( clockwise ? 0 : stringPoints.size (), circlePoint1 );
526
+ if ( circlePoint2 != circlePoint3 && circlePoint1 != circlePoint2 ) // draw straight line segment if two points have the same position
533
527
{
534
528
QgsWKBTypes::Type pointWkbType = QgsWKBTypes::Point ;
535
529
if ( hasZ )
536
530
pointWkbType = QgsWKBTypes::addZ ( pointWkbType );
537
531
if ( hasM )
538
532
pointWkbType = QgsWKBTypes::addM ( pointWkbType );
539
533
540
- for ( double angle = a1 + increment; clockwise ? angle > a3 : angle < a3; angle += increment )
534
+ // make sure the curve point p2 is part of the segmentized vertices. But only if p1 != p3
535
+ bool addP2 = true ;
536
+ if ( qgsDoubleNear ( circlePoint1.x (), circlePoint3.x () ) && qgsDoubleNear ( circlePoint1.y (), circlePoint3.y () ) )
541
537
{
538
+ addP2 = false ;
539
+ }
540
+
541
+ for ( double angle = a1 + increment; angle < a3; angle += increment )
542
+ {
543
+ if (( addP2 && angle > a2 ) )
544
+ {
545
+ stringPoints.insert ( clockwise ? 0 : stringPoints.size (), circlePoint2 );
546
+ addP2 = false ;
547
+ }
548
+
542
549
x = centerX + radius * cos ( angle );
543
550
y = centerY + radius * sin ( angle );
544
551
545
552
if ( !hasZ && !hasM )
546
553
{
547
- points. append ( QgsPointV2 ( x, y ) );
554
+ stringPoints. insert ( clockwise ? 0 : stringPoints. size (), QgsPointV2 ( x, y ) );
548
555
continue ;
549
556
}
550
557
551
558
if ( hasZ )
552
559
{
553
- z = interpolateArc ( angle, a1, a2, a3, p1 .z (), p2 .z (), p3 .z () );
560
+ z = interpolateArc ( angle, a1, a2, a3, circlePoint1 .z (), circlePoint2 .z (), circlePoint3 .z () );
554
561
}
555
562
if ( hasM )
556
563
{
557
- m = interpolateArc ( angle, a1, a2, a3, p1 .m (), p2 .m (), p3 .m () );
564
+ m = interpolateArc ( angle, a1, a2, a3, circlePoint1 .m (), circlePoint2 .m (), circlePoint3 .m () );
558
565
}
559
566
560
- points. append ( QgsPointV2 ( pointWkbType, x, y, z, m ) );
567
+ stringPoints. insert ( clockwise ? 0 : stringPoints. size (), QgsPointV2 ( pointWkbType, x, y, z, m ) );
561
568
}
562
569
}
563
- points.append ( p3 );
570
+ stringPoints.insert ( clockwise ? 0 : stringPoints.size (), circlePoint3 );
571
+ points.append ( stringPoints );
564
572
}
565
573
566
574
int QgsCircularStringV2::segmentSide ( const QgsPointV2& pt1, const QgsPointV2& pt3, const QgsPointV2& pt2 ) const
0 commit comments