Skip to content

Commit 9a6d966

Browse files
committedApr 23, 2018
Allow using the longer arc with two point and center methods
1 parent 732d6bb commit 9a6d966

File tree

8 files changed

+41
-9
lines changed

8 files changed

+41
-9
lines changed
 

‎python/core/geometry/qgscircularstring.sip.in

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,16 @@ arc passing through ``p1``, ``p2`` and ``p3``.
4141

4242
static QgsCircularString fromTwoPointsAndCenter( const QgsPoint &p1,
4343
const QgsPoint &p2,
44-
const QgsPoint &center );
44+
const QgsPoint &center,
45+
bool useShortestArc = true );
4546
%Docstring
4647
Creates a circular string with a single arc representing
4748
the curve from ``p1`` to ``p2`` with the specified ``center``.
4849

50+
If ``useShortestArc`` is true, then the arc returned will be that corresponding
51+
to the shorter arc from ``p1`` to ``p2``. If it is false, the longer arc from ``p1``
52+
to ``p2`` will be used (i.e. winding the other way around the circle).
53+
4954
.. versionadded:: 3.2
5055
%End
5156

‎python/core/geometry/qgsgeometryutils.sip.in

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,15 @@ first 3D point amongst ``p1`` and ``p2``.
277277
.. seealso:: :py:func:`segmentMidPointFromCenter`
278278
%End
279279

280-
static QgsPoint segmentMidPointFromCenter( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &center );
280+
static QgsPoint segmentMidPointFromCenter( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &center, bool useShortestArc = true );
281281
%Docstring
282282
Calculates the midpoint on the circle passing through ``p1`` and ``p2``,
283283
with the specified ``center`` coordinate.
284284

285+
If ``useShortestArc`` is true, then the midpoint returned will be that corresponding
286+
to the shorter arc from ``p1`` to ``p2``. If it is false, the longer arc from ``p1``
287+
to ``p2`` will be used (i.e. winding the other way around the circle).
288+
285289
.. versionadded:: 3.2
286290

287291
.. seealso:: :py:func:`segmentMidPoint`

‎src/core/geometry/qgscircularstring.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ QgsCircularString::QgsCircularString( const QgsPoint &p1, const QgsPoint &p2, co
6666
}
6767
}
6868

69-
QgsCircularString QgsCircularString::fromTwoPointsAndCenter( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &center )
69+
QgsCircularString QgsCircularString::fromTwoPointsAndCenter( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &center, const bool useShortestArc )
7070
{
71-
const QgsPoint midPoint = QgsGeometryUtils::segmentMidPointFromCenter( p1, p2, center );
71+
const QgsPoint midPoint = QgsGeometryUtils::segmentMidPointFromCenter( p1, p2, center, useShortestArc );
7272
return QgsCircularString( p1, midPoint, p2 );
7373
}
7474

‎src/core/geometry/qgscircularstring.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,16 @@ class CORE_EXPORT QgsCircularString: public QgsCurve
5454
* Creates a circular string with a single arc representing
5555
* the curve from \a p1 to \a p2 with the specified \a center.
5656
*
57+
* If \a useShortestArc is true, then the arc returned will be that corresponding
58+
* to the shorter arc from \a p1 to \a p2. If it is false, the longer arc from \a p1
59+
* to \a p2 will be used (i.e. winding the other way around the circle).
60+
*
5761
* \since QGIS 3.2
5862
*/
5963
static QgsCircularString fromTwoPointsAndCenter( const QgsPoint &p1,
6064
const QgsPoint &p2,
61-
const QgsPoint &center );
65+
const QgsPoint &center,
66+
bool useShortestArc = true );
6267

6368
bool equals( const QgsCurve &other ) const override;
6469

‎src/core/geometry/qgsgeometryutils.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -740,10 +740,12 @@ bool QgsGeometryUtils::segmentMidPoint( const QgsPoint &p1, const QgsPoint &p2,
740740
return true;
741741
}
742742

743-
QgsPoint QgsGeometryUtils::segmentMidPointFromCenter( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &center )
743+
QgsPoint QgsGeometryUtils::segmentMidPointFromCenter( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &center, const bool useShortestArc )
744744
{
745-
const double midPointAngle = averageAngle( lineAngle( center.x(), center.y(), p1.x(), p1.y() ),
746-
lineAngle( center.x(), center.y(), p2.x(), p2.y() ) );
745+
double midPointAngle = averageAngle( lineAngle( center.x(), center.y(), p1.x(), p1.y() ),
746+
lineAngle( center.x(), center.y(), p2.x(), p2.y() ) );
747+
if ( !useShortestArc )
748+
midPointAngle += M_PI;
747749
return center.project( center.distance( p1 ), midPointAngle * 180 / M_PI );
748750
}
749751

‎src/core/geometry/qgsgeometryutils.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,10 +288,14 @@ class CORE_EXPORT QgsGeometryUtils
288288
* Calculates the midpoint on the circle passing through \a p1 and \a p2,
289289
* with the specified \a center coordinate.
290290
*
291+
* If \a useShortestArc is true, then the midpoint returned will be that corresponding
292+
* to the shorter arc from \a p1 to \a p2. If it is false, the longer arc from \a p1
293+
* to \a p2 will be used (i.e. winding the other way around the circle).
294+
*
291295
* \since QGIS 3.2
292296
* \see segmentMidPoint()
293297
*/
294-
static QgsPoint segmentMidPointFromCenter( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &center );
298+
static QgsPoint segmentMidPointFromCenter( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &center, bool useShortestArc = true );
295299

296300
//! Calculates the direction angle of a circle tangent (clockwise from north in radians)
297301
static double circleTangentDirection( const QgsPoint &tangentPoint, const QgsPoint &cp1, const QgsPoint &cp2, const QgsPoint &cp3 );

‎tests/src/core/testqgsgeometry.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,15 @@ void TestQgsGeometry::circularString()
12211221
QCOMPARE( from3Pts.yAt( 1 ), 22.0 );
12221222
QCOMPARE( from3Pts.xAt( 2 ), 31.0 );
12231223
QCOMPARE( from3Pts.yAt( 2 ), 2.0 );
1224+
from3Pts = QgsCircularString::fromTwoPointsAndCenter( QgsPoint( 1, 2 ), QgsPoint( 31, 2 ), QgsPoint( 21, 2 ), false );
1225+
QCOMPARE( from3Pts.wkbType(), QgsWkbTypes::CircularString );
1226+
QCOMPARE( from3Pts.numPoints(), 3 );
1227+
QCOMPARE( from3Pts.xAt( 0 ), 1.0 );
1228+
QCOMPARE( from3Pts.yAt( 0 ), 2.0 );
1229+
QCOMPARE( from3Pts.xAt( 1 ), 21.0 );
1230+
QCOMPARE( from3Pts.yAt( 1 ), -18.0 );
1231+
QCOMPARE( from3Pts.xAt( 2 ), 31.0 );
1232+
QCOMPARE( from3Pts.yAt( 2 ), 2.0 );
12241233
from3Pts = QgsCircularString::fromTwoPointsAndCenter( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ), QgsPoint( QgsWkbTypes::PointZ, 32, 2, 33 ),
12251234
QgsPoint( QgsWkbTypes::PointZ, 21, 2, 23 ) );
12261235
QCOMPARE( from3Pts.wkbType(), QgsWkbTypes::CircularStringZ );

‎tests/src/core/testqgsgeometryutils.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,9 @@ void TestQgsGeometryUtils::testSegmentMidPointCenter()
220220
QgsPoint mid = QgsGeometryUtils::segmentMidPointFromCenter( QgsPoint( 10, 21 ), QgsPoint( 11, 20 ), QgsPoint( 10, 20 ) );
221221
QGSCOMPARENEAR( mid.x(), 10.7071, 0.0001 );
222222
QGSCOMPARENEAR( mid.y(), 20.7071, 0.0001 );
223+
QgsGeometryUtils::segmentMidPointFromCenter( QgsPoint( 10, 21 ), QgsPoint( 11, 20 ), QgsPoint( 10, 20 ), false );
224+
QGSCOMPARENEAR( mid.x(), 10.7071, 0.0001 );
225+
QGSCOMPARENEAR( mid.y(), 20.7071, 0.0001 );
223226
mid = QgsGeometryUtils::segmentMidPointFromCenter( QgsPoint( 10, 21 ), QgsPoint( 9, 20 ), QgsPoint( 10, 20 ) );
224227
QGSCOMPARENEAR( mid.x(), 9.292893, 0.0001 );
225228
QGSCOMPARENEAR( mid.y(), 20.7071, 0.0001 );

0 commit comments

Comments
 (0)
Please sign in to comment.