Skip to content
{{ message }}

# qgis / QGIS

Add geometry util to calculate a point along a segment offset in a pe…

`…rpendicular direction by a set offset amount`
• Loading branch information
nyalldawson committed Mar 19, 2021
1 parent 8b94ec5 commit ba6d96725b4e60db6596322a71c5a3c6aa597b31
 @@ -269,6 +269,37 @@ Returns a point a specified ``distance`` toward a second point. %End static void perpendicularOffsetPointAlongSegment( double x1, double y1, double x2, double y2, double proportion, double offset, double *x /Out/, double *y /Out/ ); %Docstring Calculates a point a certain ``proportion`` of the way along the segment from (``x1``, ``y1``) to (``x2``, ``y2``), offset from the segment by the specified ``offset`` amount. :param x1: x-coordinate of start of segment :param y1: y-coordinate of start of segment :param x2: x-coordinate of end of segment :param y2: y-coordinate of end of segment :param proportion: proportion of the segment's length at which to place the point (between 0.0 and 1.0) :param offset: perpendicular offset from segment to apply to point. A negative ``offset`` shifts the point to the left of the segment, while a positive ``offset`` will shift it to the right of the segment. Example ------- .. code-block:: python # Offset point at center of segment by 2 units to the right x, y = QgsGeometryUtils.perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.5, 2 ) # (6.0, 3.0) # Offset point at center of segment by 2 units to the left x, y = QgsGeometryUtils.perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.5, -2 ) # (6.0, 7.0) :return: - x: calculated point x-coordinate - y: calculated point y-coordinate .. versionadded:: 3.20 %End static QgsPoint interpolatePointOnArc( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double distance ) /HoldGIL/; %Docstring Interpolates a point on an arc defined by three points, ``pt1``, ``pt2`` and ``pt3``. The arc will be
 @@ -631,6 +631,23 @@ void QgsGeometryUtils::pointOnLineWithDistance( double x1, double y1, double x2, } } void QgsGeometryUtils::perpendicularOffsetPointAlongSegment( double x1, double y1, double x2, double y2, double proportion, double offset, double *x, double *y ) { // calculate point along segment const double mX = x1 + ( x2 - x1 ) * proportion; const double mY = y1 + ( y2 - y1 ) * proportion; const double pX = x1 - x2; const double pY = y1 - y2; double normalX = -pY; double normalY = pX; const double normalLength = sqrt( ( normalX * normalX ) + ( normalY * normalY ) ); normalX /= normalLength; normalY /= normalLength; *x = mX + offset * normalX; *y = mY + offset * normalY; } QgsPoint QgsGeometryUtils::interpolatePointOnArc( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double distance ) { double centerX, centerY, radius;
 @@ -301,6 +301,35 @@ class CORE_EXPORT QgsGeometryUtils double *z1 = nullptr, double *z2 = nullptr, double *z = nullptr, double *m1 = nullptr, double *m2 = nullptr, double *m = nullptr ) SIP_SKIP; /** * Calculates a point a certain \a proportion of the way along the segment from (\a x1, \a y1) to (\a x2, \a y2), * offset from the segment by the specified \a offset amount. * * \param x1 x-coordinate of start of segment * \param y1 y-coordinate of start of segment * \param x2 x-coordinate of end of segment * \param y2 y-coordinate of end of segment * \param proportion proportion of the segment's length at which to place the point (between 0.0 and 1.0) * \param offset perpendicular offset from segment to apply to point. A negative \a offset shifts the point to the left of the segment, while a positive \a offset will shift it to the right of the segment. * \param x calculated point x-coordinate * \param y calculated point y-coordinate * * ### Example * * \code{.py} * # Offset point at center of segment by 2 units to the right * x, y = QgsGeometryUtils.perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.5, 2 ) * # (6.0, 3.0) * * # Offset point at center of segment by 2 units to the left * x, y = QgsGeometryUtils.perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.5, -2 ) * # (6.0, 7.0) * \endcode * * \since QGIS 3.20 */ static void perpendicularOffsetPointAlongSegment( double x1, double y1, double x2, double y2, double proportion, double offset, double *x SIP_OUT, double *y SIP_OUT ); /** * Interpolates a point on an arc defined by three points, \a pt1, \a pt2 and \a pt3. The arc will be * interpolated by the specified \a distance from \a pt1.
 @@ -83,6 +83,7 @@ class TestQgsGeometryUtils: public QObject void testPointContinuesArc(); void testBisector(); void testAngleBisector(); void testPerpendicularOffsetPoint(); }; @@ -1537,5 +1538,34 @@ void TestQgsGeometryUtils::testAngleBisector() QVERIFY( !QgsGeometryUtils::angleBisector( 0, 0, 5, 0, 6, 0, 10, 0, x, y, angle ) ); } void TestQgsGeometryUtils::testPerpendicularOffsetPoint() { double x, y; QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.5, 2, &x, &y ); QGSCOMPARENEAR( x, 6.0, 10e-3 ); QGSCOMPARENEAR( y, 3.0, 10e-3 ); QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.5, -2, &x, &y ); QGSCOMPARENEAR( x, 6.0, 10e-3 ); QGSCOMPARENEAR( y, 7.0, 10e-3 ); QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.1, 2, &x, &y ); QGSCOMPARENEAR( x, 2.0, 10e-3 ); QGSCOMPARENEAR( y, 3.0, 10e-3 ); QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.9, 2, &x, &y ); QGSCOMPARENEAR( x, 10.0, 10e-3 ); QGSCOMPARENEAR( y, 3.0, 10e-3 ); QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.0, 2, &x, &y ); QGSCOMPARENEAR( x, 1.0, 10e-3 ); QGSCOMPARENEAR( y, 3.0, 10e-3 ); QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 1.0, 2, &x, &y ); QGSCOMPARENEAR( x, 11.0, 10e-3 ); QGSCOMPARENEAR( y, 3.0, 10e-3 ); QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 5, 1, 5, 11, 0.5, 2, &x, &y ); QGSCOMPARENEAR( x, 7.0, 10e-3 ); QGSCOMPARENEAR( y, 6.0, 10e-3 ); QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 5, 1, 5, 11, 0.5, -2, &x, &y ); QGSCOMPARENEAR( x, 3.0, 10e-3 ); QGSCOMPARENEAR( y, 6.0, 10e-3 ); } QGSTEST_MAIN( TestQgsGeometryUtils ) #include "testqgsgeometryutils.moc"

#### 0 comments on commit `ba6d967`

Please sign in to comment.