From ba5ac8a04b1178eaa7f86866054690baa7048ee9 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Tue, 15 Mar 2016 17:38:07 +0200 Subject: [PATCH] Fixed issue #458. Issue with segment of curve. (grafted from 4d70b5b863bcad171e8185265cdcf4e177c5c90d) --HG-- branch : develop --- ChangeLog.txt | 1 + src/libs/vgeometry/vabstractcurve.cpp | 23 +++-- src/libs/vgeometry/vabstractcurve.h | 2 + src/libs/vgeometry/vgobject.cpp | 15 ++- src/libs/vgeometry/vgobject.h | 2 +- src/test/ValentinaTest/ValentinaTest.pro | 2 + src/test/ValentinaTest/qttestmainlambda.cpp | 2 + src/test/ValentinaTest/tst_vabstractcurve.cpp | 97 +++++++++++++++++++ src/test/ValentinaTest/tst_vabstractcurve.h | 45 +++++++++ 9 files changed, 176 insertions(+), 13 deletions(-) create mode 100644 src/test/ValentinaTest/tst_vabstractcurve.cpp create mode 100644 src/test/ValentinaTest/tst_vabstractcurve.h diff --git a/ChangeLog.txt b/ChangeLog.txt index 7194964f0..74ddc9fe2 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -12,6 +12,7 @@ - [#385] Add 'Open Recent' option in Tape.exe, 'File' dropdown menu. # Version 0.4.4 +- [#458] Issue with segment of curve. - Fixed disappearing curve if start and finish points of a segment are equal. - Fixed bug case where an open equidistant point is too far from a main path. - Fixed wrong handling with true darts points inside tool detail. diff --git a/src/libs/vgeometry/vabstractcurve.cpp b/src/libs/vgeometry/vabstractcurve.cpp index 084a955ea..431549162 100644 --- a/src/libs/vgeometry/vabstractcurve.cpp +++ b/src/libs/vgeometry/vabstractcurve.cpp @@ -58,12 +58,13 @@ VAbstractCurve::~VAbstractCurve() {} //--------------------------------------------------------------------------------------------------------------------- -QVector VAbstractCurve::GetSegmentPoints(const QPointF &begin, const QPointF &end, bool reverse) const +QVector VAbstractCurve::GetSegmentPoints(const QVector &points, const QPointF &begin, + const QPointF &end, bool reverse) { - QVector points = GetPoints(); + QVector segment = points; if (reverse) { - points = GetReversePoints(points); + segment = GetReversePoints(segment); } QPointF start = begin; @@ -71,13 +72,19 @@ QVector VAbstractCurve::GetSegmentPoints(const QPointF &begin, const QP if (begin == end) { - start = points.first(); - finish = points.last(); + start = segment.first(); + finish = segment.last(); } - points = FromBegin(points, start); - points = ToEnd(points, finish); - return points; + segment = FromBegin(segment, start); + segment = ToEnd(segment, finish); + return segment; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector VAbstractCurve::GetSegmentPoints(const QPointF &begin, const QPointF &end, bool reverse) const +{ + return GetSegmentPoints(GetPoints(), begin, end, reverse); } diff --git a/src/libs/vgeometry/vabstractcurve.h b/src/libs/vgeometry/vabstractcurve.h index 536406a95..fbc32ac7a 100644 --- a/src/libs/vgeometry/vabstractcurve.h +++ b/src/libs/vgeometry/vabstractcurve.h @@ -49,6 +49,8 @@ public: virtual ~VAbstractCurve() Q_DECL_OVERRIDE; virtual QVector GetPoints() const =0; + static QVector GetSegmentPoints(const QVector &points, const QPointF &begin, const QPointF &end, + bool reverse = false); QVector GetSegmentPoints(const QPointF &begin, const QPointF &end, bool reverse = false) const; virtual QPainterPath GetPath(PathDirection direction = PathDirection::Hide) const; diff --git a/src/libs/vgeometry/vgobject.cpp b/src/libs/vgeometry/vgobject.cpp index aa4cd848f..8bcab8340 100644 --- a/src/libs/vgeometry/vgobject.cpp +++ b/src/libs/vgeometry/vgobject.cpp @@ -440,21 +440,28 @@ void VGObject::LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c */ bool VGObject::IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const QPointF &p2) { + // Round points. 1 mm now more than 3 pixels (96 dpi). So, no big reasons to work with float values. + // See bug issue #458 Issue with segment of curve. + // https://bitbucket.org/dismine/valentina/issues/458/issue-with-segment-of-curve + const QPoint tR = t.toPoint(); + const QPoint p1R = p1.toPoint(); + const QPoint p2R = p2.toPoint(); + // 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()) )) + if (not ( (p1R.x() <= tR.x() && tR.x() <= p2R.x()) || (p2R.x() <= tR.x() && tR.x() <= p1R.x()) )) { // test point not in x-range return false; } - if (not ( (p1.y() <= t.y() && t.y() <= p2.y()) || (p2.y() <= t.y() && t.y() <= p1.y()) )) + if (not ( (p1R.y() <= tR.y() && tR.y() <= p2R.y()) || (p2R.y() <= tR.y() && tR.y() <= p1R.y()) )) { // test point not in y-range return false; } // Test via the perp dot product (PDP) - return IsPointOnLineviaPDP(t, p1, p2); + return IsPointOnLineviaPDP(tR, p1R, p2R); } //--------------------------------------------------------------------------------------------------------------------- @@ -474,7 +481,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 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()); } diff --git a/src/libs/vgeometry/vgobject.h b/src/libs/vgeometry/vgobject.h index 9cda0214a..bd58c4170 100644 --- a/src/libs/vgeometry/vgobject.h +++ b/src/libs/vgeometry/vgobject.h @@ -92,7 +92,7 @@ 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 double PerpDotProduct(const QPointF &p1, const QPointF &p2, const QPointF &t); static 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/ValentinaTest.pro b/src/test/ValentinaTest/ValentinaTest.pro index 52a187aa9..a57763b63 100644 --- a/src/test/ValentinaTest/ValentinaTest.pro +++ b/src/test/ValentinaTest/ValentinaTest.pro @@ -54,6 +54,7 @@ SOURCES += \ tst_vcommandline.cpp \ tst_tstranslation.cpp \ tst_vdetail.cpp \ + tst_vabstractcurve.cpp \ tst_findpoint.cpp \ tst_vellipticalarc.cpp @@ -77,6 +78,7 @@ HEADERS += \ tst_vcommandline.h \ tst_tstranslation.h \ tst_vdetail.h \ + tst_vabstractcurve.h \ tst_findpoint.h \ tst_vellipticalarc.h diff --git a/src/test/ValentinaTest/qttestmainlambda.cpp b/src/test/ValentinaTest/qttestmainlambda.cpp index b1a4f4e1d..ec78c032f 100644 --- a/src/test/ValentinaTest/qttestmainlambda.cpp +++ b/src/test/ValentinaTest/qttestmainlambda.cpp @@ -47,6 +47,7 @@ #include "tst_tstranslation.h" #include "tst_vdetail.h" #include "tst_findpoint.h" +#include "tst_vabstractcurve.h" int main(int argc, char** argv) { @@ -80,6 +81,7 @@ int main(int argc, char** argv) ASSERT_TEST(new TST_Misc()); ASSERT_TEST(new TST_VCommandLine()); ASSERT_TEST(new TST_TSTranslation()); + ASSERT_TEST(new TST_VAbstractCurve()); return status; } diff --git a/src/test/ValentinaTest/tst_vabstractcurve.cpp b/src/test/ValentinaTest/tst_vabstractcurve.cpp new file mode 100644 index 000000000..84e148bf9 --- /dev/null +++ b/src/test/ValentinaTest/tst_vabstractcurve.cpp @@ -0,0 +1,97 @@ +/************************************************************************ + ** + ** @file tst_vabstractcurve.cpp + ** @author Roman Telezhynskyi + ** @date 15 3, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "tst_vabstractcurve.h" +#include "../vgeometry/vabstractcurve.h" + +#include + +//--------------------------------------------------------------------------------------------------------------------- +TST_VAbstractCurve::TST_VAbstractCurve(QObject *parent) + : AbstractTest(parent) +{ +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractCurve::GetSegmentPoints_issue458() +{ + // Real case. Issue #458. https://bitbucket.org/dismine/valentina/issues/458/issue-with-segment-of-curve + // See file AnalyzeStrangeIssueBug_isotated.val + + QVector curve; + curve.append(QPointF(-11.267867716535433, -621.9401574803151)); + curve.append(QPointF(28.929492484925593, -621.8607845421614)); + curve.append(QPointF(111.02420124017556, -621.0204613872887)); + curve.append(QPointF(192.81663506084445, -619.5641192834869)); + curve.append(QPointF(271.7042817720716, -617.7160624366999)); + curve.append(QPointF(380.07266406952584, -614.6790467524394)); + curve.append(QPointF(489.18908873700275, -611.324295072277)); + curve.append(QPointF(520.2546519685039, -610.6015748031497)); + curve.append(QPointF(520.2546519685039, -610.6015748031497)); + curve.append(QPointF(533.2501074340664, -610.4104062194663)); + curve.append(QPointF(558.2116609090922, -610.3912171914401)); + curve.append(QPointF(581.9682255886432, -610.7865804010944)); + curve.append(QPointF(604.5534016414362, -611.572911926731)); + curve.append(QPointF(626.0007892361873, -612.7266278466516)); + curve.append(QPointF(646.343988541613, -614.224144239158)); + curve.append(QPointF(665.6165997264297, -616.0418771825518)); + curve.append(QPointF(683.8522229593539, -618.1562427551349)); + curve.append(QPointF(701.0844584091014, -620.543657035209)); + curve.append(QPointF(717.3469062443893, -623.1805361010756)); + curve.append(QPointF(740.1064499883596, -627.5281982218287)); + curve.append(QPointF(767.2158219967725, -634.0157380079388)); + curve.append(QPointF(791.0508465842408, -641.0766263466508)); + curve.append(QPointF(811.8803251004954, -648.5221918643786)); + curve.append(QPointF(829.9730588952673, -656.1637631875356)); + curve.append(QPointF(845.5978493182879, -663.8126689425358)); + curve.append(QPointF(859.0234977192879, -671.2802377557932)); + curve.append(QPointF(875.8174743129977, -681.8104925021551)); + curve.append(QPointF(892.6995351796473, -693.3935519951781)); + curve.append(QPointF(899.4017385826772, -697.5307086614174)); + + QPointF begin (541.621890489816, -610.374541985993); + QPointF end (660.2625170532651, -735.7793605757131); + + const QVector points = VAbstractCurve::GetSegmentPoints(curve, begin, end, true); + + QVector origPoints; + origPoints.append(QPointF(541.621890489816, -610.374541985993)); + origPoints.append(QPointF(533.2501074340664, -610.4104062194663)); + origPoints.append(QPointF(520.2546519685039, -610.6015748031497)); + origPoints.append(QPointF(520.2546519685039, -610.6015748031497)); + origPoints.append(QPointF(489.18908873700275, -611.324295072277)); + origPoints.append(QPointF(380.07266406952584, -614.6790467524394)); + origPoints.append(QPointF(271.7042817720716, -617.7160624366999)); + origPoints.append(QPointF(192.81663506084445, -619.5641192834869)); + origPoints.append(QPointF(111.02420124017556, -621.0204613872887)); + origPoints.append(QPointF(28.929492484925593, -621.8607845421614)); + origPoints.append(QPointF(-11.267867716535433, -621.9401574803151)); + + // Begin comparison + Comparison(points, origPoints); +} diff --git a/src/test/ValentinaTest/tst_vabstractcurve.h b/src/test/ValentinaTest/tst_vabstractcurve.h new file mode 100644 index 000000000..642bb741e --- /dev/null +++ b/src/test/ValentinaTest/tst_vabstractcurve.h @@ -0,0 +1,45 @@ +/************************************************************************ + ** + ** @file tst_vabstractcurve.h + ** @author Roman Telezhynskyi + ** @date 15 3, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef TST_VABSTRACTCURVE_H +#define TST_VABSTRACTCURVE_H + +#include "abstracttest.h" + +class TST_VAbstractCurve : public AbstractTest +{ + Q_OBJECT +public: + explicit TST_VAbstractCurve(QObject *parent = nullptr); + +private slots: + void GetSegmentPoints_issue458(); + +}; + +#endif // TST_VABSTRACTCURVE_H