From 67a6b67afc5e1791d33ef8a8ee1c7545c7792d0c Mon Sep 17 00:00:00 2001
From: Roman Telezhynskyi <kroluku@gmail.com>
Date: Thu, 8 Dec 2016 13:56:17 +0200
Subject: [PATCH] Fix broken test on Windows.

--HG--
branch : develop
---
 src/libs/vgeometry/vgobject.cpp         | 22 +++++++++++++----
 src/libs/vgeometry/vgobject.h           |  6 ++---
 src/test/ValentinaTest/tst_vgobject.cpp | 32 +++++++++++++++++++------
 3 files changed, 45 insertions(+), 15 deletions(-)

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<long double>(p1.x());
+    const auto p1y = static_cast<long double>(p1.y());
+
+    const auto p2x = static_cast<long double>(p2.x());
+    const auto p2y = static_cast<long double>(p2.y());
+
+    const auto tx = static_cast<long double>(t.x());
+    const auto ty = static_cast<long double>(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<QPointF> GetReversePoints(const QVector<QPointF> &points);
     static int GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints);
 
-    static double accuracyPointOnLine;
+    static const double accuracyPointOnLine;
 protected:
     static QTransform FlippingMatrix(const QLineF &axis);
 private:
     QSharedDataPointer<VGObjectData> 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 &center, 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;
     }
 }