From fe56607d7d1c03e950d89d208cc6c3bd07c28eec Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Sat, 10 Sep 2016 21:40:30 +0300 Subject: [PATCH] Flipping VSpline, VSplinePath, VEllipticalArc, VCubicBezierPath and VCubicBezier. --HG-- branch : feature --- src/libs/vgeometry/vcubicbezier.cpp | 12 ++++ src/libs/vgeometry/vcubicbezier.h | 1 + src/libs/vgeometry/vcubicbezierpath.cpp | 13 ++++ src/libs/vgeometry/vcubicbezierpath.h | 1 + src/libs/vgeometry/vellipticalarc.cpp | 14 +++++ src/libs/vgeometry/vellipticalarc.h | 2 + src/libs/vgeometry/vspline.cpp | 14 +++++ src/libs/vgeometry/vspline.h | 1 + src/libs/vgeometry/vsplinepath.cpp | 22 +++++++ src/libs/vgeometry/vsplinepath.h | 1 + src/test/ValentinaTest/tst_vellipticalarc.cpp | 41 +++++++++++++ src/test/ValentinaTest/tst_vellipticalarc.h | 2 + src/test/ValentinaTest/tst_vspline.cpp | 44 +++++++++++++ src/test/ValentinaTest/tst_vspline.h | 2 + src/test/ValentinaTest/tst_vsplinepath.cpp | 61 +++++++++++++++++++ src/test/ValentinaTest/tst_vsplinepath.h | 2 + 16 files changed, 233 insertions(+) diff --git a/src/libs/vgeometry/vcubicbezier.cpp b/src/libs/vgeometry/vcubicbezier.cpp index cfa3b071d..3b3d88786 100644 --- a/src/libs/vgeometry/vcubicbezier.cpp +++ b/src/libs/vgeometry/vcubicbezier.cpp @@ -78,6 +78,18 @@ VCubicBezier VCubicBezier::Rotate(const QPointF &originPoint, qreal degrees, con return curve; } +//--------------------------------------------------------------------------------------------------------------------- +VCubicBezier VCubicBezier::Flip(const QLineF &axis, const QString &prefix) const +{ + const VPointF p1 = GetP1().Flip(axis); + const VPointF p2 = GetP2().Flip(axis); + const VPointF p3 = GetP3().Flip(axis); + const VPointF p4 = GetP4().Flip(axis); + VCubicBezier curve(p1, p2, p3, p4); + curve.setName(name() + prefix); + return curve; +} + //--------------------------------------------------------------------------------------------------------------------- VCubicBezier::~VCubicBezier() { diff --git a/src/libs/vgeometry/vcubicbezier.h b/src/libs/vgeometry/vcubicbezier.h index 8b6c1f338..283141884 100644 --- a/src/libs/vgeometry/vcubicbezier.h +++ b/src/libs/vgeometry/vcubicbezier.h @@ -53,6 +53,7 @@ public: Draw mode = Draw::Calculation); VCubicBezier &operator=(const VCubicBezier &curve); VCubicBezier Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const; + VCubicBezier Flip(const QLineF &axis, const QString &prefix = QString()) const; virtual ~VCubicBezier(); virtual VPointF GetP1() const Q_DECL_OVERRIDE; diff --git a/src/libs/vgeometry/vcubicbezierpath.cpp b/src/libs/vgeometry/vcubicbezierpath.cpp index 496354a8a..1cc4c9c1b 100644 --- a/src/libs/vgeometry/vcubicbezierpath.cpp +++ b/src/libs/vgeometry/vcubicbezierpath.cpp @@ -91,6 +91,19 @@ VCubicBezierPath VCubicBezierPath::Rotate(const QPointF &originPoint, qreal degr return curve; } +//--------------------------------------------------------------------------------------------------------------------- +VCubicBezierPath VCubicBezierPath::Flip(const QLineF &axis, const QString &prefix) const +{ + const QVector points = GetCubicPath(); + VCubicBezierPath curve; + for(int i=0; i < points.size(); ++i) + { + curve.append(points.at(i).Flip(axis)); + } + curve.setName(name() + prefix); + return curve; +} + //--------------------------------------------------------------------------------------------------------------------- VCubicBezierPath::~VCubicBezierPath() { diff --git a/src/libs/vgeometry/vcubicbezierpath.h b/src/libs/vgeometry/vcubicbezierpath.h index b232a7567..c0c38cd8e 100644 --- a/src/libs/vgeometry/vcubicbezierpath.h +++ b/src/libs/vgeometry/vcubicbezierpath.h @@ -56,6 +56,7 @@ public: VCubicBezierPath(const QVector &points, quint32 idObject = 0, Draw mode = Draw::Calculation); VCubicBezierPath &operator=(const VCubicBezierPath &curve); VCubicBezierPath Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const; + VCubicBezierPath Flip(const QLineF &axis, const QString &prefix = QString()) const; virtual ~VCubicBezierPath(); VPointF &operator[](int indx); diff --git a/src/libs/vgeometry/vellipticalarc.cpp b/src/libs/vgeometry/vellipticalarc.cpp index f501a3392..81798cc81 100644 --- a/src/libs/vgeometry/vellipticalarc.cpp +++ b/src/libs/vgeometry/vellipticalarc.cpp @@ -134,6 +134,20 @@ VEllipticalArc VEllipticalArc::Rotate(const QPointF &originPoint, qreal degrees, return elArc; } +//--------------------------------------------------------------------------------------------------------------------- +VEllipticalArc VEllipticalArc::Flip(const QLineF &axis, const QString &prefix) const +{ + const VPointF center = GetCenter().Flip(axis); + const QPointF p1 = VPointF::FlipPF(axis, GetP1()); + const QPointF p2 = VPointF::FlipPF(axis, GetP2()); + const qreal f1 = QLineF(center, p1).angle() - GetRotationAngle(); + const qreal f2 = QLineF(center, p2).angle() - GetRotationAngle(); + VEllipticalArc elArc(center, GetRadius1(), GetRadius2(), f1, f2, GetRotationAngle()); + elArc.setName(name() + prefix); + elArc.SetFlipped(true); + return elArc; +} + //--------------------------------------------------------------------------------------------------------------------- VEllipticalArc::~VEllipticalArc() {} diff --git a/src/libs/vgeometry/vellipticalarc.h b/src/libs/vgeometry/vellipticalarc.h index 79393a70f..b77372efd 100644 --- a/src/libs/vgeometry/vellipticalarc.h +++ b/src/libs/vgeometry/vellipticalarc.h @@ -63,6 +63,7 @@ public: VEllipticalArc& operator= (const VEllipticalArc &arc); VEllipticalArc Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const; + VEllipticalArc Flip(const QLineF &axis, const QString &prefix = QString()) const; virtual ~VEllipticalArc() Q_DECL_OVERRIDE; @@ -99,6 +100,7 @@ private: static int GetQuadransRad(qreal &rad); }; +Q_DECLARE_METATYPE(VEllipticalArc) Q_DECLARE_TYPEINFO(VEllipticalArc, Q_MOVABLE_TYPE); #endif // VELLIPTICALARC_H diff --git a/src/libs/vgeometry/vspline.cpp b/src/libs/vgeometry/vspline.cpp index 2234caea0..b9fceff03 100644 --- a/src/libs/vgeometry/vspline.cpp +++ b/src/libs/vgeometry/vspline.cpp @@ -126,6 +126,20 @@ VSpline VSpline::Rotate(const QPointF &originPoint, qreal degrees, const QString return spl; } +//--------------------------------------------------------------------------------------------------------------------- +VSpline VSpline::Flip(const QLineF &axis, const QString &prefix) const +{ + const VPointF p1 = GetP1().Flip(axis); + const VPointF p4 = GetP4().Flip(axis); + + const QPointF p2 = VPointF::FlipPF(axis, GetP2()); + const QPointF p3 = VPointF::FlipPF(axis, GetP3()); + + VSpline spl(p1, p2, p3, p4); + spl.setName(name() + prefix); + return spl; +} + //--------------------------------------------------------------------------------------------------------------------- VSpline::~VSpline() {} diff --git a/src/libs/vgeometry/vspline.h b/src/libs/vgeometry/vspline.h index e648a3c80..78705e496 100644 --- a/src/libs/vgeometry/vspline.h +++ b/src/libs/vgeometry/vspline.h @@ -63,6 +63,7 @@ public: const QString &angle2Formula, qreal c1Length, const QString &c1LengthFormula, qreal c2Length, const QString &c2LengthFormula, quint32 idObject = 0, Draw mode = Draw::Calculation); VSpline Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const; + VSpline Flip(const QLineF &axis, const QString &prefix = QString()) const; virtual ~VSpline(); VSpline &operator=(const VSpline &spl); diff --git a/src/libs/vgeometry/vsplinepath.cpp b/src/libs/vgeometry/vsplinepath.cpp index 8410c8364..bbf0be400 100644 --- a/src/libs/vgeometry/vsplinepath.cpp +++ b/src/libs/vgeometry/vsplinepath.cpp @@ -122,6 +122,28 @@ VSplinePath VSplinePath::Rotate(const QPointF &originPoint, qreal degrees, const return splPath; } +//--------------------------------------------------------------------------------------------------------------------- +VSplinePath VSplinePath::Flip(const QLineF &axis, const QString &prefix) const +{ + QVector newPoints(CountPoints()); + for (qint32 i = 1; i <= CountSubSpl(); ++i) + { + const VSpline spl = GetSpline(i).Flip(axis); + + newPoints[i-1].SetP(spl.GetP1()); + newPoints[i-1].SetAngle2(spl.GetStartAngle(), spl.GetStartAngleFormula()); + newPoints[i-1].SetLength2(spl.GetC1Length(), spl.GetC1LengthFormula()); + + newPoints[i].SetP(spl.GetP4()); + newPoints[i].SetAngle1(spl.GetEndAngle(), spl.GetEndAngleFormula()); + newPoints[i].SetLength1(spl.GetC2Length(), spl.GetC2LengthFormula()); + } + + VSplinePath splPath(newPoints); + splPath.setName(name() + prefix); + return splPath; +} + //--------------------------------------------------------------------------------------------------------------------- VSplinePath::~VSplinePath() {} diff --git a/src/libs/vgeometry/vsplinepath.h b/src/libs/vgeometry/vsplinepath.h index e0dea14d9..424e1de44 100644 --- a/src/libs/vgeometry/vsplinepath.h +++ b/src/libs/vgeometry/vsplinepath.h @@ -61,6 +61,7 @@ public: VSplinePath(const QVector &points, quint32 idObject = 0, Draw mode = Draw::Calculation); VSplinePath(const VSplinePath& splPath); VSplinePath Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const; + VSplinePath Flip(const QLineF &axis, const QString &prefix = QString()) const; virtual ~VSplinePath() Q_DECL_OVERRIDE; VSplinePath &operator=(const VSplinePath &path); diff --git a/src/test/ValentinaTest/tst_vellipticalarc.cpp b/src/test/ValentinaTest/tst_vellipticalarc.cpp index 023884d47..5abd8b583 100644 --- a/src/test/ValentinaTest/tst_vellipticalarc.cpp +++ b/src/test/ValentinaTest/tst_vellipticalarc.cpp @@ -31,6 +31,7 @@ #include "../vlayout/vabstractdetail.h" #include "../vmisc/logging.h" +#include #include //--------------------------------------------------------------------------------------------------------------------- @@ -455,3 +456,43 @@ void TST_VEllipticalArc::TestRotation() const QString errorMsg = QString("The name doesn't contain the prefix '%1'.").arg(prefix); QVERIFY2(rotatedArc.name().endsWith(prefix), qUtf8Printable(errorMsg)); } + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VEllipticalArc::TestFlip_data() +{ + QTest::addColumn("elArc"); + QTest::addColumn("axis"); + QTest::addColumn("prefix"); + + const VEllipticalArc elArc(QPointF(), 10., 20.0, 1., 91., 0.); + + QLineF axis(QPointF(600, 30), QPointF(600, 1800)); + + QTest::newRow("Vertical axis") << elArc << axis << "a2"; + + axis = QLineF(QPointF(600, 30), QPointF(1200, 30)); + + QTest::newRow("Horizontal axis") << elArc << axis << "a2"; + + axis = QLineF(QPointF(600, 30), QPointF(600, 1800)); + axis.setAngle(45); + + QTest::newRow("Diagonal axis") << elArc << axis << "a2"; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VEllipticalArc::TestFlip() +{ + QFETCH(VEllipticalArc, elArc); + QFETCH(QLineF, axis); + QFETCH(QString, prefix); + + const VEllipticalArc res = elArc.Flip(axis, prefix); + + const QString errorMsg = QString("The name doesn't contain the prefix '%1'.").arg(prefix); + QVERIFY2(res.name().endsWith(prefix), qUtf8Printable(errorMsg)); + + QCOMPARE(qRound(elArc.GetLength()*-1), qRound(res.GetLength())); + QCOMPARE(elArc.GetRadius1(), res.GetRadius1()); + QCOMPARE(elArc.GetRadius2(), res.GetRadius2()); +} diff --git a/src/test/ValentinaTest/tst_vellipticalarc.h b/src/test/ValentinaTest/tst_vellipticalarc.h index 17e8fc2b1..61f1f678c 100644 --- a/src/test/ValentinaTest/tst_vellipticalarc.h +++ b/src/test/ValentinaTest/tst_vellipticalarc.h @@ -51,6 +51,8 @@ private slots: void TestGetPoints4(); void TestRotation_data(); void TestRotation(); + void TestFlip_data(); + void TestFlip(); private: Q_DISABLE_COPY(TST_VEllipticalArc) diff --git a/src/test/ValentinaTest/tst_vspline.cpp b/src/test/ValentinaTest/tst_vspline.cpp index b5c0e206e..364274b87 100644 --- a/src/test/ValentinaTest/tst_vspline.cpp +++ b/src/test/ValentinaTest/tst_vspline.cpp @@ -28,6 +28,7 @@ #include "tst_vspline.h" #include "../vgeometry/vspline.h" +#include "../vmisc/logging.h" #include @@ -388,6 +389,49 @@ void TST_VSpline::TestLengthByPoint() QVERIFY(qAbs(resLength - length) < ToPixel(0.5, Unit::Mm)); } +//--------------------------------------------------------------------------------------------------------------------- +void TST_VSpline::TestFlip_data() +{ + QTest::addColumn("spl"); + QTest::addColumn("axis"); + QTest::addColumn("prefix"); + + VPointF p1(1168.8582803149607, 39.999874015748034, "p1", 5.0000125984251973, 9.9999874015748045); + VPointF p4(681.33729132409951, 1815.7969526662778, "p4", 5.0000125984251973, 9.9999874015748045); + + VSpline spl(p1, p4, 229.381, 41.6325, 0.96294100000000005, 1.00054, 1); + + QLineF axis(QPointF(600, 30), QPointF(600, 1800)); + + QTest::newRow("Vertical axis") << spl << axis << "a2"; + + axis = QLineF(QPointF(600, 30), QPointF(1200, 30)); + + QTest::newRow("Horizontal axis") << spl << axis << "a2"; + + axis = QLineF(QPointF(600, 30), QPointF(600, 1800)); + axis.setAngle(45); + + QTest::newRow("Diagonal axis") << spl << axis << "a2"; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VSpline::TestFlip() +{ + QFETCH(VSpline, spl); + QFETCH(QLineF, axis); + QFETCH(QString, prefix); + + const VSpline res = spl.Flip(axis, prefix); + + const QString errorMsg = QString("The name doesn't contain the prefix '%1'.").arg(prefix); + QVERIFY2(res.name().endsWith(prefix), qUtf8Printable(errorMsg)); + + QCOMPARE(spl.GetLength(), res.GetLength()); + QCOMPARE(spl.GetC1Length(), res.GetC1Length()); + QCOMPARE(spl.GetC2Length(), res.GetC2Length()); +} + //--------------------------------------------------------------------------------------------------------------------- void TST_VSpline::CompareSplines(const VSpline &spl1, const VSpline &spl2) const { diff --git a/src/test/ValentinaTest/tst_vspline.h b/src/test/ValentinaTest/tst_vspline.h index 7e910baf9..776274222 100644 --- a/src/test/ValentinaTest/tst_vspline.h +++ b/src/test/ValentinaTest/tst_vspline.h @@ -51,6 +51,8 @@ private slots: void TestParametrT(); void TestLengthByPoint_data(); void TestLengthByPoint(); + void TestFlip_data(); + void TestFlip(); private: Q_DISABLE_COPY(TST_VSpline) diff --git a/src/test/ValentinaTest/tst_vsplinepath.cpp b/src/test/ValentinaTest/tst_vsplinepath.cpp index 14af3e847..586bd36e9 100644 --- a/src/test/ValentinaTest/tst_vsplinepath.cpp +++ b/src/test/ValentinaTest/tst_vsplinepath.cpp @@ -135,3 +135,64 @@ void TST_VSplinePath::TestRotation() } } +//--------------------------------------------------------------------------------------------------------------------- +void TST_VSplinePath::TestFlip_data() +{ + QTest::addColumn>("originPoints"); + QTest::addColumn("axis"); + QTest::addColumn("prefix"); + + QVector originPoints; + + { + VPointF pSpline(30, 39.999874015748034, "X", 5.0000125984251973, 9.9999874015748045); + VSplinePoint p(pSpline, 89.208600000000004, "89.2086", 269.20859999999999, "269.209", 0, "0", + 153.33618897637794, "4.05702"); + originPoints.append(p); + } + + { + VPointF pSpline(198.77104389529981, 249.18158602595835, "X", 5.0000125984251973, 9.9999874015748045); + VSplinePoint p(pSpline, 146.43199999999999, "146.432", 326.43200000000002, "326.432", + 36.387590551181106, "0.962755", 60.978897637795278, "1.6134"); + originPoints.append(p); + } + + { + VPointF pSpline(820.42771653543309, 417.95262992125987, "X", 5.0000125984251973, 9.9999874015748045); + VSplinePoint p(pSpline, 173.39500000000001, "173.395", 353.39499999999998, "353.395", + 381.23716535433073, "10.0869", 0, "0"); + originPoints.append(p); + } + + QLineF axis(QPointF(0, 0), QPointF(0, 10)); + + QTest::newRow("Vertical axis") << originPoints << axis << "a2"; + + axis = QLineF(QPointF(0, 0), QPointF(10, 0)); + + QTest::newRow("Horizontal axis") << originPoints << axis << "a2"; + + axis = QLineF(QPointF(0, 0), QPointF(0, 10)); + axis.setAngle(45); + + QTest::newRow("Diagonal axis") << originPoints << axis << "a2"; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VSplinePath::TestFlip() +{ + QFETCH(QVector, originPoints); + QFETCH(QLineF, axis); + QFETCH(QString, prefix); + + const VSplinePath splPath(originPoints); + const VSplinePath res = splPath.Flip(axis, prefix); + + const QString errorMsg = QString("The name doesn't contain the prefix '%1'.").arg(prefix); + QVERIFY2(res.name().endsWith(prefix), qUtf8Printable(errorMsg)); + + QCOMPARE(splPath.GetLength(), res.GetLength()); + QCOMPARE(splPath.CountPoints(), res.CountPoints()); +} + diff --git a/src/test/ValentinaTest/tst_vsplinepath.h b/src/test/ValentinaTest/tst_vsplinepath.h index 0baec27a2..60362ba95 100644 --- a/src/test/ValentinaTest/tst_vsplinepath.h +++ b/src/test/ValentinaTest/tst_vsplinepath.h @@ -39,6 +39,8 @@ public: private slots: void TestRotation_data(); void TestRotation(); + void TestFlip_data(); + void TestFlip(); private: Q_DISABLE_COPY(TST_VSplinePath) };