Fixed issue #458. Issue with segment of curve.

(grafted from 4d70b5b863bcad171e8185265cdcf4e177c5c90d)

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2016-03-15 17:38:07 +02:00
parent 4a9302ee4e
commit ba5ac8a04b
9 changed files with 176 additions and 13 deletions

View File

@ -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.

View File

@ -58,12 +58,13 @@ VAbstractCurve::~VAbstractCurve()
{}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VAbstractCurve::GetSegmentPoints(const QPointF &begin, const QPointF &end, bool reverse) const
QVector<QPointF> VAbstractCurve::GetSegmentPoints(const QVector<QPointF> &points, const QPointF &begin,
const QPointF &end, bool reverse)
{
QVector<QPointF> points = GetPoints();
QVector<QPointF> segment = points;
if (reverse)
{
points = GetReversePoints(points);
segment = GetReversePoints(segment);
}
QPointF start = begin;
@ -71,13 +72,19 @@ QVector<QPointF> 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<QPointF> VAbstractCurve::GetSegmentPoints(const QPointF &begin, const QPointF &end, bool reverse) const
{
return GetSegmentPoints(GetPoints(), begin, end, reverse);
}

View File

@ -49,6 +49,8 @@ public:
virtual ~VAbstractCurve() Q_DECL_OVERRIDE;
virtual QVector<QPointF> GetPoints() const =0;
static QVector<QPointF> GetSegmentPoints(const QVector<QPointF> &points, const QPointF &begin, const QPointF &end,
bool reverse = false);
QVector<QPointF> GetSegmentPoints(const QPointF &begin, const QPointF &end, bool reverse = false) const;
virtual QPainterPath GetPath(PathDirection direction = PathDirection::Hide) const;

View File

@ -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());
}

View File

@ -92,7 +92,7 @@ private:
QSharedDataPointer<VGObjectData> 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 &center, qreal radius);

View File

@ -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

View File

@ -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;
}

View File

@ -0,0 +1,97 @@
/************************************************************************
**
** @file tst_vabstractcurve.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "tst_vabstractcurve.h"
#include "../vgeometry/vabstractcurve.h"
#include <QtTest>
//---------------------------------------------------------------------------------------------------------------------
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<QPointF> 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<QPointF> points = VAbstractCurve::GetSegmentPoints(curve, begin, end, true);
QVector<QPointF> 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);
}

View File

@ -0,0 +1,45 @@
/************************************************************************
**
** @file tst_vabstractcurve.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#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