From 7143d9fe1652f4edf52cd3b0c9dedd026a6788db Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Tue, 9 Jun 2015 13:21:10 +0300 Subject: [PATCH] Construct acr from angle and length. --HG-- branch : develop --- src/libs/vgeometry/varc.cpp | 111 +++++++++++++++++--- src/libs/vgeometry/varc.h | 11 ++ src/libs/vgeometry/varc_p.h | 23 +++- src/test/ValentinaTest/ValentinaTest.pro | 6 +- src/test/ValentinaTest/qttestmainlambda.cpp | 2 + src/test/ValentinaTest/tst_varc.cpp | 73 +++++++++++++ src/test/ValentinaTest/tst_varc.h | 45 ++++++++ 7 files changed, 253 insertions(+), 18 deletions(-) create mode 100644 src/test/ValentinaTest/tst_varc.cpp create mode 100644 src/test/ValentinaTest/tst_varc.h diff --git a/src/libs/vgeometry/varc.cpp b/src/libs/vgeometry/varc.cpp index 9a4aa2487..be7c64a88 100644 --- a/src/libs/vgeometry/varc.cpp +++ b/src/libs/vgeometry/varc.cpp @@ -55,17 +55,32 @@ VArc::VArc (VPointF center, qreal radius, QString formulaRadius, qreal f1, QStri : VAbstractCurve(GOType::Arc, idObject, mode), d (new VArcData(center, radius, formulaRadius, f1, formulaF1, f2, formulaF2)) { - setName(QString (arc_+"%1").arg(this->GetCenter().name())); + ArcName(); } //--------------------------------------------------------------------------------------------------------------------- VArc::VArc(VPointF center, qreal radius, qreal f1, qreal f2) : VAbstractCurve(GOType::Arc, NULL_ID, Draw::Calculation), d (new VArcData(center, radius, f1, f2)) { - setName(QString (arc_+"%1").arg(this->GetCenter().name())); - d->formulaF1 = QString("%1").arg(f1); - d->formulaF2 = QString("%1").arg(f2); - d->formulaRadius = QString("%1").arg(radius); + ArcName(); +} + +//--------------------------------------------------------------------------------------------------------------------- +VArc::VArc(qreal length, QString formulaLength, VPointF center, qreal radius, QString formulaRadius, qreal f1, + QString formulaF1, quint32 idObject, Draw mode) + : VAbstractCurve(GOType::Arc, idObject, mode), + d (new VArcData(formulaLength, center, radius, formulaRadius, f1, formulaF1)) +{ + ArcName(); + FindF2(length); +} + +//--------------------------------------------------------------------------------------------------------------------- +VArc::VArc(qreal length, VPointF center, qreal radius, qreal f1) + : VAbstractCurve(GOType::Arc, NULL_ID, Draw::Calculation), d (new VArcData(center, radius, f1)) +{ + ArcName(); + FindF2(length); } //--------------------------------------------------------------------------------------------------------------------- @@ -105,7 +120,13 @@ VArc::~VArc() */ qreal VArc::GetLength() const { - return (M_PI * d->radius)/180 * AngleArc(); + qreal length = (M_PI * d->radius)/180 * AngleArc(); + if (d->isFlipped) + { + length = length * -1; + } + + return length; } //--------------------------------------------------------------------------------------------------------------------- @@ -150,7 +171,15 @@ qreal VArc::AngleArc() const l1.setAngle(d->f1); QLineF l2(0, 0, 100, 100); l2.setAngle(d->f2); - return l1.angleTo(l2); + + qreal ang = l1.angleTo(l2); + + if (d->isFlipped) + { + ang = 360 - ang; + } + + return ang; } //--------------------------------------------------------------------------------------------------------------------- @@ -162,18 +191,27 @@ QVector VArc::GetPoints() const { QVector points; qreal i = 0; - qreal angle = AngleArc(); - qint32 k = static_cast(angle); - qreal s = angle/(k/4); + const qreal angle = AngleArc(); + const qint32 k = static_cast(angle); + const qreal s = angle/(k/4); do { - QLineF line(d->center.toQPointF(), GetP1()); + QPointF pStart; + if (d->isFlipped) + { + pStart = GetP2(); + } + else + { + pStart = GetP1(); + } + QLineF line(d->center.toQPointF(), pStart); line.setAngle(line.angle()+i); points.append(line.p2()); i = i + s; if (i > angle) { - QLineF line(d->center.toQPointF(), GetP1()); + QLineF line(d->center.toQPointF(), pStart); line.setAngle(line.angle()+angle); points.append(line.p2()); } @@ -239,6 +277,42 @@ void VArc::setId(const quint32 &id) setName(QString (arc_+"%1_%2").arg(d->center.name()).arg(id)); } +//--------------------------------------------------------------------------------------------------------------------- +void VArc::ArcName() +{ + setName(QString (arc_+"%1").arg(this->GetCenter().name())); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VArc::FindF2(qreal length) +{ + length < 0 ? d->isFlipped = true : d->isFlipped = false; + + if (length >= MaxLength()) + { + length = MaxLength(); + } + + qreal arcAngle = (qAbs(length)*180)/(M_PI*d->radius); + + if (d->isFlipped) + { + arcAngle = arcAngle * -1; + } + + QLineF startAngle(0, 0, 100, 0); + startAngle.setAngle(d->f1 + arcAngle);// We use QLineF just because it is easy way correct angle value + + d->f2 = startAngle.angle(); + d->formulaF2 = QString("%1").arg(d->f2); +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VArc::MaxLength() const +{ + return 2*M_PI*d->radius; +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief GetF1 return start angle. @@ -335,3 +409,16 @@ void VArc::SetCenter(const VPointF &value) { d->center = value; } + +//--------------------------------------------------------------------------------------------------------------------- +QString VArc::GetFormulaLength() const +{ + return d->formulaLength; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VArc::SetFormulaLength(const QString &formula, qreal value) +{ + d->formulaLength = formula; + FindF2(value); +} diff --git a/src/libs/vgeometry/varc.h b/src/libs/vgeometry/varc.h index 63850a5ba..30591883a 100644 --- a/src/libs/vgeometry/varc.h +++ b/src/libs/vgeometry/varc.h @@ -47,6 +47,9 @@ public: VArc (VPointF center, qreal radius, QString formulaRadius, qreal f1, QString formulaF1, qreal f2, QString formulaF2, quint32 idObject = 0, Draw mode = Draw::Calculation); VArc (VPointF center, qreal radius, qreal f1, qreal f2); + VArc (qreal length, QString formulaLength, VPointF center, qreal radius, QString formulaRadius, qreal f1, + QString formulaF1, quint32 idObject = 0, Draw mode = Draw::Calculation); + VArc (qreal length, VPointF center, qreal radius, qreal f1); VArc(const VArc &arc); VArc& operator= (const VArc &arc); virtual ~VArc(); @@ -66,7 +69,10 @@ public: VPointF GetCenter () const; void SetCenter (const VPointF &value); + QString GetFormulaLength () const; + void SetFormulaLength (const QString &formula, qreal value); qreal GetLength () const; + QPointF GetP1() const; QPointF GetP2 () const; qreal AngleArc() const; @@ -76,6 +82,11 @@ public: virtual void setId(const quint32 &id); private: QSharedDataPointer d; + + void ArcName(); + void FindF2(qreal length); + + qreal MaxLength() const; }; #endif // VARC_H diff --git a/src/libs/vgeometry/varc_p.h b/src/libs/vgeometry/varc_p.h index 3b406a58d..f5481c2d5 100644 --- a/src/libs/vgeometry/varc_p.h +++ b/src/libs/vgeometry/varc_p.h @@ -44,23 +44,34 @@ public: VArcData () : f1(0), formulaF1(QString()), f2(0), formulaF2(QString()), radius(0), formulaRadius(QString()), - center(VPointF()) + center(VPointF()), isFlipped(false), formulaLength() {} VArcData (VPointF center, qreal radius, QString formulaRadius, qreal f1, QString formulaF1, qreal f2, QString formulaF2) : f1(f1), formulaF1(formulaF1), f2(f2), formulaF2(formulaF2), radius(radius), formulaRadius(formulaRadius), - center(center) + center(center), isFlipped(false), formulaLength() {} VArcData(VPointF center, qreal radius, qreal f1, qreal f2) : f1(f1), formulaF1(QString("%1").arg(f1)), f2(f2), formulaF2(QString("%1").arg(f2)), radius(radius), - formulaRadius(QString("%1").arg(radius)), center(center) + formulaRadius(QString("%1").arg(radius)), center(center), isFlipped(false), formulaLength() + {} + + VArcData (QString formulaLength, VPointF center, qreal radius, QString formulaRadius, qreal f1, QString formulaF1 ) + : f1(f1), formulaF1(formulaF1), f2(0), formulaF2("0"), radius(radius), formulaRadius(formulaRadius), + center(center), isFlipped(false), formulaLength(formulaLength) + {} + + VArcData(VPointF center, qreal radius, qreal f1) + : f1(f1), formulaF1(QString("%1").arg(f1)), f2(0), formulaF2("0"), radius(radius), + formulaRadius(QString("%1").arg(radius)), center(center), isFlipped(false), formulaLength() {} VArcData(const VArcData &arc) : QSharedData(arc), f1(arc.f1), formulaF1(arc.formulaF1), f2(arc.f2), formulaF2(arc.formulaF2), - radius(arc.radius), formulaRadius(arc.formulaRadius), center(arc.center) + radius(arc.radius), formulaRadius(arc.formulaRadius), center(arc.center), isFlipped(arc.isFlipped), + formulaLength(arc.formulaLength) {} virtual ~VArcData(); @@ -85,6 +96,10 @@ public: /** @brief center center point of arc. */ VPointF center; + + bool isFlipped; + + QString formulaLength; }; VArcData::~VArcData() diff --git a/src/test/ValentinaTest/ValentinaTest.pro b/src/test/ValentinaTest/ValentinaTest.pro index 9cd11a249..7a560610c 100644 --- a/src/test/ValentinaTest/ValentinaTest.pro +++ b/src/test/ValentinaTest/ValentinaTest.pro @@ -40,7 +40,8 @@ SOURCES += \ tst_vspline.cpp \ abstracttest.cpp \ tst_nameregexp.cpp \ - tst_vlayoutdetail.cpp + tst_vlayoutdetail.cpp \ + tst_varc.cpp HEADERS += \ tst_vposter.h \ @@ -48,7 +49,8 @@ HEADERS += \ tst_vspline.h \ abstracttest.h \ tst_nameregexp.h \ - tst_vlayoutdetail.h + tst_vlayoutdetail.h \ + tst_varc.h CONFIG(debug, debug|release){ # Debug mode diff --git a/src/test/ValentinaTest/qttestmainlambda.cpp b/src/test/ValentinaTest/qttestmainlambda.cpp index a4fa8d606..08a415890 100644 --- a/src/test/ValentinaTest/qttestmainlambda.cpp +++ b/src/test/ValentinaTest/qttestmainlambda.cpp @@ -33,6 +33,7 @@ #include "tst_vspline.h" #include "tst_nameregexp.h" #include "tst_vlayoutdetail.h" +#include "tst_varc.h" int main(int argc, char** argv) { @@ -50,6 +51,7 @@ int main(int argc, char** argv) ASSERT_TEST(new TST_VSpline()); ASSERT_TEST(new TST_NameRegExp()); ASSERT_TEST(new TST_VLayoutDetail()); + ASSERT_TEST(new TST_VArc()); return status; } diff --git a/src/test/ValentinaTest/tst_varc.cpp b/src/test/ValentinaTest/tst_varc.cpp new file mode 100644 index 000000000..629f2a723 --- /dev/null +++ b/src/test/ValentinaTest/tst_varc.cpp @@ -0,0 +1,73 @@ +/************************************************************************ + ** + ** @file tst_varc.cpp + ** @author Roman Telezhynskyi + ** @date 9 6, 2015 + ** + ** @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) 2015 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_varc.h" +#include "../../libs/vgeometry/varc.h" + +#include + +//--------------------------------------------------------------------------------------------------------------------- +TST_VArc::TST_VArc(QObject *parent) + :QObject(parent) +{} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VArc::CompareTwoWays() +{ + const VPointF center; + const qreal radius = 100; + const qreal f1 = 1; + const qreal f2 = 46; + const qreal length = M_PI*radius/180*(f2-f1); + + VArc arc1(center, radius, f1, f2); + VArc arc2(length, center, radius, f1); + + QCOMPARE(arc1.GetLength(), length); + QCOMPARE(arc2.GetLength(), length); + + QCOMPARE(arc1.GetLength(), arc2.GetLength()); + QCOMPARE(arc1.GetEndAngle(), arc2.GetEndAngle()); + + QCOMPARE(arc1.GetEndAngle(), f2); + QCOMPARE(arc2.GetEndAngle(), f2); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VArc::NegativeArc() +{ + const VPointF center; + const qreal radius = 100; + const qreal f1 = 1; + const qreal f2 = 316; + const qreal length = M_PI*radius/180*45; + VArc arc(-length, center, radius, f1); + + QCOMPARE(arc.GetLength(), -length); + QCOMPARE(arc.GetEndAngle(), f2); +} diff --git a/src/test/ValentinaTest/tst_varc.h b/src/test/ValentinaTest/tst_varc.h new file mode 100644 index 000000000..44361a84f --- /dev/null +++ b/src/test/ValentinaTest/tst_varc.h @@ -0,0 +1,45 @@ +/************************************************************************ + ** + ** @file tst_varc.h + ** @author Roman Telezhynskyi + ** @date 9 6, 2015 + ** + ** @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) 2015 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_VARC_H +#define TST_VARC_H + +#include + +class TST_VArc : public QObject +{ + Q_OBJECT +public: + explicit TST_VArc(QObject *parent = 0); + +private slots: + void CompareTwoWays(); + void NegativeArc(); +}; + +#endif // TST_VARC_H