Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Use proper arcs when converting geometries to painter paths
  • Loading branch information
nyalldawson committed Nov 16, 2021
1 parent eb223fd commit 0cfee7f
Show file tree
Hide file tree
Showing 16 changed files with 25 additions and 27 deletions.
38 changes: 14 additions & 24 deletions src/core/geometry/qgscircularstring.cpp
Expand Up @@ -1156,6 +1156,19 @@ void QgsCircularString::transform( const QTransform &t, double zTranslate, doubl
}
}

void arcTo( QPainterPath &path, QPointF pt1, QPointF pt2, QPointF pt3 )
{
double centerX, centerY, radius;
QgsGeometryUtils::circleCenterRadius( QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ),
radius, centerX, centerY );

double p1Angle = QgsGeometryUtils::ccwAngle( pt1.y() - centerY, pt1.x() - centerX );
double sweepAngle = QgsGeometryUtils::sweepAngle( centerX, centerY, pt1.x(), pt1.y(), pt2.x(), pt2.y(), pt3.x(), pt3.y() );

double diameter = 2 * radius;
path.arcTo( centerX - radius, centerY - radius, diameter, diameter, -p1Angle, -sweepAngle );
}

void QgsCircularString::addToPainterPath( QPainterPath &path ) const
{
int nPoints = numPoints();
Expand All @@ -1171,15 +1184,7 @@ void QgsCircularString::addToPainterPath( QPainterPath &path ) const

for ( int i = 0; i < ( nPoints - 2 ) ; i += 2 )
{
QgsPointSequence pt;
QgsGeometryUtils::segmentizeArc( QgsPoint( mX[i], mY[i] ), QgsPoint( mX[i + 1], mY[i + 1] ), QgsPoint( mX[i + 2], mY[i + 2] ), pt );
for ( int j = 1; j < pt.size(); ++j )
{
path.lineTo( pt.at( j ).x(), pt.at( j ).y() );
}
#if 0
//arcTo( path, QPointF( mX[i], mY[i] ), QPointF( mX[i + 1], mY[i + 1] ), QPointF( mX[i + 2], mY[i + 2] ) );
#endif
arcTo( path, QPointF( mX[i], mY[i] ), QPointF( mX[i + 1], mY[i + 1] ), QPointF( mX[i + 2], mY[i + 2] ) );
}

//if number of points is even, connect to last point with straight line (even though the circular string is not valid)
Expand All @@ -1189,21 +1194,6 @@ void QgsCircularString::addToPainterPath( QPainterPath &path ) const
}
}

#if 0
void QgsCircularString::arcTo( QPainterPath &path, QPointF pt1, QPointF pt2, QPointF pt3 )
{
double centerX, centerY, radius;
QgsGeometryUtils::circleCenterRadius( QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ),
radius, centerX, centerY );

double p1Angle = QgsGeometryUtils::ccwAngle( pt1.y() - centerY, pt1.x() - centerX );
double sweepAngle = QgsGeometryUtils::sweepAngle( centerX, centerY, pt1.x(), pt1.y(), pt2.x(), pt2.y(), pt3.x(), pt3.y() );

double diameter = 2 * radius;
path.arcTo( centerX - radius, centerY - radius, diameter, diameter, p1Angle, sweepAngle );
}
#endif

void QgsCircularString::drawAsPolygon( QPainter &p ) const
{
draw( p );
Expand Down
9 changes: 9 additions & 0 deletions src/core/geometry/qgscompoundcurve.cpp
Expand Up @@ -727,8 +727,13 @@ void QgsCompoundCurve::transform( const QTransform &t, double zTranslate, double
void QgsCompoundCurve::addToPainterPath( QPainterPath &path ) const
{
QPainterPath pp;

for ( const QgsCurve *curve : mCurves )
{
if ( curve != mCurves.at( 0 ) && pp.currentPosition() != curve->startPoint().toQPointF() )
{
pp.lineTo( curve->startPoint().toQPointF() );
}
curve->addToPainterPath( pp );
}
path.addPath( pp );
Expand All @@ -739,6 +744,10 @@ void QgsCompoundCurve::drawAsPolygon( QPainter &p ) const
QPainterPath pp;
for ( const QgsCurve *curve : mCurves )
{
if ( curve != mCurves.at( 0 ) && pp.currentPosition() != curve->startPoint().toQPointF() )
{
pp.lineTo( curve->startPoint().toQPointF() );
}
curve->addToPainterPath( pp );
}
p.drawPath( pp );
Expand Down
5 changes: 2 additions & 3 deletions tests/src/python/test_qgsgeometry.py
Expand Up @@ -6734,7 +6734,7 @@ def testGeometryDraw(self):
geom = QgsGeometry.fromWkt(test['wkt'])
self.assertTrue(geom and not geom.isNull(), 'Could not create geometry {}'.format(test['wkt']))
rendered_image = self.renderGeometry(geom, test['use_pen'])
assert self.imageCheck(test['name'], test['reference_image'], rendered_image)
self.assertTrue(self.imageCheck(test['name'], test['reference_image'], rendered_image), test['name'])

if hasattr(geom.constGet(), 'addToPainterPath'):
# also check using painter path
Expand All @@ -6743,11 +6743,10 @@ def testGeometryDraw(self):

if 'as_polygon_reference_image' in test:
rendered_image = self.renderGeometry(geom, False, True)
assert self.imageCheck(test['name'] + '_aspolygon', test['as_polygon_reference_image'], rendered_image)
self.assertTrue(self.imageCheck(test['name'] + '_aspolygon', test['as_polygon_reference_image'], rendered_image), test['name'] + '_aspolygon')

def testGeometryAsQPainterPath(self):
'''Tests conversion of different geometries to QPainterPath, including bad/odd geometries.'''

empty_multipolygon = QgsMultiPolygon()
empty_multipolygon.addGeometry(QgsPolygon())
empty_polygon = QgsPolygon()
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 0cfee7f

Please sign in to comment.