diff --git a/python/core/geometry/qgslinesegment.sip.in b/python/core/geometry/qgslinesegment.sip.in index 48f3f9f79e8..3ae1fa5e5c1 100644 --- a/python/core/geometry/qgslinesegment.sip.in +++ b/python/core/geometry/qgslinesegment.sip.in @@ -162,6 +162,19 @@ Sets the segment's ``end`` point. .. seealso:: :py:func:`setEndY` .. seealso:: :py:func:`setStart` +%End + + int pointLeftOfLine( const QgsPointXY &point ) const; +%Docstring +Tests if a ``point`` is to the left of the line segment. + +Returns -1 if the point falls to the left of the line, or +1 if the point +is to the right. + +If the return value is 0, then the test was unsuccessful (e.g. due to testing a point exactly +on the line, or exactly in line with the segment) and the result is undefined. + +.. seealso:: :py:func:`QgsGeometryUtils.leftOfLine` %End bool operator==( const QgsLineSegment2D &other ) const; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 75f232983b6..a0e360918d3 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -463,6 +463,7 @@ SET(QGIS_CORE_SRCS geometry/qgsgeometryutils.cpp geometry/qgsgeos.cpp geometry/qgsinternalgeometryengine.cpp + geometry/qgslinesegment.cpp geometry/qgslinestring.cpp geometry/qgsmulticurve.cpp geometry/qgsmultilinestring.cpp diff --git a/src/core/geometry/qgslinesegment.cpp b/src/core/geometry/qgslinesegment.cpp new file mode 100644 index 00000000000..93e91f36fb1 --- /dev/null +++ b/src/core/geometry/qgslinesegment.cpp @@ -0,0 +1,16 @@ +/*************************************************************************** + qgslinesegment.cpp + ----------------- + begin : April 2018 + copyright : (C) 2018 by Nyall Dawson + email : nyall dot dawson at gmail dot com + ***************************************************************************/ + +#include "qgslinesegment.h" +#include "qgsgeometryutils.h" + +int QgsLineSegment2D::pointLeftOfLine( const QgsPointXY &point ) const +{ + return QgsGeometryUtils::leftOfLine( point.x(), point.y(), mStart.x(), mStart.y(), mEnd.x(), mEnd.y() ); +} + diff --git a/src/core/geometry/qgslinesegment.h b/src/core/geometry/qgslinesegment.h index 862bb2e4d19..ad9a2f579b5 100644 --- a/src/core/geometry/qgslinesegment.h +++ b/src/core/geometry/qgslinesegment.h @@ -176,6 +176,19 @@ class CORE_EXPORT QgsLineSegment2D mEnd = end; } + /** + * Tests if a \a point is to the left of the line segment. + * + * Returns -1 if the point falls to the left of the line, or +1 if the point + * is to the right. + * + * If the return value is 0, then the test was unsuccessful (e.g. due to testing a point exactly + * on the line, or exactly in line with the segment) and the result is undefined. + * + * \see QgsGeometryUtils::leftOfLine() + */ + int pointLeftOfLine( const QgsPointXY &point ) const; + //! Equality operator bool operator==( const QgsLineSegment2D &other ) const { diff --git a/tests/src/python/test_qgslinesegment.py b/tests/src/python/test_qgslinesegment.py index a653ec403c4..017d6e58695 100644 --- a/tests/src/python/test_qgslinesegment.py +++ b/tests/src/python/test_qgslinesegment.py @@ -102,6 +102,16 @@ class TestQgsLineSegment2D(unittest.TestCase): self.assertAlmostEqual(segment.length(), 3.60555127546, 5) self.assertEqual(segment.lengthSquared(), 13) + def testPointLeftOfLine(self): + segment = QgsLineSegment2D(QgsPointXY(1, 2), QgsPointXY(3, 5)) + self.assertEqual(segment.pointLeftOfLine(QgsPointXY(1.5, 6)), -1) + self.assertEqual(segment.pointLeftOfLine(QgsPointXY(1.5, -6)), 1) + self.assertEqual(segment.pointLeftOfLine(QgsPointXY(5, 8)), 0) + segment = QgsLineSegment2D(QgsPointXY(3, 5), QgsPointXY(1, 2)) + self.assertEqual(segment.pointLeftOfLine(QgsPointXY(1.5, 6)), 1) + self.assertEqual(segment.pointLeftOfLine(QgsPointXY(1.5, -6)), -1) + self.assertEqual(segment.pointLeftOfLine(QgsPointXY(5, 8)), 0) + if __name__ == '__main__': unittest.main()