diff --git a/src/libs/vgeometry/vgobject.cpp b/src/libs/vgeometry/vgobject.cpp index 6ee835c4a..3ac67e251 100644 --- a/src/libs/vgeometry/vgobject.cpp +++ b/src/libs/vgeometry/vgobject.cpp @@ -40,7 +40,7 @@ #include "../ifc/ifcdef.h" #include "vgobject_p.h" -double VGObject::accuracyPointOnLine = (0.026/*mm*/ / 25.4) * PrintDPI; +const double VGObject::accuracyPointOnLine = (0.026/*mm*/ / 25.4) * PrintDPI; //--------------------------------------------------------------------------------------------------------------------- /** @@ -476,10 +476,13 @@ bool VGObject::IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const Q * @brief IsPointOnLineviaPDP use the perp dot product (PDP) way. * * The pdp is zero only if the t lies on the line e1 = vector from p1 to p2. + * @return true if point is on line */ bool VGObject::IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2) { - return ( qAbs(PerpDotProduct(p1, p2, t)) < GetEpsilon(p1, p2) ); + const auto p = qAbs(PerpDotProduct(p1, p2, t)); + const auto e = GetEpsilon(p1, p2); + return p <= e; } //--------------------------------------------------------------------------------------------------------------------- @@ -488,9 +491,18 @@ bool VGObject::IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QP * This is actually the same as the area of the triangle defined by the three points, multiplied by 2. * @return 2 * triangleArea(a,b,c) */ -double VGObject::PerpDotProduct(const QPointF &p1, const QPointF &p2, const QPointF &t) +long double VGObject::PerpDotProduct(const QPointF &p1, const QPointF &p2, const QPointF &t) { - return (p1.x() - t.x()) * (p2.y() - t.y()) - (p1.y() - t.y()) * (p2.x() - t.x()); + const auto p1x = static_cast(p1.x()); + const auto p1y = static_cast(p1.y()); + + const auto p2x = static_cast(p2.x()); + const auto p2y = static_cast(p2.y()); + + const auto tx = static_cast(t.x()); + const auto ty = static_cast(t.y()); + + return (p1x - tx) * (p2y - ty) - (p1y - ty) * (p2x - tx); } //--------------------------------------------------------------------------------------------------------------------- @@ -503,7 +515,7 @@ double VGObject::PerpDotProduct(const QPointF &p1, const QPointF &p2, const QPoi * line e1=(p1, p2), e.g. the minimal area calucalted with PerpDotProduc() if point still not on the line. This distance * is controled by variable accuracyPointOnLine */ -double VGObject::GetEpsilon(const QPointF &p1, const QPointF &p2) +long double VGObject::GetEpsilon(const QPointF &p1, const QPointF &p2) { QLineF line(p1, p2); line.setAngle(line.angle() + 90); diff --git a/src/libs/vgeometry/vgobject.h b/src/libs/vgeometry/vgobject.h index 328316fe9..56ef87f94 100644 --- a/src/libs/vgeometry/vgobject.h +++ b/src/libs/vgeometry/vgobject.h @@ -93,14 +93,14 @@ public: static QVector GetReversePoints(const QVector &points); static int GetLengthContour(const QVector &contour, const QVector &newPoints); - static double accuracyPointOnLine; + static const double accuracyPointOnLine; protected: static QTransform FlippingMatrix(const QLineF &axis); private: QSharedDataPointer d; - static double PerpDotProduct(const QPointF &p1, const QPointF &p2, const QPointF &t); - static double GetEpsilon(const QPointF &p1, const QPointF &p2); + static long double PerpDotProduct(const QPointF &p1, const QPointF &p2, const QPointF &t); + static long double GetEpsilon(const QPointF &p1, const QPointF &p2); static int PointInCircle (const QPointF &p, const QPointF ¢er, qreal radius); }; diff --git a/src/test/ValentinaTest/tst_vgobject.cpp b/src/test/ValentinaTest/tst_vgobject.cpp index 4cdadad0d..7a24a4f1e 100644 --- a/src/test/ValentinaTest/tst_vgobject.cpp +++ b/src/test/ValentinaTest/tst_vgobject.cpp @@ -68,17 +68,35 @@ void TST_VGObject::TestIsPointOnLineviaPDP_data() } { + const qreal gap = VGObject::accuracyPointOnLine; const QPointF p1(483.54330708661416, 3819.527433070866); const QPointF p2(483.54330708661416, 1929.763653543307); - const QPointF t(483.54330708661416 + VGObject::accuracyPointOnLine, 2874.763653543307); - QTest::newRow("Min accuracy gap. On middle.") << p1 << p2 << t << false; + const QPointF t(483.54330708661416 + gap, 2874.763653543307); + QTest::newRow("Min accuracy gap. On middle.") << p1 << p2 << t << true; } { + const qreal gap = VGObject::accuracyPointOnLine; const QPointF p1(483.54330708661416, 3819.527433070866); const QPointF p2(483.54330708661416, 1929.763653543307); - const QPointF t(483.54330708661416 + VGObject::accuracyPointOnLine, 1929.763653543307); - QTest::newRow("Min accuracy gap.") << p1 << p2 << t << false; + const QPointF t(483.54330708661416 + gap, 1929.763653543307); + QTest::newRow("Min accuracy gap. The end of segment.") << p1 << p2 << t << true; + } + + { + const qreal gap = VGObject::accuracyPointOnLine + VGObject::accuracyPointOnLine*0.01; + const QPointF p1(483.54330708661416, 3819.527433070866); + const QPointF p2(483.54330708661416, 1929.763653543307); + const QPointF t(483.54330708661416 + gap, 2874.763653543307); + QTest::newRow("Min accuracy gap + 1%. On middle.") << p1 << p2 << t << false; + } + + { + const qreal gap = VGObject::accuracyPointOnLine + VGObject::accuracyPointOnLine*0.01; + const QPointF p1(483.54330708661416, 3819.527433070866); + const QPointF p2(483.54330708661416, 1929.763653543307); + const QPointF t(483.54330708661416 + gap, 1929.763653543307); + QTest::newRow("Min accuracy gap + 1%. The end of segment.") << p1 << p2 << t << false; } { @@ -92,7 +110,7 @@ void TST_VGObject::TestIsPointOnLineviaPDP_data() const QPointF p1(483.54330708661416, 3819.527433070866); const QPointF p2(483.54330708661416, 1929.763653543307); const QPointF t(483.54330708661416 + VGObject::accuracyPointOnLine/2., 1929.763653543307); - QTest::newRow("Less than min accuracy gap.") << p1 << p2 << t << true; + QTest::newRow("Less than min accuracy gap. The end of segment.") << p1 << p2 << t << true; } { @@ -106,7 +124,7 @@ void TST_VGObject::TestIsPointOnLineviaPDP_data() const QPointF p1(483.54330708661416, 3819.527433070866); const QPointF p2(483.54330708661416, 1929.763653543307); const QPointF t(370.1574803149606, 1929.763653543307); - QTest::newRow("Issue 534 - 3 cm gap.") << p1 << p2 << t << false; + QTest::newRow("Issue 534 - 3 cm gap. The end of segment.") << p1 << p2 << t << false; } { @@ -120,7 +138,7 @@ void TST_VGObject::TestIsPointOnLineviaPDP_data() const QPointF p1(483.54330708661416, 3819.527433070866); const QPointF p2(483.54330708661416, 1929.763653543307); const QPointF t(407.9527559055118, 1929.763653543307); - QTest::newRow("Issue 534 - 2 cm gap.") << p1 << p2 << t << false; + QTest::newRow("Issue 534 - 2 cm gap. The end of segment.") << p1 << p2 << t << false; } }