Merged in ValentinaZhuravska/valentina/feature (pull request #99)
Added VEllipticalArc --HG-- branch : develop
This commit is contained in:
commit
9c1730da12
|
@ -147,6 +147,7 @@ extern const QString ColorYellow;
|
||||||
// Hacks for avoiding the linker error "undefined reference to"
|
// Hacks for avoiding the linker error "undefined reference to"
|
||||||
#define SPL_ "Spl_"
|
#define SPL_ "Spl_"
|
||||||
#define ARC_ "Arc_"
|
#define ARC_ "Arc_"
|
||||||
|
#define EARC_ "ElArc_"
|
||||||
|
|
||||||
extern const QString line_;
|
extern const QString line_;
|
||||||
extern const QString angleLine_;
|
extern const QString angleLine_;
|
||||||
|
|
|
@ -283,7 +283,7 @@ QPointF VArc::CutArc(const qreal &length, VArc &arc1, VArc &arc2) const
|
||||||
len = length;
|
len = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal n = (len*180)/(M_PI*d->radius);
|
qreal n = (len*180)/(M_PI*d->radius); // n - is angle in degrees
|
||||||
QLineF line(GetCenter().toQPointF(), GetP1());
|
QLineF line(GetCenter().toQPointF(), GetP1());
|
||||||
line.setAngle(line.angle()+n);
|
line.setAngle(line.angle()+n);
|
||||||
|
|
||||||
|
@ -354,7 +354,7 @@ void VArc::FindF2(qreal length)
|
||||||
startAngle.setAngle(d->f1 + arcAngle);// We use QLineF just because it is easy way correct angle value
|
startAngle.setAngle(d->f1 + arcAngle);// We use QLineF just because it is easy way correct angle value
|
||||||
|
|
||||||
d->f2 = startAngle.angle();
|
d->f2 = startAngle.angle();
|
||||||
d->formulaF2 = QString("%1").arg(d->f2);
|
d->formulaF2 = QString().number(d->f2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include <QSharedData>
|
#include <QSharedData>
|
||||||
#include "vgeometrydef.h"
|
#include "vgeometrydef.h"
|
||||||
|
#include "../vmisc/vabstractapplication.h"
|
||||||
#include "vpointf.h"
|
#include "vpointf.h"
|
||||||
|
|
||||||
#ifdef Q_CC_GNU
|
#ifdef Q_CC_GNU
|
||||||
|
@ -54,18 +55,20 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
VArcData(VPointF center, qreal radius, qreal f1, qreal f2)
|
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),
|
: f1(f1), formulaF1(QString().number(f1)),
|
||||||
formulaRadius(QString("%1").arg(radius)), center(center), isFlipped(false), formulaLength()
|
f2(f2), formulaF2(QString().number(f2)),
|
||||||
|
radius(radius), formulaRadius(QString().number(qApp->fromPixel(radius))),
|
||||||
|
center(center), isFlipped(false), formulaLength()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
VArcData (QString formulaLength, VPointF center, qreal radius, QString formulaRadius, qreal f1, QString formulaF1 )
|
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),
|
: f1(f1), formulaF1(formulaF1), f2(0), formulaF2("0"), radius(radius), formulaRadius(formulaRadius),
|
||||||
center(center), isFlipped(false), formulaLength(formulaLength)
|
center(center), isFlipped(false), formulaLength(formulaLength)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
VArcData(VPointF center, qreal radius, qreal f1)
|
VArcData(VPointF center, qreal radius, qreal f1)
|
||||||
: f1(f1), formulaF1(QString("%1").arg(f1)), f2(0), formulaF2("0"), radius(radius),
|
: f1(f1), formulaF1(QString().number(f1)), f2(0), formulaF2("0"), radius(radius),
|
||||||
formulaRadius(QString("%1").arg(radius)), center(center), isFlipped(false), formulaLength()
|
formulaRadius(QString().number(qApp->fromPixel(radius))), center(center), isFlipped(false), formulaLength()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
VArcData(const VArcData &arc)
|
VArcData(const VArcData &arc)
|
||||||
|
|
592
src/libs/vgeometry/vellipticalarc.cpp
Normal file
592
src/libs/vgeometry/vellipticalarc.cpp
Normal file
|
@ -0,0 +1,592 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file vellipticalarc.cpp
|
||||||
|
** @author Valentina Zhuravska <zhuravska19(at)gmail.com>
|
||||||
|
** @date February 1, 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) 2013-2015 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 "vellipticalarc.h"
|
||||||
|
#include "vellipticalarc_p.h"
|
||||||
|
#include "vspline.h"
|
||||||
|
#include "../ifc/ifcdef.h"
|
||||||
|
#include <QtCore/qmath.h>
|
||||||
|
#include <QLineF>
|
||||||
|
#include <QPainterPath>
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief VEllipticalArc default constructor.
|
||||||
|
*/
|
||||||
|
VEllipticalArc::VEllipticalArc()
|
||||||
|
:VAbstractCurve(GOType::EllipticalArc), d (new VEllipticalArcData)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief VEllipticalArc constructor.
|
||||||
|
* @param center center point.
|
||||||
|
* @param radius1 arc major radius.
|
||||||
|
* @param radius2 arc minor radius.
|
||||||
|
* @param f1 start angle (degree).
|
||||||
|
* @param f2 end angle (degree).
|
||||||
|
*/
|
||||||
|
VEllipticalArc::VEllipticalArc (VPointF center, qreal radius1, qreal radius2,
|
||||||
|
QString formulaRadius1, QString formulaRadius2, qreal f1, QString formulaF1, qreal f2,
|
||||||
|
QString formulaF2, qreal rotationAngle, quint32 idObject, Draw mode)
|
||||||
|
: VAbstractCurve(GOType::EllipticalArc, idObject, mode),
|
||||||
|
d (new VEllipticalArcData(center, radius1, radius2, formulaRadius1, formulaRadius2,
|
||||||
|
f1, formulaF1, f2, formulaF2, rotationAngle))
|
||||||
|
{
|
||||||
|
CreateName();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
VEllipticalArc::VEllipticalArc(VPointF center, qreal radius1, qreal radius2, qreal f1, qreal f2, qreal rotationAngle)
|
||||||
|
: VAbstractCurve(GOType::EllipticalArc, NULL_ID, Draw::Calculation),
|
||||||
|
d (new VEllipticalArcData(center, radius1, radius2, f1, f2, rotationAngle))
|
||||||
|
{
|
||||||
|
CreateName();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
VEllipticalArc::VEllipticalArc(qreal length, QString formulaLength, VPointF center, qreal radius1, qreal radius2,
|
||||||
|
QString formulaRadius1, QString formulaRadius2, qreal f1, QString formulaF1, qreal rotationAngle,
|
||||||
|
quint32 idObject, Draw mode)
|
||||||
|
: VAbstractCurve(GOType::EllipticalArc, idObject, mode),
|
||||||
|
d (new VEllipticalArcData(formulaLength, center, radius1, radius2, formulaRadius1, formulaRadius2,
|
||||||
|
f1, formulaF1, rotationAngle))
|
||||||
|
{
|
||||||
|
CreateName();
|
||||||
|
FindF2(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
VEllipticalArc::VEllipticalArc(qreal length, VPointF center, qreal radius1, qreal radius2, qreal f1,
|
||||||
|
qreal rotationAngle)
|
||||||
|
: VAbstractCurve(GOType::EllipticalArc, NULL_ID, Draw::Calculation),
|
||||||
|
d (new VEllipticalArcData(center, radius1, radius2, f1, rotationAngle))
|
||||||
|
{
|
||||||
|
CreateName();
|
||||||
|
FindF2(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief VEllipticalArc copy constructor
|
||||||
|
* @param arc arc
|
||||||
|
*/
|
||||||
|
VEllipticalArc::VEllipticalArc(const VEllipticalArc &arc)
|
||||||
|
: VAbstractCurve(arc), d (arc.d)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief operator = assignment operator
|
||||||
|
* @param arc arc
|
||||||
|
* @return arc
|
||||||
|
*/
|
||||||
|
VEllipticalArc &VEllipticalArc::operator =(const VEllipticalArc &arc)
|
||||||
|
{
|
||||||
|
if ( &arc == this )
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
VAbstractCurve::operator=(arc);
|
||||||
|
d = arc.d;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
VEllipticalArc::~VEllipticalArc()
|
||||||
|
{}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetLength return arc length.
|
||||||
|
* @return length.
|
||||||
|
*/
|
||||||
|
qreal VEllipticalArc::GetLength() const
|
||||||
|
{
|
||||||
|
qreal length = 0;
|
||||||
|
QPainterPath elArc;
|
||||||
|
QVector<QPointF> points = GetPoints();
|
||||||
|
elArc.moveTo(points.at(0));
|
||||||
|
for (qint32 i = 1; i < points.count(); ++i)
|
||||||
|
{
|
||||||
|
elArc.lineTo(points.at(i));
|
||||||
|
}
|
||||||
|
length = elArc.length();
|
||||||
|
|
||||||
|
if (d->isFlipped)
|
||||||
|
{
|
||||||
|
length = length * -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetP1 return point associated with start angle.
|
||||||
|
* @return point.
|
||||||
|
*/
|
||||||
|
QPointF VEllipticalArc::GetP1() const
|
||||||
|
{
|
||||||
|
return GetPoint(d->f1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetP2 return point associated with end angle.
|
||||||
|
* @return point.
|
||||||
|
*/
|
||||||
|
QPointF VEllipticalArc::GetP2 () const
|
||||||
|
{
|
||||||
|
return GetPoint(d->f2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetPoint return point associated with angle.
|
||||||
|
* @return point.
|
||||||
|
*/
|
||||||
|
QPointF VEllipticalArc::GetPoint (qreal angle) const
|
||||||
|
{
|
||||||
|
if (angle > 360 || angle < 0)
|
||||||
|
{// Filter incorect value of angle
|
||||||
|
QLineF dummy(0,0, 100, 0);
|
||||||
|
dummy.setAngle(angle);
|
||||||
|
angle = dummy.angle();
|
||||||
|
}
|
||||||
|
|
||||||
|
// p - point without rotation
|
||||||
|
qreal x = qAbs((d->radius1 * d->radius2)/
|
||||||
|
(qSqrt(d->radius2*d->radius2+d->radius1*d->radius1*qTan(M_PI*angle/180)*qTan(M_PI*angle/180))));
|
||||||
|
qreal y = qAbs(qTan(M_PI*angle/180) * x);
|
||||||
|
|
||||||
|
if (angle > 90 && angle <= 180)
|
||||||
|
{
|
||||||
|
x = -x;
|
||||||
|
}
|
||||||
|
else if (angle > 180 && angle < 270)
|
||||||
|
{
|
||||||
|
x = -x;
|
||||||
|
y = -y;
|
||||||
|
}
|
||||||
|
else if (angle > 270)
|
||||||
|
{
|
||||||
|
y = -y;
|
||||||
|
}
|
||||||
|
else if (angle == 90)
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
y = d->radius2;
|
||||||
|
}
|
||||||
|
else if (angle == 270)
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
y = -d->radius2;
|
||||||
|
}
|
||||||
|
QPointF p ( GetCenter().x () + x, GetCenter().y () + y);
|
||||||
|
// rotation of point
|
||||||
|
QLineF line(GetCenter().toQPointF(), p);
|
||||||
|
line.setAngle(line.angle() + GetRotationAngle());
|
||||||
|
|
||||||
|
return line.p2();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief AngleArc calculate arc angle.
|
||||||
|
* @return angle in degree.
|
||||||
|
*/
|
||||||
|
qreal VEllipticalArc::AngleArc() const
|
||||||
|
{
|
||||||
|
if ((qFuzzyIsNull(d->f1) && qFuzzyCompare(d->f2, 360)) ||
|
||||||
|
(qFuzzyCompare(d->f1, 360) && qFuzzyIsNull(d->f2)))
|
||||||
|
{
|
||||||
|
return 360;
|
||||||
|
}
|
||||||
|
QLineF l1(0, 0, 100, 100);
|
||||||
|
l1.setAngle(d->f1);
|
||||||
|
QLineF l2(0, 0, 100, 100);
|
||||||
|
l2.setAngle(d->f2);
|
||||||
|
|
||||||
|
qreal ang = l1.angleTo(l2);
|
||||||
|
|
||||||
|
if (d->isFlipped)
|
||||||
|
{
|
||||||
|
ang = 360 - ang;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ang;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetAngles return list of angles needed for drawing arc.
|
||||||
|
* @return list of angles
|
||||||
|
*/
|
||||||
|
QVector<qreal> VEllipticalArc::GetAngles() const
|
||||||
|
{
|
||||||
|
QVector<qreal> sectionAngle;
|
||||||
|
qreal angle = AngleArc();
|
||||||
|
|
||||||
|
if (qFuzzyIsNull(angle))
|
||||||
|
{// Return the array that includes one angle
|
||||||
|
sectionAngle.append(d->f1);
|
||||||
|
return sectionAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (angle > 360 || angle < 0)
|
||||||
|
{// Filter incorect value of angle
|
||||||
|
QLineF dummy(0,0, 100, 0);
|
||||||
|
dummy.setAngle(angle);
|
||||||
|
angle = dummy.angle();
|
||||||
|
}
|
||||||
|
|
||||||
|
const qreal angleInterpolation = 45; //degree
|
||||||
|
const int sections = qFloor(angle / angleInterpolation);
|
||||||
|
for (int i = 0; i < sections; ++i)
|
||||||
|
{
|
||||||
|
sectionAngle.append(angleInterpolation);
|
||||||
|
}
|
||||||
|
|
||||||
|
const qreal tail = angle - sections * angleInterpolation;
|
||||||
|
if (tail > 0)
|
||||||
|
{
|
||||||
|
sectionAngle.append(tail);
|
||||||
|
}
|
||||||
|
return sectionAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetPoints return list of points needed for drawing arc.
|
||||||
|
* @return list of points
|
||||||
|
*/
|
||||||
|
QVector<QPointF> VEllipticalArc::GetPoints() const
|
||||||
|
{
|
||||||
|
QVector<QPointF> points;
|
||||||
|
QVector<qreal> sectionAngle = GetAngles();
|
||||||
|
|
||||||
|
qreal currentAngle;
|
||||||
|
d->isFlipped ? currentAngle = GetEndAngle() : currentAngle = GetStartAngle();
|
||||||
|
for (int i = 0; i < sectionAngle.size(); ++i)
|
||||||
|
{
|
||||||
|
QPointF startPoint = GetPoint(currentAngle);
|
||||||
|
QPointF ellipsePoint2 = GetPoint(currentAngle + sectionAngle.at(i)/3);
|
||||||
|
QPointF ellipsePoint3 = GetPoint(currentAngle + 2*sectionAngle.at(i)/3);
|
||||||
|
QPointF lastPoint = GetPoint(currentAngle + sectionAngle.at(i));
|
||||||
|
// four points that are on ellipse
|
||||||
|
|
||||||
|
QPointF bezierPoint1 = ( -5*startPoint + 18*ellipsePoint2 -9*ellipsePoint3 + 2*lastPoint )/6;
|
||||||
|
QPointF bezierPoint2 = ( 2*startPoint - 9*ellipsePoint2 + 18*ellipsePoint3 - 5*lastPoint )/6;
|
||||||
|
|
||||||
|
VSpline spl(VPointF(startPoint), bezierPoint1, bezierPoint2, VPointF(lastPoint), 1.0);
|
||||||
|
|
||||||
|
QVector<QPointF> splPoints = spl.GetPoints();
|
||||||
|
|
||||||
|
if (not splPoints.isEmpty() && i != sectionAngle.size() - 1)
|
||||||
|
{
|
||||||
|
splPoints.removeLast();
|
||||||
|
}
|
||||||
|
points << splPoints;
|
||||||
|
currentAngle += sectionAngle.at(i);
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief CutArc cut arc into two arcs.
|
||||||
|
* @param length length first arc.
|
||||||
|
* @param arc1 first arc.
|
||||||
|
* @param arc2 second arc.
|
||||||
|
* @return point cutting
|
||||||
|
*/
|
||||||
|
QPointF VEllipticalArc::CutArc(const qreal &length, VEllipticalArc &arc1, VEllipticalArc &arc2) const
|
||||||
|
{
|
||||||
|
//Always need return two arcs, so we must correct wrong length.
|
||||||
|
qreal len = 0;
|
||||||
|
if (length < this->GetLength()*0.02)
|
||||||
|
{
|
||||||
|
len = this->GetLength()*0.02;
|
||||||
|
}
|
||||||
|
else if ( length > this->GetLength()*0.98)
|
||||||
|
{
|
||||||
|
len = this->GetLength()*0.98;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the first arc has given length and startAngle just like in the origin arc
|
||||||
|
arc1 = VEllipticalArc (len, QString().setNum(length), d->center, d->radius1, d->radius2,
|
||||||
|
d->formulaRadius1, d->formulaRadius2, d->f1, d->formulaF1, d->rotationAngle,
|
||||||
|
getIdObject(), getMode());
|
||||||
|
// the second arc has startAngle just like endAngle of the first arc
|
||||||
|
// and it has endAngle just like endAngle of the origin arc
|
||||||
|
arc2 = VEllipticalArc (d->center, d->radius1, d->radius2, d->formulaRadius1, d->formulaRadius2,
|
||||||
|
arc1.GetEndAngle(), arc1.GetFormulaF2(), d->f2, d->formulaF2, d->rotationAngle,
|
||||||
|
getIdObject(), getMode());
|
||||||
|
return arc1.GetP1();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
QPointF VEllipticalArc::CutArc(const qreal &length) const
|
||||||
|
{
|
||||||
|
VEllipticalArc arc1;
|
||||||
|
VEllipticalArc arc2;
|
||||||
|
return this->CutArc(length, arc1, arc2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief setId keep id arc in data.
|
||||||
|
* @param id id arc in data.
|
||||||
|
*/
|
||||||
|
void VEllipticalArc::setId(const quint32 &id)
|
||||||
|
{
|
||||||
|
VAbstractCurve::setId(id);
|
||||||
|
CreateName();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VEllipticalArc::CreateName()
|
||||||
|
{
|
||||||
|
QString name = EARC_ + QString("%1").arg(this->GetCenter().name());
|
||||||
|
|
||||||
|
if (VAbstractCurve::id() != NULL_ID)
|
||||||
|
{
|
||||||
|
name += QString("_%1").arg(VAbstractCurve::id());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetDuplicate() > 0)
|
||||||
|
{
|
||||||
|
name += QString("_%1").arg(GetDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
setName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VEllipticalArc::FindF2(qreal length)
|
||||||
|
{
|
||||||
|
qreal gap = 180;
|
||||||
|
if (length < 0)
|
||||||
|
{
|
||||||
|
d->isFlipped = true;
|
||||||
|
gap = -gap;
|
||||||
|
}
|
||||||
|
while (length > MaxLength())
|
||||||
|
{
|
||||||
|
length = length - MaxLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to calculate the second angle
|
||||||
|
// first approximation of angle between start and end angles
|
||||||
|
|
||||||
|
qreal endAngle = GetStartAngle() + gap;
|
||||||
|
d->f2 = endAngle; // we need to set the end anngle, because we want to use GetLength()
|
||||||
|
|
||||||
|
qreal lenBez = GetLength(); // first approximation of length
|
||||||
|
|
||||||
|
qreal eps = 0.001 * qAbs(length);
|
||||||
|
|
||||||
|
while (qAbs(lenBez - length) > eps)
|
||||||
|
{
|
||||||
|
gap = gap/2;
|
||||||
|
if (lenBez > length)
|
||||||
|
{ // we selected too big end angle
|
||||||
|
endAngle = endAngle - qAbs(gap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // we selected too little end angle
|
||||||
|
endAngle = endAngle + qAbs(gap);
|
||||||
|
}
|
||||||
|
// we need to set d->f2, because we use it when we calculate GetLength
|
||||||
|
d->f2 = endAngle;
|
||||||
|
lenBez = GetLength();
|
||||||
|
}
|
||||||
|
d->formulaF2 = QString().number(d->f2);
|
||||||
|
d->formulaLength = QString().number(qApp->fromPixel(lenBez));
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
qreal VEllipticalArc::MaxLength() const
|
||||||
|
{
|
||||||
|
const qreal h = ((d->radius1-d->radius2)*(d->radius1-d->radius2))/((d->radius1+d->radius2)*(d->radius1+d->radius2));
|
||||||
|
const qreal ellipseLength = M_PI*(d->radius1+d->radius2)*(1+3*h/(10+qSqrt(4-3*h)));
|
||||||
|
return ellipseLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetF1 return start angle.
|
||||||
|
* @return angle in degree.
|
||||||
|
*/
|
||||||
|
QString VEllipticalArc::GetFormulaF1() const
|
||||||
|
{
|
||||||
|
return d->formulaF1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VEllipticalArc::SetFormulaF1(const QString &formula, qreal value)
|
||||||
|
{
|
||||||
|
d->formulaF1 = formula;
|
||||||
|
d->f1 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetF1 return formula for start angle.
|
||||||
|
* @return string with formula.
|
||||||
|
*/
|
||||||
|
qreal VEllipticalArc::GetStartAngle() const
|
||||||
|
{
|
||||||
|
return d->f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetF2 return end angle.
|
||||||
|
* @return angle in degree.
|
||||||
|
*/
|
||||||
|
QString VEllipticalArc::GetFormulaF2() const
|
||||||
|
{
|
||||||
|
return d->formulaF2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VEllipticalArc::SetFormulaF2(const QString &formula, qreal value)
|
||||||
|
{
|
||||||
|
d->formulaF2 = formula;
|
||||||
|
d->f2 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetF2 return formula for end angle.
|
||||||
|
* @return string with formula.
|
||||||
|
*/
|
||||||
|
qreal VEllipticalArc::GetEndAngle() const
|
||||||
|
{
|
||||||
|
return d->f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetRadius return arc major radius.
|
||||||
|
* @return radius.
|
||||||
|
*/
|
||||||
|
QString VEllipticalArc::GetFormulaRadius1() const
|
||||||
|
{
|
||||||
|
return d->formulaRadius1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetRadius return arc minor radius.
|
||||||
|
* @return radius.
|
||||||
|
*/
|
||||||
|
QString VEllipticalArc::GetFormulaRadius2() const
|
||||||
|
{
|
||||||
|
return d->formulaRadius2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetRotationAngle return rotation angle.
|
||||||
|
* @return rotationAngle.
|
||||||
|
*/
|
||||||
|
qreal VEllipticalArc::GetRotationAngle() const
|
||||||
|
{
|
||||||
|
return d->rotationAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VEllipticalArc::SetFormulaRadius1(const QString &formula, qreal value)
|
||||||
|
{
|
||||||
|
d->formulaRadius1 = formula;
|
||||||
|
d->radius1 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VEllipticalArc::SetFormulaRadius2(const QString &formula, qreal value)
|
||||||
|
{
|
||||||
|
d->formulaRadius2 = formula;
|
||||||
|
d->radius2 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetRadius return formula for major radius.
|
||||||
|
* @return string with formula.
|
||||||
|
*/
|
||||||
|
qreal VEllipticalArc::GetRadius1() const
|
||||||
|
{
|
||||||
|
return d->radius1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetRadius return formula for minor radius.
|
||||||
|
* @return string with formula.
|
||||||
|
*/
|
||||||
|
qreal VEllipticalArc::GetRadius2() const
|
||||||
|
{
|
||||||
|
return d->radius2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief GetCenter return center point.
|
||||||
|
* @return center point.
|
||||||
|
*/
|
||||||
|
VPointF VEllipticalArc::GetCenter() const
|
||||||
|
{
|
||||||
|
return d->center;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VEllipticalArc::SetCenter(const VPointF &value)
|
||||||
|
{
|
||||||
|
d->center = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
QString VEllipticalArc::GetFormulaLength() const
|
||||||
|
{
|
||||||
|
return d->formulaLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VEllipticalArc::SetFormulaLength(const QString &formula, qreal value)
|
||||||
|
{
|
||||||
|
d->formulaLength = formula;
|
||||||
|
FindF2(value);
|
||||||
|
}
|
107
src/libs/vgeometry/vellipticalarc.h
Normal file
107
src/libs/vgeometry/vellipticalarc.h
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file vellipticalarc.h
|
||||||
|
** @author Valentina Zhuravska <zhuravska19(at)gmail.com>
|
||||||
|
** @date February 1, 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) 2013-2015 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 VELLIPTICALARC_H
|
||||||
|
#define VELLIPTICALARC_H
|
||||||
|
|
||||||
|
#include "vabstractcurve.h"
|
||||||
|
#include "vpointf.h"
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
class VEllipticalArcData;
|
||||||
|
|
||||||
|
class VEllipticalArc : public VAbstractCurve
|
||||||
|
{
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(VEllipticalArc)
|
||||||
|
public:
|
||||||
|
VEllipticalArc();
|
||||||
|
VEllipticalArc (VPointF center, qreal radius1, qreal radius2, QString formulaRadius1, QString formulaRadius2,
|
||||||
|
qreal f1, QString formulaF1, qreal f2, QString formulaF2, qreal rotationAngle,
|
||||||
|
quint32 idObject = 0, Draw mode = Draw::Calculation);
|
||||||
|
|
||||||
|
VEllipticalArc (VPointF center, qreal radius1, qreal radius2, qreal f1, qreal f2, qreal rotationAngle);
|
||||||
|
|
||||||
|
VEllipticalArc (qreal length, QString formulaLength, VPointF center, qreal radius1, qreal radius2,
|
||||||
|
QString formulaRadius1, QString formulaRadius2, qreal f1, QString formulaF1,
|
||||||
|
qreal rotationAngle, quint32 idObject = 0, Draw mode = Draw::Calculation);
|
||||||
|
|
||||||
|
VEllipticalArc (qreal length, VPointF center, qreal radius1, qreal radius2, qreal f1, qreal rotationAngle);
|
||||||
|
|
||||||
|
VEllipticalArc(const VEllipticalArc &arc);
|
||||||
|
|
||||||
|
VEllipticalArc& operator= (const VEllipticalArc &arc);
|
||||||
|
|
||||||
|
virtual ~VEllipticalArc() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
QString GetFormulaF1 () const;
|
||||||
|
void SetFormulaF1 (const QString &formula, qreal value);
|
||||||
|
virtual qreal GetStartAngle () const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
QString GetFormulaF2 () const;
|
||||||
|
void SetFormulaF2 (const QString &formula, qreal value);
|
||||||
|
virtual qreal GetEndAngle () const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
qreal GetRotationAngle() const;
|
||||||
|
|
||||||
|
QString GetFormulaRadius1 () const;
|
||||||
|
void SetFormulaRadius1 (const QString &formula, qreal value);
|
||||||
|
qreal GetRadius1 () const;
|
||||||
|
|
||||||
|
QString GetFormulaRadius2 () const;
|
||||||
|
void SetFormulaRadius2 (const QString &formula, qreal value);
|
||||||
|
qreal GetRadius2 () const;
|
||||||
|
|
||||||
|
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;
|
||||||
|
QVector<qreal> GetAngles () const;
|
||||||
|
QVector<QPointF> GetPoints () const;
|
||||||
|
QPointF CutArc (const qreal &length, VEllipticalArc &arc1, VEllipticalArc &arc2) const;
|
||||||
|
QPointF CutArc (const qreal &length) const;
|
||||||
|
virtual void setId(const quint32 &id) Q_DECL_OVERRIDE;
|
||||||
|
protected:
|
||||||
|
virtual void CreateName() Q_DECL_OVERRIDE;
|
||||||
|
private:
|
||||||
|
QSharedDataPointer<VEllipticalArcData> d;
|
||||||
|
void FindF2(qreal length);
|
||||||
|
|
||||||
|
qreal MaxLength() const;
|
||||||
|
QPointF GetPoint (qreal angle) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_TYPEINFO(VEllipticalArc, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
|
#endif // VELLIPTICALARC_H
|
90
src/libs/vgeometry/vellipticalarc_p.h
Normal file
90
src/libs/vgeometry/vellipticalarc_p.h
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#ifndef VELLIPTICALARC_P
|
||||||
|
#define VELLIPTICALARC_P
|
||||||
|
|
||||||
|
#include <QSharedData>
|
||||||
|
#include "../vmisc/vabstractapplication.h"
|
||||||
|
#include "vpointf.h"
|
||||||
|
|
||||||
|
class VEllipticalArcData : public QSharedData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
VEllipticalArcData ()
|
||||||
|
: f1(0), f2(0), formulaF1(QString()), formulaF2(QString()),
|
||||||
|
radius1(0), radius2(0), formulaRadius1(QString()), formulaRadius2(QString()),
|
||||||
|
center(VPointF()), isFlipped(false), formulaLength(), rotationAngle(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
VEllipticalArcData (VPointF center, qreal radius1, qreal radius2, QString formulaRadius1, QString formulaRadius2,
|
||||||
|
qreal f1, QString formulaF1, qreal f2, QString formulaF2, qreal rotationAngle)
|
||||||
|
: f1(f1), f2(f2), formulaF1(formulaF1), formulaF2(formulaF2),
|
||||||
|
radius1(radius1), radius2(radius2), formulaRadius1(formulaRadius1), formulaRadius2(formulaRadius2),
|
||||||
|
center(center), isFlipped(false), formulaLength(), rotationAngle(rotationAngle)
|
||||||
|
{}
|
||||||
|
|
||||||
|
VEllipticalArcData(VPointF center, qreal radius1, qreal radius2, qreal f1, qreal f2, qreal rotationAngle)
|
||||||
|
: f1(f1), f2(f2), formulaF1(QString().number(f1)),
|
||||||
|
formulaF2(QString().number(f2)), radius1(radius1), radius2(radius2),
|
||||||
|
formulaRadius1(QString().number(qApp->fromPixel(radius1))),
|
||||||
|
formulaRadius2(QString().number(qApp->fromPixel(radius2))),
|
||||||
|
center(center), isFlipped(false), formulaLength(), rotationAngle(rotationAngle)
|
||||||
|
{}
|
||||||
|
|
||||||
|
VEllipticalArcData (QString formulaLength, VPointF center, qreal radius1, qreal radius2,
|
||||||
|
QString formulaRadius1, QString formulaRadius2, qreal f1, QString formulaF1,
|
||||||
|
qreal rotationAngle)
|
||||||
|
: f1(f1), f2(0), formulaF1(formulaF1), formulaF2("0"), radius1(radius1),radius2(radius2),
|
||||||
|
formulaRadius1(formulaRadius1), formulaRadius2(formulaRadius2),
|
||||||
|
center(center), isFlipped(false), formulaLength(formulaLength), rotationAngle(rotationAngle)
|
||||||
|
{}
|
||||||
|
|
||||||
|
VEllipticalArcData(VPointF center, qreal radius1, qreal radius2, qreal f1, qreal rotationAngle)
|
||||||
|
: f1(f1), f2(0), formulaF1(QString().number(f1)), formulaF2("0"),
|
||||||
|
radius1(radius1), radius2(radius2),
|
||||||
|
formulaRadius1(QString().number(qApp->fromPixel(radius1))),
|
||||||
|
formulaRadius2(QString().number(qApp->fromPixel(radius2))),
|
||||||
|
center(center), isFlipped(false), formulaLength(), rotationAngle(rotationAngle)
|
||||||
|
{}
|
||||||
|
|
||||||
|
VEllipticalArcData(const VEllipticalArcData &arc)
|
||||||
|
: QSharedData(arc), f1(arc.f1), f2(arc.f2), formulaF1(arc.formulaF1), formulaF2(arc.formulaF2),
|
||||||
|
radius1(arc.radius1), radius2(arc.radius2),
|
||||||
|
formulaRadius1(arc.formulaRadius1), formulaRadius2(arc.formulaRadius2),
|
||||||
|
center(arc.center), isFlipped(arc.isFlipped), formulaLength(arc.formulaLength),
|
||||||
|
rotationAngle(arc.rotationAngle)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual ~VEllipticalArcData();
|
||||||
|
|
||||||
|
/** @brief f1 start angle in degree. */
|
||||||
|
qreal f1;
|
||||||
|
/** @brief f2 end angle in degree. */
|
||||||
|
qreal f2;
|
||||||
|
/** @brief formulaF1 formula for start angle. */
|
||||||
|
QString formulaF1;
|
||||||
|
/** @brief formulaF2 formula for end angle. */
|
||||||
|
QString formulaF2;
|
||||||
|
/** @brief radius1 elliptical arc major radius. */
|
||||||
|
qreal radius1;
|
||||||
|
/** @brief radius2 elliptical arc minor radius. */
|
||||||
|
qreal radius2;
|
||||||
|
/** @brief formulaRadius1 formula for elliptical arc major radius. */
|
||||||
|
QString formulaRadius1;
|
||||||
|
/** @brief formulaRadius2 formula for elliptical arc minor radius. */
|
||||||
|
QString formulaRadius2;
|
||||||
|
/** @brief center center point of arc. */
|
||||||
|
VPointF center;
|
||||||
|
bool isFlipped;
|
||||||
|
QString formulaLength;
|
||||||
|
/** @brief rotationAngle in degree. */
|
||||||
|
qreal rotationAngle;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VEllipticalArcData &operator=(const VEllipticalArcData &) Q_DECL_EQ_DELETE;
|
||||||
|
};
|
||||||
|
|
||||||
|
VEllipticalArcData::~VEllipticalArcData()
|
||||||
|
{}
|
||||||
|
|
||||||
|
#endif // VELLIPTICALARC_P
|
||||||
|
|
|
@ -8,7 +8,8 @@ SOURCES += \
|
||||||
$$PWD/vpointf.cpp \
|
$$PWD/vpointf.cpp \
|
||||||
$$PWD/vspline.cpp \
|
$$PWD/vspline.cpp \
|
||||||
$$PWD/vsplinepath.cpp \
|
$$PWD/vsplinepath.cpp \
|
||||||
$$PWD/vsplinepoint.cpp
|
$$PWD/vsplinepoint.cpp \
|
||||||
|
$$PWD/vellipticalarc.cpp
|
||||||
|
|
||||||
win32-msvc*:SOURCES += $$PWD/stable.cpp
|
win32-msvc*:SOURCES += $$PWD/stable.cpp
|
||||||
|
|
||||||
|
@ -28,4 +29,6 @@ HEADERS += \
|
||||||
$$PWD/vsplinepoint.h \
|
$$PWD/vsplinepoint.h \
|
||||||
$$PWD/vsplinepoint_p.h \
|
$$PWD/vsplinepoint_p.h \
|
||||||
$$PWD/vgeometrydef.h \
|
$$PWD/vgeometrydef.h \
|
||||||
|
$$PWD/vellipticalarc.h \
|
||||||
|
$$PWD/vellipticalarc_p.h \
|
||||||
$$PWD/vabstractcurve_p.h
|
$$PWD/vabstractcurve_p.h
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
# File with common stuff for whole project
|
# File with common stuff for whole project
|
||||||
include(../../../common.pri)
|
include(../../../common.pri)
|
||||||
|
|
||||||
|
QT += widgets
|
||||||
|
|
||||||
# Name of library
|
# Name of library
|
||||||
TARGET = vgeometry
|
TARGET = vgeometry
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
enum class Draw : char { Calculation, Modeling, Layout };
|
enum class Draw : char { Calculation, Modeling, Layout };
|
||||||
enum class GOType : char { Point, Arc, Spline, SplinePath, Unknown };
|
enum class GOType : char { Point, Arc, EllipticalArc, Spline, SplinePath, Unknown };
|
||||||
enum class SplinePointPosition : char { FirstPoint, LastPoint };
|
enum class SplinePointPosition : char { FirstPoint, LastPoint };
|
||||||
|
|
||||||
#endif // VGEOMETRYDEF_H
|
#endif // VGEOMETRYDEF_H
|
||||||
|
|
|
@ -54,7 +54,8 @@ SOURCES += \
|
||||||
tst_vcommandline.cpp \
|
tst_vcommandline.cpp \
|
||||||
tst_tstranslation.cpp \
|
tst_tstranslation.cpp \
|
||||||
tst_vdetail.cpp \
|
tst_vdetail.cpp \
|
||||||
tst_findpoint.cpp
|
tst_findpoint.cpp \
|
||||||
|
tst_vellipticalarc.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
tst_vposter.h \
|
tst_vposter.h \
|
||||||
|
@ -76,7 +77,8 @@ HEADERS += \
|
||||||
tst_vcommandline.h \
|
tst_vcommandline.h \
|
||||||
tst_tstranslation.h \
|
tst_tstranslation.h \
|
||||||
tst_vdetail.h \
|
tst_vdetail.h \
|
||||||
tst_findpoint.h
|
tst_findpoint.h \
|
||||||
|
tst_vellipticalarc.h
|
||||||
|
|
||||||
# Set using ccache. Function enable_ccache() defined in common.pri.
|
# Set using ccache. Function enable_ccache() defined in common.pri.
|
||||||
$$enable_ccache()
|
$$enable_ccache()
|
||||||
|
|
|
@ -46,7 +46,7 @@ class AbstractTest : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit AbstractTest(QObject *parent = 0);
|
explicit AbstractTest(QObject *parent = nullptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Comparison(const QVector<QPointF> &ekv, const QVector<QPointF> &ekvOrig) const;
|
void Comparison(const QVector<QPointF> &ekv, const QVector<QPointF> &ekvOrig) const;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "tst_nameregexp.h"
|
#include "tst_nameregexp.h"
|
||||||
#include "tst_vlayoutdetail.h"
|
#include "tst_vlayoutdetail.h"
|
||||||
#include "tst_varc.h"
|
#include "tst_varc.h"
|
||||||
|
#include "tst_vellipticalarc.h"
|
||||||
#include "tst_measurementregexp.h"
|
#include "tst_measurementregexp.h"
|
||||||
#include "tst_tapecommandline.h"
|
#include "tst_tapecommandline.h"
|
||||||
#include "tst_valentinacommandline.h"
|
#include "tst_valentinacommandline.h"
|
||||||
|
@ -68,6 +69,7 @@ int main(int argc, char** argv)
|
||||||
ASSERT_TEST(new TST_NameRegExp());
|
ASSERT_TEST(new TST_NameRegExp());
|
||||||
ASSERT_TEST(new TST_VLayoutDetail());
|
ASSERT_TEST(new TST_VLayoutDetail());
|
||||||
ASSERT_TEST(new TST_VArc());
|
ASSERT_TEST(new TST_VArc());
|
||||||
|
ASSERT_TEST(new TST_VEllipticalArc());
|
||||||
ASSERT_TEST(new TST_MeasurementRegExp());
|
ASSERT_TEST(new TST_MeasurementRegExp());
|
||||||
ASSERT_TEST(new TST_TapeCommandLine());
|
ASSERT_TEST(new TST_TapeCommandLine());
|
||||||
ASSERT_TEST(new TST_ValentinaCommandLine());
|
ASSERT_TEST(new TST_ValentinaCommandLine());
|
||||||
|
|
|
@ -40,7 +40,7 @@ class TST_MeasurementRegExp : public AbstractTest
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TST_MeasurementRegExp(QObject *parent = 0);
|
explicit TST_MeasurementRegExp(QObject *parent = nullptr);
|
||||||
virtual ~TST_MeasurementRegExp() Q_DECL_OVERRIDE;
|
virtual ~TST_MeasurementRegExp() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -35,7 +35,7 @@ class TST_NameRegExp : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TST_NameRegExp(QObject *parent = 0);
|
explicit TST_NameRegExp(QObject *parent = nullptr);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ class TST_QmuTokenParser : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Q_DISABLE_COPY(TST_QmuTokenParser)
|
Q_DISABLE_COPY(TST_QmuTokenParser)
|
||||||
explicit TST_QmuTokenParser(QObject *parent = 0);
|
explicit TST_QmuTokenParser(QObject *parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void IsSingle_data();
|
void IsSingle_data();
|
||||||
|
|
|
@ -35,7 +35,7 @@ class TST_TapeCommandLine : public AbstractTest
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TST_TapeCommandLine(QObject *parent = 0);
|
explicit TST_TapeCommandLine(QObject *parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void init();
|
void init();
|
||||||
|
|
|
@ -38,7 +38,7 @@ class TST_TSTranslation : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TST_TSTranslation(QObject *parent = 0);
|
explicit TST_TSTranslation(QObject *parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void CheckEnglishLocalization();
|
void CheckEnglishLocalization();
|
||||||
|
|
|
@ -35,7 +35,7 @@ class TST_VAbstractDetail : public AbstractTest
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TST_VAbstractDetail(QObject *parent = 0);
|
explicit TST_VAbstractDetail(QObject *parent = nullptr);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ class TST_ValentinaCommandLine : public AbstractTest
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TST_ValentinaCommandLine(QObject *parent = 0);
|
explicit TST_ValentinaCommandLine(QObject *parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void init();
|
void init();
|
||||||
|
|
|
@ -190,19 +190,19 @@ void TST_VArc::TestGetPoints()
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
qreal gSquere = 0.0;// geometry squere
|
qreal gSquere = 0.0;// geometry square
|
||||||
|
|
||||||
if (qFuzzyCompare(arc.AngleArc(), 360.0))
|
if (qFuzzyCompare(arc.AngleArc(), 360.0))
|
||||||
{// circle squere
|
{// circle square
|
||||||
gSquere = M_PI * radius * radius;
|
gSquere = M_PI * radius * radius;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{// sector squere
|
{// sector square
|
||||||
gSquere = (M_PI * radius * radius) / 360.0 * arc.AngleArc();
|
gSquere = (M_PI * radius * radius) / 360.0 * arc.AngleArc();
|
||||||
points.append(center.toQPointF());
|
points.append(center.toQPointF());
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculated squere
|
// calculated square
|
||||||
const qreal cSquare = qAbs(VAbstractDetail::SumTrapezoids(points)/2.0);
|
const qreal cSquare = qAbs(VAbstractDetail::SumTrapezoids(points)/2.0);
|
||||||
const qreal value = qAbs(gSquere - cSquare);
|
const qreal value = qAbs(gSquere - cSquare);
|
||||||
const QString errorMsg =
|
const QString errorMsg =
|
||||||
|
|
|
@ -35,7 +35,7 @@ class TST_VArc : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TST_VArc(QObject *parent = 0);
|
explicit TST_VArc(QObject *parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void CompareTwoWays();
|
void CompareTwoWays();
|
||||||
|
|
375
src/test/ValentinaTest/tst_vellipticalarc.cpp
Normal file
375
src/test/ValentinaTest/tst_vellipticalarc.cpp
Normal file
|
@ -0,0 +1,375 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file tst_vellipticalarc.cpp
|
||||||
|
** @author Valentina Zhuravska <zhuravska19(at)gmail.com>
|
||||||
|
** @date 12 2, 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) 2015 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_vellipticalarc.h"
|
||||||
|
#include "../vgeometry/vellipticalarc.h"
|
||||||
|
#include "../vlayout/vabstractdetail.h"
|
||||||
|
|
||||||
|
#include <QtTest>
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
TST_VEllipticalArc::TST_VEllipticalArc(QObject *parent) : QObject(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
// cppcheck-suppress unusedFunction
|
||||||
|
void TST_VEllipticalArc::CompareTwoWays()
|
||||||
|
{
|
||||||
|
const VPointF center;
|
||||||
|
const qreal radius1 = 100;
|
||||||
|
const qreal radius2 = 200;
|
||||||
|
const qreal f1 = 0;
|
||||||
|
const qreal f2 = 90;
|
||||||
|
const qreal rotationAngle = 0;
|
||||||
|
|
||||||
|
const qreal h = ((radius1-radius2)*(radius1-radius2))/((radius1+radius2)*(radius1+radius2));
|
||||||
|
const qreal length = M_PI*(radius1+radius2)*(1+3*h/(10+qSqrt(4-3*h)))/4;
|
||||||
|
|
||||||
|
VEllipticalArc arc1(center, radius1, radius2, f1, f2, rotationAngle);
|
||||||
|
VEllipticalArc arc2(length, center, radius1, radius2, f1, rotationAngle);
|
||||||
|
|
||||||
|
const qreal eps = length*0.5/100; // computing error
|
||||||
|
const QString errorMsg =
|
||||||
|
QString("Difference between real and computing lengthes bigger than eps = %1.").number(eps);
|
||||||
|
QVERIFY2(qAbs(arc1.GetLength() - length) <= eps, qUtf8Printable(errorMsg));
|
||||||
|
QVERIFY2(qAbs(arc2.GetLength() - length) <= eps, qUtf8Printable(errorMsg));
|
||||||
|
QVERIFY2(qAbs(arc1.GetLength() - arc2.GetLength()) <= eps, qUtf8Printable(errorMsg));
|
||||||
|
|
||||||
|
// compare angles
|
||||||
|
QVERIFY2(qAbs(arc1.GetEndAngle() - arc2.GetEndAngle()) <= eps, qUtf8Printable(errorMsg));
|
||||||
|
QVERIFY2(qAbs(arc1.GetEndAngle() - f2) <= eps, qUtf8Printable(errorMsg));
|
||||||
|
QVERIFY2(qAbs(arc1.GetEndAngle() - f2) <= eps, qUtf8Printable(errorMsg));
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
// cppcheck-suppress unusedFunction
|
||||||
|
void TST_VEllipticalArc::NegativeArc()
|
||||||
|
{
|
||||||
|
const VPointF center;
|
||||||
|
const qreal radius1 = 100;
|
||||||
|
const qreal radius2 = 200;
|
||||||
|
const qreal f1 = 1;
|
||||||
|
const qreal f2 = 181;
|
||||||
|
const qreal rotationAngle = 0;
|
||||||
|
|
||||||
|
const qreal h = ((radius1-radius2)*(radius1-radius2))/((radius1+radius2)*(radius1+radius2));
|
||||||
|
const qreal length = M_PI*(radius1+radius2)*(1+3*h/(10+qSqrt(4-3*h)))/2;
|
||||||
|
qreal l = -length;
|
||||||
|
VEllipticalArc arc(l, center, radius1, radius2, f1, rotationAngle);
|
||||||
|
|
||||||
|
const qreal eps = 1; // computing error
|
||||||
|
const QString errorMsg =
|
||||||
|
QString("Difference between real and computing lengthes bigger than eps = %1.").number(eps);
|
||||||
|
|
||||||
|
QVERIFY2(qAbs(arc.GetLength() + length) <= eps, qUtf8Printable(errorMsg));
|
||||||
|
QVERIFY2(arc.GetEndAngle() - f2 <= eps, qUtf8Printable(errorMsg));
|
||||||
|
}
|
||||||
|
|
||||||
|
// cppcheck-suppress unusedFunction
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void TST_VEllipticalArc::TestGetPoints1_data()
|
||||||
|
{
|
||||||
|
TestData();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void TST_VEllipticalArc::TestGetPoints2_data()
|
||||||
|
{
|
||||||
|
TestData();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void TST_VEllipticalArc::TestGetPoints3_data()
|
||||||
|
{
|
||||||
|
TestData();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void TST_VEllipticalArc::TestGetPoints4_data()
|
||||||
|
{
|
||||||
|
TestData();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void TST_VEllipticalArc::TestData()
|
||||||
|
{
|
||||||
|
QTest::addColumn<qreal>("radius1");
|
||||||
|
QTest::addColumn<qreal>("radius2");
|
||||||
|
QTest::addColumn<qreal>("startAngle");
|
||||||
|
QTest::addColumn<qreal>("endAngle");
|
||||||
|
QTest::addColumn<qreal>("rotationAngle");
|
||||||
|
|
||||||
|
QTest::newRow("Full circle: radiuses 10, 20") << 10.0 << 20.0 << 0.0 << 360.0 << 0.0;
|
||||||
|
QTest::newRow("Full circle: radiuses 150, 200") << 150.0 << 200.0 << 0.0 << 360.0 << 0.0;
|
||||||
|
QTest::newRow("Full circle: radiuses 150, 200, rotation 30") << 150.0 << 200.0 << 0.0 << 360.0 << 30.0;
|
||||||
|
QTest::newRow("Full circle: radiuses 1500, 1000") << 1500.0 << 1000.0 << 0.0 << 360.0 << 0.0;
|
||||||
|
QTest::newRow("Full circle: radiuses 1500, 1000, rotation 50") << 1500.0 << 1000.0 << 0.0 << 360.0 << 50.0;
|
||||||
|
QTest::newRow("Full circle: radiuses 90000, 80000, rotation 90") << 90000.0 << 80000.0 << 0.0 << 360.0 << 90.0;
|
||||||
|
|
||||||
|
QTest::newRow("Arc less than 45 degree, radiuses 100, 50") << 100.0 << 50.0 << 0.0 << 10.5 << 0.0;
|
||||||
|
QTest::newRow("Arc less than 45 degree, radiuses 150, 50, rotation 180") << 150.0 << 50.0 << 0.0 << 10.5 << 180.0;
|
||||||
|
QTest::newRow("Arc less than 45 degree, radiuses 1500, 800, rotation 90") << 1500.0 << 800.0 << 0.0 << 10.5 << 90.0;
|
||||||
|
QTest::newRow("Arc less than 45 degree, radiuses 50000, 10000, rotation 40")
|
||||||
|
<< 50000.0 << 10000.0 << 0.0 << 10.5 << 40.0;
|
||||||
|
QTest::newRow("Arc less than 45 degree, radiuses 90000, 10000") << 90000.0 << 10000.0 << 0.0 << 10.5 << 0.0;
|
||||||
|
|
||||||
|
QTest::newRow("Arc 45 degree, radiuses 100, 50, rotation 45") << 100.0 << 50.0 << 0.0 << 45.0 << 45.0;
|
||||||
|
QTest::newRow("Arc 45 degree, radiuses 150, 15, rotation 30") << 150.0 << 15.0 << 0.0 << 45.0 << 30.0;
|
||||||
|
QTest::newRow("Arc 45 degree, radiuses 1500, 150, rotation 45") << 1500.0 << 150.0 << 0.0 << 45.0 << 45.0;
|
||||||
|
QTest::newRow("Arc 45 degree, radiuses 50000, 50000") << 50000.0 << 50000.0 << 0.0 << 45.0 << 0.0;
|
||||||
|
QTest::newRow("Arc 45 degree, radiuses 90000, 50000, rotation 270") << 90000.0 << 50000.0 << 0.0 << 45.0 << 270.0;
|
||||||
|
|
||||||
|
QTest::newRow("Arc less than 90 degree, radiuses 100, 400, rotation 50") << 100.0 << 400.0 << 0.0 << 75.0 << 50.0;
|
||||||
|
QTest::newRow("Arc less than 90 degree, radiuses 150, 400, rotation 90") << 150.0 << 400.0 << 0.0 << 75.0 << 90.0;
|
||||||
|
QTest::newRow("Arc less than 90 degree, radiuses 1500, 50000, rotation 180")
|
||||||
|
<< 1500.0 << 50000.0 << 0.0 << 75.0 << 180.0;
|
||||||
|
QTest::newRow("Arc less than 90 degree, radiuses 50000, 5000, rotation 30")
|
||||||
|
<< 50000.0 << 5000.0 << 0.0 << 75.0 << 30.0;
|
||||||
|
QTest::newRow("Arc less than 90 degree, radiuses 90000, 50000, rotation 30")
|
||||||
|
<< 90000.0 << 50000.0 << 0.0 << 75.0 << 30.0;
|
||||||
|
|
||||||
|
QTest::newRow("Arc 90 degree, radiuses 100, 50, rotation 30") << 100.0 << 50.0 << 0.0 << 90.0 << 30.0;
|
||||||
|
QTest::newRow("Arc 90 degree, radiuses 150, 400") << 150.0 << 400.0 << 0.0 << 90.0 << 0.0;
|
||||||
|
QTest::newRow("Arc 90 degree, radiuses 1500, 800, rotation 70") << 1500.0 << 800.0 << 0.0 << 90.0 << 70.0;
|
||||||
|
QTest::newRow("Arc 90 degree, radiuses 50000, 5000, rotation 30") << 50000.0 << 5000.0 << 0.0 << 90.0 << 30.0;
|
||||||
|
QTest::newRow("Arc 90 degree, radiuses 90000, 50000, rotation 235") << 90000.0 << 50000.0 << 0.0 << 90.0 << 235.0;
|
||||||
|
|
||||||
|
QTest::newRow("Arc less than 135 degree, radiuses 100, 50, rotation 60") << 100.0 << 50.0 << 0.0 << 110.6 << 60.0;
|
||||||
|
QTest::newRow("Arc less than 135 degree, radiuses 150, 400, rotation 300")
|
||||||
|
<< 150.0 << 400.0 << 0.0 << 110.6 << 300.0;
|
||||||
|
QTest::newRow("Arc less than 135 degree, radiuses 1500, 800, rotation 360")
|
||||||
|
<< 1500.0 << 800.0 << 0.0 << 110.6 << 360.0;
|
||||||
|
QTest::newRow("Arc less than 135 degree, radiuses 50000, 5000, rotation 290")
|
||||||
|
<< 50000.0 << 5000.0 << 0.0 << 110.6 << 290.0;
|
||||||
|
QTest::newRow("Arc less than 135 degree, radiuses 90000, 50000") << 90000.0 << 50000.0 << 0.0 << 110.6 << 0.0;
|
||||||
|
|
||||||
|
QTest::newRow("Arc 135 degree, radiuses 100, 50") << 100.0 << 50.0 << 0.0 << 135.0 << 0.0;
|
||||||
|
QTest::newRow("Arc 135 degree, radiuses 150, 400") << 150.0 << 400.0 << 0.0 << 135.0 << 0.0;
|
||||||
|
QTest::newRow("Arc 135 degree, radiuses 1500, 800") << 1500.0 << 800.0 << 0.0 << 135.0 << 0.0;
|
||||||
|
QTest::newRow("Arc 135 degree, radiuses 50000, 5000, rotation 20") << 50000.0 << 5000.0 << 0.0 << 135.0 << 20.0;
|
||||||
|
QTest::newRow("Arc 135 degree, radiuses 90000, 50000") << 90000.0 << 50000.0 << 0.0 << 135.0 << 0.0;
|
||||||
|
|
||||||
|
QTest::newRow("Arc less than 180 degree, radiuses 100, 50") << 100.0 << 50.0 << 0.0 << 160.7 << 0.0;
|
||||||
|
QTest::newRow("Arc less than 180 degree, radiuses 150, 400") << 150.0 << 400.0 << 0.0 << 160.7 << 0.0;
|
||||||
|
QTest::newRow("Arc less than 180 degree, radiuses 1500, 800") << 1500.0 << 800.0 << 0.0 << 160.7 << 0.0;
|
||||||
|
QTest::newRow("Arc less than 180 degree, radiuses 50000, 5000, rotation 270")
|
||||||
|
<< 50000.0 << 5000.0 << 0.0 << 160.7 << 270.0;
|
||||||
|
QTest::newRow("Arc less than 180 degree, radiuses 90000, 50000") << 90000.0 << 50000.0 << 0.0 << 160.7 << 0.0;
|
||||||
|
|
||||||
|
QTest::newRow("Arc 180 degree, radiuses 100, 50") << 100.0 << 50.0 << 0.0 << 180.0 << 0.0;
|
||||||
|
QTest::newRow("Arc 180 degree, radiuses 150, 400") << 150.0 << 400.0 << 0.0 << 180.0 << 0.0;
|
||||||
|
QTest::newRow("Arc 180 degree, radiuses 1500, 800") << 1500.0 << 800.0 << 0.0 << 180.0 << 0.0;
|
||||||
|
QTest::newRow("Arc 180 degree, radiuses 50000, 5000, rotation 60") << 50000.0 << 5000.0 << 0.0 << 180.0 << 60.0;
|
||||||
|
QTest::newRow("Arc 180 degree, radiuses 90000, 50000") << 90000.0 << 50000.0 << 0.0 << 180.0 << 0.0;
|
||||||
|
|
||||||
|
QTest::newRow("Arc less than 270 degree, radiuses 100, 50") << 100.0 << 50.0 << 0.0 << 150.3 << 0.0;
|
||||||
|
QTest::newRow("Arc less than 270 degree, radiuses 150, 400") << 150.0 << 400.0 << 0.0 << 150.3 << 0.0;
|
||||||
|
QTest::newRow("Arc less than 270 degree, radiuses 1500, 800") << 1500.0 << 800.0 << 0.0 << 150.3 << 0.0;
|
||||||
|
QTest::newRow("Arc less than 270 degree, radiuses 50000, 5000, rotation 20")
|
||||||
|
<< 50000.0 << 5000.0 << 0.0 << 150.3 << 20.0;
|
||||||
|
QTest::newRow("Arc less than 270 degree, radiuses 90000, 50000") << 90000.0 << 50000.0 << 0.0 << 150.3 << 0.0;
|
||||||
|
|
||||||
|
QTest::newRow("Arc 270 degree, radiuses 100, 50") << 100.0 << 50.0 << 0.0 << 270.0 << 0.0;
|
||||||
|
QTest::newRow("Arc 270 degree, radiuses 150, 400") << 150.0 << 400.0 << 0.0 << 270.0 << 0.0;
|
||||||
|
QTest::newRow("Arc 270 degree, radiuses 1500, 800") << 1500.0 << 800.0 << 0.0 << 270.0 << 0.0;
|
||||||
|
QTest::newRow("Arc 270 degree, radiuses 50000, 5000, rotation 90") << 50000.0 << 5000.0 << 0.0 << 270.0 << 90.0;
|
||||||
|
QTest::newRow("Arc 270 degree, radiuses 90000, 50000") << 90000.0 << 50000.0 << 0.0 << 270.0 << 0.0;
|
||||||
|
|
||||||
|
QTest::newRow("Arc less than 360 degree, radiuses 100, 50") << 100.0 << 50.0 << 0.0 << 340.0 << 0.0;
|
||||||
|
QTest::newRow("Arc less than 360 degree, radiuses 150, 400") << 150.0 << 400.0 << 0.0 << 340.0 << 0.0;
|
||||||
|
QTest::newRow("Arc less than 360 degree, radiuses 1500, 800") << 1500.0 << 800.0 << 0.0 << 340.0 << 0.0;
|
||||||
|
QTest::newRow("Arc less than 360 degree, radiuses 50000, 5000, rotation 30")
|
||||||
|
<< 50000.0 << 5000.0 << 0.0 << 340.0 << 30.0;
|
||||||
|
QTest::newRow("Arc less than 360 degree, radiuses 90000, 50000") << 90000.0 << 50000.0 << 0.0 << 340.0 << 0.0;
|
||||||
|
|
||||||
|
QTest::newRow("Arc start 90 degree, angle 45 degree, radiuses 100, 50") << 100.0 << 50.0 << 90.0 << 135.0 << 0.0;
|
||||||
|
QTest::newRow("Arc start 90 degree, angle 45 degree, radiuses 150, 400") << 150.0 << 400.0 << 90.0 << 135.0 << 0.0;
|
||||||
|
QTest::newRow("Arc start 90 degree, angle 45 degree, radiuses 1500, 800")
|
||||||
|
<< 1500.0 << 800.0 << 90.0 << 135.0 << 0.0;
|
||||||
|
QTest::newRow("Arc start 90 degree, angle 45 degree, radiuses 50000, 5000")
|
||||||
|
<< 50000.0 << 5000.0 << 90.0 << 135.0 << 0.0;
|
||||||
|
QTest::newRow("Arc start 90 degree, angle 45 degree, radiuses 90000, 50000")
|
||||||
|
<< 90000.0 << 50000.0 << 90.0 << 135.0 << 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
// cppcheck-suppress unusedFunction
|
||||||
|
void TST_VEllipticalArc::TestGetPoints1()
|
||||||
|
{
|
||||||
|
//Any point must satisfy the equation of ellipse
|
||||||
|
QFETCH(qreal, radius1);
|
||||||
|
QFETCH(qreal, radius2);
|
||||||
|
QFETCH(qreal, startAngle);
|
||||||
|
QFETCH(qreal, endAngle);
|
||||||
|
QFETCH(qreal, rotationAngle);
|
||||||
|
|
||||||
|
const VPointF center;
|
||||||
|
VEllipticalArc arc(center, radius1, radius2, startAngle, endAngle, rotationAngle);
|
||||||
|
|
||||||
|
QVector<QPointF> points = arc.GetPoints();
|
||||||
|
if (rotationAngle == 0.0)
|
||||||
|
{ // equation of ellipse will be different when rotation angle isn't 0 so we can't use this test in this case
|
||||||
|
qreal eps = 0.05;
|
||||||
|
|
||||||
|
for (int i=0; i < points.size(); ++i)
|
||||||
|
{
|
||||||
|
QPointF p = points.at(i);
|
||||||
|
const qreal equationRes = p.rx()*p.rx()/(radius1*radius1) + p.ry()*p.ry()/(radius2*radius2);
|
||||||
|
const qreal diff = qAbs(equationRes - 1);
|
||||||
|
const QString errorMsg = QString("Broken the first rule. Any point must satisfy the equation of ellipse."
|
||||||
|
"diff = '%1' > eps = '%2'").number(diff).number(eps);
|
||||||
|
QVERIFY2( diff <= eps, qUtf8Printable(errorMsg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
// cppcheck-suppress unusedFunction
|
||||||
|
void TST_VEllipticalArc::TestGetPoints2()
|
||||||
|
{
|
||||||
|
// Distance from the any point to the focus1 plus distance from this point to the focus2 should be the same.
|
||||||
|
QFETCH(qreal, radius1);
|
||||||
|
QFETCH(qreal, radius2);
|
||||||
|
QFETCH(qreal, startAngle);
|
||||||
|
QFETCH(qreal, endAngle);
|
||||||
|
QFETCH(qreal, rotationAngle);
|
||||||
|
|
||||||
|
const VPointF center;
|
||||||
|
VEllipticalArc arc(center, radius1, radius2, startAngle, endAngle, rotationAngle);
|
||||||
|
QVector<QPointF> points = arc.GetPoints();
|
||||||
|
|
||||||
|
const qreal c = qSqrt(qAbs(radius2*radius2 - radius1*radius1));
|
||||||
|
// distance from the center to the focus
|
||||||
|
|
||||||
|
QPointF focus1 = center.toQPointF();
|
||||||
|
QPointF focus2 = center.toQPointF();
|
||||||
|
|
||||||
|
if (radius1 < radius2)
|
||||||
|
{
|
||||||
|
focus1.setY(focus1.ry() + c);
|
||||||
|
QLineF line(center.toQPointF(), focus1);
|
||||||
|
line.setAngle(line.angle() + rotationAngle);
|
||||||
|
focus1 = line.p2();
|
||||||
|
|
||||||
|
focus2.setY(focus2.ry() - c);
|
||||||
|
line.setP2(focus2);
|
||||||
|
line.setAngle(line.angle() + rotationAngle);
|
||||||
|
focus2 = line.p2();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
focus1.setX(focus1.rx() + c);
|
||||||
|
QLineF line(center.toQPointF(), focus1);
|
||||||
|
line.setAngle(line.angle() + rotationAngle);
|
||||||
|
focus1 = line.p2();
|
||||||
|
|
||||||
|
focus2.setX(focus2.rx() - c);
|
||||||
|
line.setP2(focus2);
|
||||||
|
line.setAngle(line.angle() + rotationAngle);
|
||||||
|
focus2 = line.p2();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF ellipsePoint(center.x() + radius1, center.y());
|
||||||
|
QLineF line(center.toQPointF(), ellipsePoint);
|
||||||
|
line.setAngle(line.angle() + rotationAngle);
|
||||||
|
ellipsePoint = line.p2();
|
||||||
|
|
||||||
|
const QLineF distance1(focus1, ellipsePoint);
|
||||||
|
const QLineF distance2(focus2, ellipsePoint);
|
||||||
|
|
||||||
|
const qreal distance = distance1.length() + distance2.length();
|
||||||
|
const qreal eps = distance * 1.1 / 100; // computing error 1.1 % from origin distance
|
||||||
|
for (int i=0; i < points.size(); ++i)
|
||||||
|
{
|
||||||
|
const QLineF rLine1(focus1, points.at(i));
|
||||||
|
const QLineF rLine2(focus2, points.at(i));
|
||||||
|
const qreal resultingDistance = rLine1.length()+rLine2.length();
|
||||||
|
const qreal diff = qAbs(resultingDistance - distance);
|
||||||
|
const QString errorMsg = QString("Broken the first rule, part 2. Distance from the any point to the focus1"
|
||||||
|
" plus distance from this point to the focus2 should be the same. Problem"
|
||||||
|
" with point '%1'. The disired distance is '%2', but resulting distance"
|
||||||
|
" is '%3'. Difference is '%4' and it biggest than eps '%5')").number(i)
|
||||||
|
.number(distance).number(resultingDistance).number(diff).number(eps);
|
||||||
|
QVERIFY2( diff <= eps, qUtf8Printable(errorMsg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
// cppcheck-suppress unusedFunction
|
||||||
|
void TST_VEllipticalArc::TestGetPoints3()
|
||||||
|
{
|
||||||
|
// Compare full ellipse square with square of VAbstractDetail
|
||||||
|
QFETCH(qreal, radius1);
|
||||||
|
QFETCH(qreal, radius2);
|
||||||
|
QFETCH(qreal, startAngle);
|
||||||
|
QFETCH(qreal, endAngle);
|
||||||
|
QFETCH(qreal, rotationAngle);
|
||||||
|
|
||||||
|
const VPointF center;
|
||||||
|
VEllipticalArc arc(center, radius1, radius2, startAngle, endAngle, rotationAngle);
|
||||||
|
QVector<QPointF> points = arc.GetPoints();
|
||||||
|
|
||||||
|
if (qFuzzyCompare(arc.AngleArc(), 360.0))
|
||||||
|
{// calculated full ellipse square
|
||||||
|
const qreal ellipseSquare = M_PI * radius1 * radius2;
|
||||||
|
const qreal epsSquare = ellipseSquare * 0.5 / 100; // computing error 0.5 % from origin squere
|
||||||
|
const qreal arcSquare = qAbs(VAbstractDetail::SumTrapezoids(points)/2.0);
|
||||||
|
const qreal diffSquare = qAbs(ellipseSquare - arcSquare);
|
||||||
|
const QString errorMsg1 = QString("Broken the second rule. Interpolation has too big computing error. "
|
||||||
|
"Difference ='%1' bigger than eps = '%2'.").arg(diffSquare).arg(epsSquare);
|
||||||
|
QVERIFY2(diffSquare <= epsSquare, qUtf8Printable(errorMsg1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
// cppcheck-suppress unusedFunction
|
||||||
|
void TST_VEllipticalArc::TestGetPoints4()
|
||||||
|
{
|
||||||
|
// Compare real full ellipse length with calculated
|
||||||
|
QFETCH(qreal, radius1);
|
||||||
|
QFETCH(qreal, radius2);
|
||||||
|
QFETCH(qreal, startAngle);
|
||||||
|
QFETCH(qreal, endAngle);
|
||||||
|
QFETCH(qreal, rotationAngle);
|
||||||
|
|
||||||
|
const VPointF center;
|
||||||
|
VEllipticalArc arc(center, radius1, radius2, startAngle, endAngle, rotationAngle);
|
||||||
|
|
||||||
|
if (qFuzzyCompare(arc.AngleArc(), 360.0))
|
||||||
|
{// calculated full ellipse length
|
||||||
|
const qreal h = ((radius1-radius2)*(radius1-radius2))/((radius1+radius2)*(radius1+radius2));
|
||||||
|
const qreal ellipseLength = M_PI*(radius1+radius2)*(1+3*h/(10+qSqrt(4-3*h)));
|
||||||
|
const qreal epsLength = ellipseLength*0.5/100; // computing error
|
||||||
|
VEllipticalArc arc(center, radius1, radius2, 0, 360, 0);
|
||||||
|
const qreal arcLength = arc.GetLength();
|
||||||
|
const qreal diffLength = qAbs(arcLength - ellipseLength);
|
||||||
|
const QString errorMsg2 = QString("Difference between real and computing lengthes "
|
||||||
|
"(diff = '%1') bigger than eps = '%2'.").arg(diffLength).arg(epsLength);
|
||||||
|
QVERIFY2(diffLength <= epsLength, qUtf8Printable(errorMsg2));
|
||||||
|
}
|
||||||
|
}
|
57
src/test/ValentinaTest/tst_vellipticalarc.h
Normal file
57
src/test/ValentinaTest/tst_vellipticalarc.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file tst_vellipticalarc.h
|
||||||
|
** @author Valentina Zhuravska <zhuravska19(at)gmail.com>
|
||||||
|
** @date 12 2, 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) 2015 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_VELLIPTICALARC_H
|
||||||
|
#define TST_VELLIPTICALARC_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class TST_VEllipticalArc : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit TST_VEllipticalArc(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void CompareTwoWays();
|
||||||
|
void NegativeArc();
|
||||||
|
void TestGetPoints1_data();
|
||||||
|
void TestGetPoints2_data();
|
||||||
|
void TestGetPoints3_data();
|
||||||
|
void TestGetPoints4_data();
|
||||||
|
void TestGetPoints1();
|
||||||
|
void TestGetPoints2();
|
||||||
|
void TestGetPoints3();
|
||||||
|
void TestGetPoints4();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY(TST_VEllipticalArc)
|
||||||
|
void TestData();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TST_VELLIPTICALARC_H
|
|
@ -35,7 +35,7 @@ class TST_VLayoutDetail : public AbstractTest
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TST_VLayoutDetail(QObject *parent = 0);
|
explicit TST_VLayoutDetail(QObject *parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void RemoveDublicates() const;
|
void RemoveDublicates() const;
|
||||||
|
|
|
@ -38,7 +38,7 @@ class TST_VPoster : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TST_VPoster(QObject *parent = 0);
|
explicit TST_VPoster(QObject *parent = nullptr);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ class TST_VSpline : public AbstractTest
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TST_VSpline(QObject *parent = 0);
|
explicit TST_VSpline(QObject *parent = nullptr);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user