Add method to test whether 3 points are collinear

This commit is contained in:
Nyall Dawson 2023-06-23 13:57:00 +10:00
parent b14d42d147
commit 933db142c5
4 changed files with 36 additions and 0 deletions

View File

@ -797,6 +797,14 @@ Returns a weighted point inside the triangle denoted by the points (``aX``, ``aY
- pointY: y-coordinate of generated point - pointY: y-coordinate of generated point
.. versionadded:: 3.10 .. versionadded:: 3.10
%End
static bool pointsAreCollinear( double x1, double y1, double x2, double y2, double x3, double y3, double epsilon );
%Docstring
Given the points (``x1``, ``y1``), (``x2``, ``y2``) and (``x3``, ``y3``) returns ``True`` if these
points can be considered collinear with a specified tolerance.
.. versionadded:: 3.32
%End %End
static bool setZValueFromPoints( const QgsPointSequence &points, QgsPoint &point ) /Deprecated/; static bool setZValueFromPoints( const QgsPointSequence &points, QgsPoint &point ) /Deprecated/;

View File

@ -1864,6 +1864,11 @@ void QgsGeometryUtils::weightedPointInTriangle( const double aX, const double aY
pointY = rBy + rCy + aY; pointY = rBy + rCy + aY;
} }
bool QgsGeometryUtils::pointsAreCollinear( double x1, double y1, double x2, double y2, double x3, double y3, double epsilon )
{
return qgsDoubleNear( x1 * ( y2 - y3 ) + x2 * ( y3 - y1 ) + x3 * ( y1 - y2 ), 0, epsilon );
};
bool QgsGeometryUtils::transferFirstMValueToPoint( const QgsPointSequence &points, QgsPoint &point ) bool QgsGeometryUtils::transferFirstMValueToPoint( const QgsPointSequence &points, QgsPoint &point )
{ {
bool rc = false; bool rc = false;

View File

@ -819,6 +819,14 @@ class CORE_EXPORT QgsGeometryUtils
static void weightedPointInTriangle( double aX, double aY, double bX, double bY, double cX, double cY, static void weightedPointInTriangle( double aX, double aY, double bX, double bY, double cX, double cY,
double weightB, double weightC, double &pointX SIP_OUT, double &pointY SIP_OUT ) SIP_HOLDGIL; double weightB, double weightC, double &pointX SIP_OUT, double &pointY SIP_OUT ) SIP_HOLDGIL;
/**
* Given the points (\a x1, \a y1), (\a x2, \a y2) and (\a x3, \a y3) returns TRUE if these
* points can be considered collinear with a specified tolerance.
*
* \since QGIS 3.32
*/
static bool pointsAreCollinear( double x1, double y1, double x2, double y2, double x3, double y3, double epsilon );
/** /**
* A Z dimension is added to \a point if one of the point in the list * A Z dimension is added to \a point if one of the point in the list
* \a points is in 3D. Moreover, the Z value of \a point is updated * \a points is in 3D. Moreover, the Z value of \a point is updated

View File

@ -75,6 +75,7 @@ class TestQgsGeometryUtils: public QObject
void testInterpolatePointOnLineByValue(); void testInterpolatePointOnLineByValue();
void testPointOnLineWithDistance(); void testPointOnLineWithDistance();
void testPointFractionAlongLine(); void testPointFractionAlongLine();
void testPointsAreCollinear();
void interpolatePointOnArc(); void interpolatePointOnArc();
void testSegmentizeArcHalfCircle(); void testSegmentizeArcHalfCircle();
void testSegmentizeArcHalfCircleOtherDirection(); void testSegmentizeArcHalfCircleOtherDirection();
@ -1386,6 +1387,20 @@ void TestQgsGeometryUtils::testPointFractionAlongLine()
QGSCOMPARENEAR( QgsGeometryUtils::pointFractionAlongLine( 0, 10, 20, 10, 10, 10 ), 0.5, 0.00001 ); QGSCOMPARENEAR( QgsGeometryUtils::pointFractionAlongLine( 0, 10, 20, 10, 10, 10 ), 0.5, 0.00001 );
} }
void TestQgsGeometryUtils::testPointsAreCollinear()
{
QVERIFY( QgsGeometryUtils::pointsAreCollinear( 0, 10, 10, 10, 20, 10, 0.00001 ) );
QVERIFY( QgsGeometryUtils::pointsAreCollinear( 10, 10, 0, 10, 20, 10, 0.00001 ) );
QVERIFY( QgsGeometryUtils::pointsAreCollinear( 20, 10, 10, 10, 0, 10, 0.00001 ) );
QVERIFY( !QgsGeometryUtils::pointsAreCollinear( 20, 15, 10, 10, 0, 10, 0.00001 ) );
QVERIFY( !QgsGeometryUtils::pointsAreCollinear( 20, 10, 10, 15, 0, 10, 0.00001 ) );
QVERIFY( !QgsGeometryUtils::pointsAreCollinear( 20, 10, 10, 10, 0, 15, 0.00001 ) );
QVERIFY( QgsGeometryUtils::pointsAreCollinear( 10, 0, 10, 10, 10, 20, 0.00001 ) );
QVERIFY( QgsGeometryUtils::pointsAreCollinear( 10, 0, 10, 20, 10, 10, 0.00001 ) );
QVERIFY( QgsGeometryUtils::pointsAreCollinear( 10, 20, 10, 0, 10, 10, 0.00001 ) );
QVERIFY( !QgsGeometryUtils::pointsAreCollinear( 15, 20, 10, 10, 10, 20, 0.00001 ) );
}
void TestQgsGeometryUtils::interpolatePointOnArc() void TestQgsGeometryUtils::interpolatePointOnArc()
{ {
QgsPoint p; QgsPoint p;