From ae43c66bd9385faaf5c5e0c1d60e64ff75134413 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 3 Dec 2015 21:56:40 +0200 Subject: [PATCH] Fixed issue #412. Error in Detail using 'Segment a Simple Curve' tool. --HG-- branch : develop --- src/libs/vgeometry/vabstractcurve.cpp | 2 +- src/libs/vgeometry/vgobject.cpp | 6 +-- src/libs/vgeometry/vgobject.h | 7 ++-- .../toolsinglepoint/vtoolpointofcontact.cpp | 6 ++- src/test/ValentinaTest/tst_vspline.cpp | 40 +++++++++++++++++++ src/test/ValentinaTest/tst_vspline.h | 1 + 6 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/libs/vgeometry/vabstractcurve.cpp b/src/libs/vgeometry/vabstractcurve.cpp index 8a4cd9468..962a7f6b6 100644 --- a/src/libs/vgeometry/vabstractcurve.cpp +++ b/src/libs/vgeometry/vabstractcurve.cpp @@ -76,7 +76,7 @@ QVector VAbstractCurve::FromBegin(const QVector &points, const { if (theBegin == false) { - if (IsPointOnLineSegment(begin, points.at(i), points.at(i+1))) + if (IsPointOnLineSegment(begin.toPoint(), points.at(i).toPoint(), points.at(i+1).toPoint())) { theBegin = true; segment.append(begin); diff --git a/src/libs/vgeometry/vgobject.cpp b/src/libs/vgeometry/vgobject.cpp index 9d035d96d..7f75206d5 100644 --- a/src/libs/vgeometry/vgobject.cpp +++ b/src/libs/vgeometry/vgobject.cpp @@ -418,7 +418,7 @@ void VGObject::LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c * * Original idea http://www.sunshine2k.de/coding/java/PointOnLine/PointOnLine.html */ -bool VGObject::IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const QPointF &p2) +bool VGObject::IsPointOnLineSegment(const QPoint &t, const QPoint &p1, const QPoint &p2) { // The test point must lie inside the bounding box spanned by the two line points. if (not ( (p1.x() <= t.x() && t.x() <= p2.x()) || (p2.x() <= t.x() && t.x() <= p1.x()) )) @@ -443,7 +443,7 @@ bool VGObject::IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const Q * * The pdp is zero only if the t lies on the line e1 = vector from p1 to p2. */ -bool VGObject::IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2) +bool VGObject::IsPointOnLineviaPDP(const QPoint &t, const QPoint &p1, const QPoint &p2) { return ( qAbs(PerpDotProduct(p1, p2, t) < GetEpsilon(p1, p2)) ); } @@ -454,7 +454,7 @@ 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 &t, const QPointF &p1, const QPointF &p2) +double VGObject::PerpDotProduct(const QPoint &t, const QPoint &p1, const QPoint &p2) { return (p1.x() - t.x()) * (p2.y() - t.y()) - (p1.y() - t.y()) * (p2.x() - t.x()); } diff --git a/src/libs/vgeometry/vgobject.h b/src/libs/vgeometry/vgobject.h index 527f14094..41e608e8d 100644 --- a/src/libs/vgeometry/vgobject.h +++ b/src/libs/vgeometry/vgobject.h @@ -37,6 +37,7 @@ class VGObjectData; class QLineF; +class QPoint; class QPointF; class QRectF; @@ -81,15 +82,15 @@ public: static QPointF ClosestPoint(const QLineF &line, const QPointF &point); static QPointF addVector (const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k); static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c); - static bool IsPointOnLineSegment (const QPointF &t, const QPointF &p1, const QPointF &p2); + static bool IsPointOnLineSegment (const QPoint &t, const QPoint &p1, const QPoint &p2); static QVector GetReversePoints(const QVector &points); static int GetLengthContour(const QVector &contour, const QVector &newPoints); private: QSharedDataPointer d; - static bool IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2); - static double PerpDotProduct(const QPointF &t, const QPointF &p1, const QPointF &p2); + static bool IsPointOnLineviaPDP(const QPoint &t, const QPoint &p1, const QPoint &p2); + static double PerpDotProduct(const QPoint &t, const QPoint &p1, const QPoint &p2); static double GetEpsilon(const QPointF &p1, const QPointF &p2); static int PointInCircle (const QPointF &p, const QPointF ¢er, qreal radius); diff --git a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofcontact.cpp b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofcontact.cpp index c4153c436..cd441496f 100644 --- a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofcontact.cpp +++ b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofcontact.cpp @@ -101,8 +101,10 @@ QPointF VToolPointOfContact::FindPoint(const qreal &radius, const QPointF ¢e break; case 2: { - const bool flagP1 = VGObject::IsPointOnLineSegment (p1, firstPoint, secondPoint); - const bool flagP2 = VGObject::IsPointOnLineSegment (p2, firstPoint, secondPoint); + const bool flagP1 = VGObject::IsPointOnLineSegment (p1.toPoint(), firstPoint.toPoint(), + secondPoint.toPoint()); + const bool flagP2 = VGObject::IsPointOnLineSegment (p2.toPoint(), firstPoint.toPoint(), + secondPoint.toPoint()); if ((flagP1 == true && flagP2 == true) || (flagP1 == false && flagP2 == false)/*In case we have something wrong*/) { diff --git a/src/test/ValentinaTest/tst_vspline.cpp b/src/test/ValentinaTest/tst_vspline.cpp index 034807dc0..d42e828ff 100644 --- a/src/test/ValentinaTest/tst_vspline.cpp +++ b/src/test/ValentinaTest/tst_vspline.cpp @@ -88,3 +88,43 @@ void TST_VSpline::GetSegmentPoints() // Begin comparison Comparison(points, origPoints); } + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VSpline::GetSegmentPoints_issue412() +{ + // Input data taken from real case + // See issue #412 https://bitbucket.org/dismine/valentina/issues/412/error-in-detail-using-segment-a-simple + VPointF p1(869.11748031496063, -61.117228346456692, "p1", 5.0000125984251973, 9.9999874015748045); + VPointF p4(491.16472440944887, 316.83552755905515, "p4", 5.0000125984251973, 9.9999874015748045); + + VSpline spl(p1, p4, 270, 0, 1, 1, 1); + + QPointF begin(869.11748031496063, -61.117228346456692); + QPointF end(758.41768107838425, 206.13572832247544); + + QVector points; + points << spl.GetSegmentPoints(begin, end, false); + + QVector origPoints; + origPoints.append(QPointF(869.117480315, -61.1172283465)); + origPoints.append(QPointF(869.034855699, -51.3519540199)); + origPoints.append(QPointF(868.055234051, -32.0262592346)); + origPoints.append(QPointF(866.119738229, -12.967761819)); + origPoints.append(QPointF(863.252115711, 5.79979075097)); + origPoints.append(QPointF(859.476113972, 24.2526509993)); + origPoints.append(QPointF(854.815480488, 42.36707145)); + origPoints.append(QPointF(849.293962735, 60.1193046272)); + origPoints.append(QPointF(842.93530819, 77.4856030548)); + origPoints.append(QPointF(835.763264327, 94.4422192569)); + origPoints.append(QPointF(827.801578624, 110.965405758)); + origPoints.append(QPointF(819.073998555, 127.031415081)); + origPoints.append(QPointF(809.604271597, 142.616499751)); + origPoints.append(QPointF(799.416145227, 157.696912291)); + origPoints.append(QPointF(788.533366919, 172.248905226)); + origPoints.append(QPointF(776.97968415, 186.24873108)); + origPoints.append(QPointF(764.778844396, 199.672642377)); + origPoints.append(QPointF(758.417681078, 206.135728322)); + + // Begin comparison + Comparison(points, origPoints); +} diff --git a/src/test/ValentinaTest/tst_vspline.h b/src/test/ValentinaTest/tst_vspline.h index 9c575393e..ab9d283d7 100644 --- a/src/test/ValentinaTest/tst_vspline.h +++ b/src/test/ValentinaTest/tst_vspline.h @@ -41,6 +41,7 @@ signals: private slots: void GetSegmentPoints(); + void GetSegmentPoints_issue412(); };