Fixed issue #793. Operations work incorrect with elliptical arc.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2018-01-05 19:41:09 +02:00
parent 7a77ad0e19
commit b25f971758
6 changed files with 185 additions and 71 deletions

View File

@ -72,7 +72,7 @@ public:
void SetFormulaF2 (const QString &formula, qreal value); void SetFormulaF2 (const QString &formula, qreal value);
virtual qreal GetEndAngle () const Q_DECL_OVERRIDE; virtual qreal GetEndAngle () const Q_DECL_OVERRIDE;
VPointF GetCenter () const; virtual VPointF GetCenter () const;
void SetCenter (const VPointF &point); void SetCenter (const VPointF &point);
QString GetFormulaLength () const; QString GetFormulaLength () const;

View File

@ -124,59 +124,57 @@ VEllipticalArc &VEllipticalArc::operator =(const VEllipticalArc &arc)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VEllipticalArc VEllipticalArc::Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix) const VEllipticalArc VEllipticalArc::Rotate(QPointF originPoint, qreal degrees, const QString &prefix) const
{ {
const VPointF center = GetCenter().Rotate(originPoint, degrees); originPoint = d->m_transform.inverted().map(originPoint);
const QPointF p1 = VPointF::RotatePF(originPoint, GetP1(), degrees); QTransform t = d->m_transform;
const QPointF p2 = VPointF::RotatePF(originPoint, GetP2(), degrees); t.translate(originPoint.x(), originPoint.y());
t.rotate(-degrees);
t.translate(-originPoint.x(), -originPoint.y());
const qreal f1 = QLineF(static_cast<QPointF>(center), p1).angle() - GetRotationAngle(); VEllipticalArc elArc(VAbstractArc::GetCenter(), GetRadius1(), GetRadius2(), VAbstractArc::GetStartAngle(),
const qreal f2 = QLineF(static_cast<QPointF>(center), p2).angle() - GetRotationAngle(); VAbstractArc::GetEndAngle(), GetRotationAngle());
VEllipticalArc elArc(center, GetRadius1(), GetRadius2(), f1, f2, GetRotationAngle());
elArc.setName(name() + prefix); elArc.setName(name() + prefix);
elArc.SetColor(GetColor()); elArc.SetColor(GetColor());
elArc.SetPenStyle(GetPenStyle()); elArc.SetPenStyle(GetPenStyle());
elArc.SetFlipped(IsFlipped()); elArc.SetFlipped(IsFlipped());
elArc.SetTransform(t);
return elArc; return elArc;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VEllipticalArc VEllipticalArc::Flip(const QLineF &axis, const QString &prefix) const VEllipticalArc VEllipticalArc::Flip(const QLineF &axis, const QString &prefix) const
{ {
const VPointF center = GetCenter().Flip(axis); VEllipticalArc elArc(VAbstractArc::GetCenter(), GetRadius1(), GetRadius2(), VAbstractArc::GetStartAngle(),
VAbstractArc::GetEndAngle(), GetRotationAngle());
const QPointF p1 = VPointF::FlipPF(axis, GetP1());
const QPointF p2 = VPointF::FlipPF(axis, GetP2());
const qreal f1 = QLineF(static_cast<QPointF>(center), p1).angle() - GetRotationAngle();
const qreal f2 = QLineF(static_cast<QPointF>(center), p2).angle() - GetRotationAngle();
VEllipticalArc elArc(center, GetRadius1(), GetRadius2(), f1, f2, GetRotationAngle());
elArc.setName(name() + prefix); elArc.setName(name() + prefix);
elArc.SetColor(GetColor()); elArc.SetColor(GetColor());
elArc.SetPenStyle(GetPenStyle()); elArc.SetPenStyle(GetPenStyle());
elArc.SetFlipped(not IsFlipped()); elArc.SetFlipped(not IsFlipped());
elArc.SetTransform(d->m_transform * VGObject::FlippingMatrix(d->m_transform.inverted().map(axis)));
return elArc; return elArc;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VEllipticalArc VEllipticalArc::Move(qreal length, qreal angle, const QString &prefix) const VEllipticalArc VEllipticalArc::Move(qreal length, qreal angle, const QString &prefix) const
{ {
const VPointF center = GetCenter().Move(length, angle); const VPointF oldCenter = VAbstractArc::GetCenter();
const VPointF center = oldCenter.Move(length, angle);
const QPointF p1 = VPointF::MovePF(GetP1(), length, angle); const QPointF position = d->m_transform.inverted().map(center.toQPointF()) -
const QPointF p2 = VPointF::MovePF(GetP2(), length, angle); d->m_transform.inverted().map(oldCenter.toQPointF());
const qreal f1 = QLineF(static_cast<QPointF>(center), p1).angle() - GetRotationAngle(); QTransform t = d->m_transform;
const qreal f2 = QLineF(static_cast<QPointF>(center), p2).angle() - GetRotationAngle(); t.translate(position.x(), position.y());
VEllipticalArc elArc(center, GetRadius1(), GetRadius2(), f1, f2, GetRotationAngle()); VEllipticalArc elArc(oldCenter, GetRadius1(), GetRadius2(), VAbstractArc::GetStartAngle(),
VAbstractArc::GetEndAngle(), GetRotationAngle());
elArc.setName(name() + prefix); elArc.setName(name() + prefix);
elArc.SetColor(GetColor()); elArc.SetColor(GetColor());
elArc.SetPenStyle(GetPenStyle()); elArc.SetPenStyle(GetPenStyle());
elArc.SetFlipped(IsFlipped()); elArc.SetFlipped(IsFlipped());
elArc.SetTransform(t);
return elArc; return elArc;
} }
@ -208,7 +206,7 @@ qreal VEllipticalArc::GetLength() const
*/ */
QPointF VEllipticalArc::GetP1() const QPointF VEllipticalArc::GetP1() const
{ {
return GetPoints().first(); return GetTransform().map(GetP(VAbstractArc::GetStartAngle()));
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -218,7 +216,29 @@ QPointF VEllipticalArc::GetP1() const
*/ */
QPointF VEllipticalArc::GetP2 () const QPointF VEllipticalArc::GetP2 () const
{ {
return GetPoints().last(); return GetTransform().map(GetP(VAbstractArc::GetEndAngle()));
}
//---------------------------------------------------------------------------------------------------------------------
QTransform VEllipticalArc::GetTransform() const
{
return d->m_transform;
}
//---------------------------------------------------------------------------------------------------------------------
void VEllipticalArc::SetTransform(const QTransform &matrix, bool combine)
{
d->m_transform = combine ? d->m_transform * matrix : matrix;
}
//---------------------------------------------------------------------------------------------------------------------
VPointF VEllipticalArc::GetCenter() const
{
VPointF center = VAbstractArc::GetCenter();
const QPointF p = d->m_transform.map(center.toQPointF());
center.setX(p.x());
center.setY(p.y());
return center;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -228,27 +248,14 @@ QPointF VEllipticalArc::GetP2 () const
*/ */
QVector<QPointF> VEllipticalArc::GetPoints() const QVector<QPointF> VEllipticalArc::GetPoints() const
{ {
QRectF box(GetCenter().x() - d->radius1, GetCenter().y() - d->radius2, d->radius1*2, const QPointF center = VAbstractArc::GetCenter().toQPointF();
d->radius2*2); QRectF box(center.x() - d->radius1, center.y() - d->radius2, d->radius1*2, d->radius2*2);
qreal startAngle = 0; QLineF startLine(center.x(), center.y(), center.x() + d->radius1, center.y());
qreal endAngle = 0;
if (not IsFlipped())
{
startAngle = GetStartAngle();
endAngle = GetEndAngle();
}
else
{
startAngle = GetEndAngle();
endAngle = GetStartAngle();
}
QLineF startLine(GetCenter().x(), GetCenter().y(), GetCenter().x() + d->radius1, GetCenter().y());
QLineF endLine = startLine; QLineF endLine = startLine;
startLine.setAngle(startAngle); startLine.setAngle(VAbstractArc::GetStartAngle());
endLine.setAngle(endAngle); endLine.setAngle(VAbstractArc::GetEndAngle());
qreal sweepAngle = startLine.angleTo(endLine); qreal sweepAngle = startLine.angleTo(endLine);
if (qFuzzyIsNull(sweepAngle)) if (qFuzzyIsNull(sweepAngle))
@ -257,12 +264,12 @@ QVector<QPointF> VEllipticalArc::GetPoints() const
} }
QPainterPath path; QPainterPath path;
path.arcTo(box, startAngle, sweepAngle); path.arcTo(box, VAbstractArc::GetStartAngle(), sweepAngle);
QTransform t; QTransform t = d->m_transform;
t.translate(GetCenter().x(), GetCenter().y()); t.translate(center.x(), center.y());
t.rotate(-GetRotationAngle()); t.rotate(-GetRotationAngle());
t.translate(-GetCenter().x(), -GetCenter().y()); t.translate(-center.x(), -center.y());
path = t.map(path); path = t.map(path);
@ -280,6 +287,18 @@ QVector<QPointF> VEllipticalArc::GetPoints() const
return polygon; return polygon;
} }
//---------------------------------------------------------------------------------------------------------------------
qreal VEllipticalArc::GetStartAngle() const
{
return QLineF(GetCenter().toQPointF(), GetP1()).angle() - GetRotationAngle();
}
//---------------------------------------------------------------------------------------------------------------------
qreal VEllipticalArc::GetEndAngle() const
{
return QLineF(GetCenter().toQPointF(), GetP2()).angle() - GetRotationAngle();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
* @brief CutArc cut arc into two arcs. * @brief CutArc cut arc into two arcs.
@ -367,7 +386,7 @@ void VEllipticalArc::FindF2(qreal length)
} }
while (length > MaxLength()) while (length > MaxLength())
{ {
length = length - MaxLength(); length = MaxLength();
} }
// We need to calculate the second angle // We need to calculate the second angle
@ -383,7 +402,7 @@ void VEllipticalArc::FindF2(qreal length)
qreal lenBez = GetLength(); // first approximation of length qreal lenBez = GetLength(); // first approximation of length
const qreal eps = ToPixel(0.1, Unit::Mm); const qreal eps = ToPixel(0.001, Unit::Mm);
while (qAbs(lenBez - length) > eps) while (qAbs(lenBez - length) > eps)
{ {
@ -416,6 +435,24 @@ qreal VEllipticalArc::MaxLength() const
return ellipseLength; return ellipseLength;
} }
//---------------------------------------------------------------------------------------------------------------------
QPointF VEllipticalArc::GetP(qreal angle) const
{
QLineF line(0, 0, 100, 0);
line.setAngle(angle);
const qreal a = line.p2().x() / GetRadius1();
const qreal b = line.p2().y() / GetRadius2();
const qreal k = qSqrt(a*a + b*b);
QPointF p(line.p2().x() / k, line.p2().y() / k);
QLineF line2(QPointF(), p);
SCASSERT(VFuzzyComparePossibleNulls(line2.angle(), line.angle()))
line2.setAngle(line2.angle() + GetRotationAngle());
return line2.p2() + VAbstractArc::GetCenter().toQPointF();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
* @brief GetFormulaRadius1 return formula for major radius. * @brief GetFormulaRadius1 return formula for major radius.

View File

@ -61,7 +61,7 @@ public:
VEllipticalArc (qreal length, const VPointF &center, qreal radius1, qreal radius2, qreal f1, qreal rotationAngle); VEllipticalArc (qreal length, const VPointF &center, qreal radius1, qreal radius2, qreal f1, qreal rotationAngle);
VEllipticalArc(const VEllipticalArc &arc); VEllipticalArc(const VEllipticalArc &arc);
VEllipticalArc Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const; VEllipticalArc Rotate(QPointF originPoint, qreal degrees, const QString &prefix = QString()) const;
VEllipticalArc Flip(const QLineF &axis, const QString &prefix = QString()) const; VEllipticalArc Flip(const QLineF &axis, const QString &prefix = QString()) const;
VEllipticalArc Move(qreal length, qreal angle, const QString &prefix = QString()) const; VEllipticalArc Move(qreal length, qreal angle, const QString &prefix = QString()) const;
@ -92,10 +92,18 @@ public:
QPointF GetP1() const; QPointF GetP1() const;
QPointF GetP2() const; QPointF GetP2() const;
QTransform GetTransform() const;
void SetTransform(const QTransform &matrix, bool combine = false);
virtual VPointF GetCenter () const Q_DECL_OVERRIDE;
virtual QVector<QPointF> GetPoints () const Q_DECL_OVERRIDE; virtual QVector<QPointF> GetPoints () const Q_DECL_OVERRIDE;
virtual qreal GetStartAngle () const Q_DECL_OVERRIDE;
virtual qreal GetEndAngle () const Q_DECL_OVERRIDE;
QPointF CutArc (const qreal &length, VEllipticalArc &arc1, VEllipticalArc &arc2) const; QPointF CutArc (const qreal &length, VEllipticalArc &arc1, VEllipticalArc &arc2) const;
QPointF CutArc (const qreal &length) const; QPointF CutArc (const qreal &length) const;
static qreal OptimizeAngle(qreal angle);
protected: protected:
virtual void CreateName() Q_DECL_OVERRIDE; virtual void CreateName() Q_DECL_OVERRIDE;
virtual void FindF2(qreal length) Q_DECL_OVERRIDE; virtual void FindF2(qreal length) Q_DECL_OVERRIDE;
@ -103,9 +111,17 @@ private:
QSharedDataPointer<VEllipticalArcData> d; QSharedDataPointer<VEllipticalArcData> d;
qreal MaxLength() const; qreal MaxLength() const;
QPointF GetP(qreal angle) const;
}; };
Q_DECLARE_METATYPE(VEllipticalArc) Q_DECLARE_METATYPE(VEllipticalArc)
Q_DECLARE_TYPEINFO(VEllipticalArc, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(VEllipticalArc, Q_MOVABLE_TYPE);
//---------------------------------------------------------------------------------------------------------------------
inline qreal VEllipticalArc::OptimizeAngle(qreal angle)
{
return angle - 360.*qFloor(angle/360.);
}
#endif // VELLIPTICALARC_H #endif // VELLIPTICALARC_H

View File

@ -33,6 +33,7 @@ public:
qreal rotationAngle; qreal rotationAngle;
/** @brief formulaRotationAngle formula for rotationAngle. */ /** @brief formulaRotationAngle formula for rotationAngle. */
QString formulaRotationAngle; QString formulaRotationAngle;
QTransform m_transform;
private: private:
VEllipticalArcData &operator=(const VEllipticalArcData &) Q_DECL_EQ_DELETE; VEllipticalArcData &operator=(const VEllipticalArcData &) Q_DECL_EQ_DELETE;
@ -45,7 +46,8 @@ VEllipticalArcData::VEllipticalArcData()
formulaRadius1(), formulaRadius1(),
formulaRadius2(), formulaRadius2(),
rotationAngle(0), rotationAngle(0),
formulaRotationAngle() formulaRotationAngle(),
m_transform()
{} {}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -57,7 +59,8 @@ VEllipticalArcData::VEllipticalArcData(qreal radius1, qreal radius2, const QStri
formulaRadius1(formulaRadius1), formulaRadius1(formulaRadius1),
formulaRadius2(formulaRadius2), formulaRadius2(formulaRadius2),
rotationAngle(rotationAngle), rotationAngle(rotationAngle),
formulaRotationAngle(formulaRotationAngle) formulaRotationAngle(formulaRotationAngle),
m_transform()
{} {}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -67,7 +70,8 @@ VEllipticalArcData::VEllipticalArcData(qreal radius1, qreal radius2, qreal rotat
formulaRadius1(QString().number(qApp->fromPixel(radius1))), formulaRadius1(QString().number(qApp->fromPixel(radius1))),
formulaRadius2(QString().number(qApp->fromPixel(radius2))), formulaRadius2(QString().number(qApp->fromPixel(radius2))),
rotationAngle(rotationAngle), rotationAngle(rotationAngle),
formulaRotationAngle(QString().number(qApp->fromPixel(rotationAngle))) formulaRotationAngle(QString().number(qApp->fromPixel(rotationAngle))),
m_transform()
{} {}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -78,7 +82,8 @@ VEllipticalArcData::VEllipticalArcData(const VEllipticalArcData &arc)
formulaRadius1(arc.formulaRadius1), formulaRadius1(arc.formulaRadius1),
formulaRadius2(arc.formulaRadius2), formulaRadius2(arc.formulaRadius2),
rotationAngle(arc.rotationAngle), rotationAngle(arc.rotationAngle),
formulaRotationAngle(arc.formulaRotationAngle) formulaRotationAngle(arc.formulaRotationAngle),
m_transform(arc.m_transform)
{} {}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -48,7 +48,7 @@ void TST_VEllipticalArc::CompareTwoWays_data()
QTest::addColumn<qreal>("f2"); QTest::addColumn<qreal>("f2");
QTest::addColumn<qreal>("rotationAngle"); QTest::addColumn<qreal>("rotationAngle");
//QTest::newRow("Test case 1") << QPointF() << 100. << 200. << 0. << 90.0 << 0.; QTest::newRow("Test case 1") << QPointF() << 100. << 200. << 0. << 90.0 << 0.;
QTest::newRow("Test case 2") << QPointF() << 100. << 200. << 0. << 180.0 << 0.; QTest::newRow("Test case 2") << QPointF() << 100. << 200. << 0. << 180.0 << 0.;
QTest::newRow("Test case 3") << QPointF() << 100. << 200. << 0. << 270.0 << 0.; QTest::newRow("Test case 3") << QPointF() << 100. << 200. << 0. << 270.0 << 0.;
QTest::newRow("Test case 4") << QPointF() << 100. << 200. << 0. << 360.0 << 0.; QTest::newRow("Test case 4") << QPointF() << 100. << 200. << 0. << 360.0 << 0.;
@ -86,18 +86,19 @@ void TST_VEllipticalArc::CompareTwoWays()
const qreal lengthEps = ToPixel(0.4, Unit::Mm); // computing error const qreal lengthEps = ToPixel(0.4, Unit::Mm); // computing error
const QString errorLengthMsg = const QString errorLengthMsg =
QString("Difference between real and computing lengthes bigger than eps = %1.").number(lengthEps); QString("Difference between real and computing lengthes bigger than eps = %1. l1 = %2; l2 = %3");
QVERIFY2(qAbs(arc1.GetLength() - length) <= lengthEps, qUtf8Printable(errorLengthMsg)); QVERIFY2(qAbs(arc2.GetLength() - length) <= lengthEps,
QVERIFY2(qAbs(arc2.GetLength() - length) <= lengthEps, qUtf8Printable(errorLengthMsg)); qUtf8Printable(errorLengthMsg.arg(lengthEps).arg(arc2.GetLength()).arg(length)));
QVERIFY2(qAbs(arc1.GetLength() - arc2.GetLength()) <= lengthEps, qUtf8Printable(errorLengthMsg)); QVERIFY2(qAbs(arc1.GetLength() - arc2.GetLength()) <= lengthEps,
qUtf8Printable(errorLengthMsg.arg(lengthEps).arg(arc2.GetLength()).arg(arc2.GetLength())));
const qreal angleEps = 0.4; const qreal angleEps = 0.4;
const QString errorAngleMsg = const QString errorAngleMsg =
QString("Difference between real and computing angles bigger than eps = %1.").number(angleEps); QString("Difference between real and computing angles bigger than eps = %1. f1 = %2; f2 = %3");
// compare angles // compare angles
QVERIFY2(qAbs(arc1.GetEndAngle() - arc2.GetEndAngle()) <= angleEps, qUtf8Printable(errorAngleMsg)); const qreal diff = qAbs(arc1.GetEndAngle() - arc2.GetEndAngle());
QVERIFY2(qAbs(arc1.GetEndAngle() - f2) <= angleEps, qUtf8Printable(errorAngleMsg)); QVERIFY2(qAbs(diff - 360.0*(diff/360.0)) <= angleEps,
QVERIFY2(qAbs(arc1.GetEndAngle() - f2) <= angleEps, qUtf8Printable(errorAngleMsg)); qUtf8Printable(errorAngleMsg.arg(angleEps).arg(arc1.GetEndAngle()).arg(arc2.GetEndAngle())));
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -158,12 +159,22 @@ void TST_VEllipticalArc::TestData()
QTest::addColumn<qreal>("endAngle"); QTest::addColumn<qreal>("endAngle");
QTest::addColumn<qreal>("rotationAngle"); 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 10, 20; start 0") << 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; start 0") << 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 150, 200, rotation 30; start 0") << 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; start 0") << 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 1500, 1000, rotation 50; start 0") << 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("Full circle: radiuses 90000, 80000, rotation 90; start 0") << 90000.0 << 80000.0 << 0.0 << 360.0
<< 90.0;
QTest::newRow("Full circle: radiuses 10, 20; start 90") << 10.0 << 20.0 << 90.0 << 90.0 << 0.0;
QTest::newRow("Full circle: radiuses 150, 200; start 90") << 150.0 << 200.0 << 90.0 << 90.0 << 0.0;
QTest::newRow("Full circle: radiuses 150, 200, rotation 30; start 90") << 150.0 << 200.0 << 90.0 << 90.0 << 30.0;
QTest::newRow("Full circle: radiuses 1500, 1000; start 90") << 1500.0 << 1000.0 << 90.0 << 90.0 << 0.0;
QTest::newRow("Full circle: radiuses 1500, 1000, rotation 50; start 90") << 1500.0 << 1000.0 << 90.0 << 90.0
<< 50.0;
QTest::newRow("Full circle: radiuses 90000, 80000, rotation 90; start 90") << 90000.0 << 80000.0 << 90.0 << 90.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 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 150, 50, rotation 180") << 150.0 << 50.0 << 0.0 << 10.5 << 180.0;
@ -408,6 +419,46 @@ void TST_VEllipticalArc::TestGetPoints4()
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void TST_VEllipticalArc::TestGetPoints5_data()
{
TestData();
}
//---------------------------------------------------------------------------------------------------------------------
void TST_VEllipticalArc::TestGetPoints5()
{
// Test if first and last point still have same angle
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);
const qreal stAngle = VEllipticalArc::OptimizeAngle(arc.GetStartAngle()+arc.GetRotationAngle());
const qreal enAngle = VEllipticalArc::OptimizeAngle(arc.GetEndAngle()+arc.GetRotationAngle());
qreal f1 = QLineF(static_cast<QPointF>(center), arc.GetP1()).angle();
if ((qFuzzyIsNull(f1) && VFuzzyComparePossibleNulls(360, stAngle)) ||
(VFuzzyComparePossibleNulls(360, f1) && qFuzzyIsNull(stAngle)))
{
f1 = stAngle;
}
qreal f2 = QLineF(static_cast<QPointF>(center), arc.GetP2()).angle();
if ((qFuzzyIsNull(f2) && VFuzzyComparePossibleNulls(360, enAngle)) ||
(VFuzzyComparePossibleNulls(360, f2) && qFuzzyIsNull(enAngle)))
{
f2 = enAngle;
}
QCOMPARE(f1, stAngle);
QCOMPARE(f2, enAngle);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void TST_VEllipticalArc::TestRotation_data() void TST_VEllipticalArc::TestRotation_data()
{ {
@ -423,6 +474,8 @@ void TST_VEllipticalArc::TestRotation_data()
QTest::newRow("Test el arc 1") << QPointF() << 10. << 20.0 << 1. << 91. << 0.<< QPointF() << 90. << "_r"; QTest::newRow("Test el arc 1") << QPointF() << 10. << 20.0 << 1. << 91. << 0.<< QPointF() << 90. << "_r";
QTest::newRow("Test el arc 2") << QPointF() << 10. << 20.0 << 0. << 90. << 0.<< QPointF() << 90. << "_r"; QTest::newRow("Test el arc 2") << QPointF() << 10. << 20.0 << 0. << 90. << 0.<< QPointF() << 90. << "_r";
QTest::newRow("Test el arc 3.2") << QPointF(10, 10) << 10. << 20.0 << 0. << 90. << 0.<< QPointF() << 90. << "_r";
QTest::newRow("Test el arc 3.1") << QPointF(10, 10) << 10. << 20.0 << 1. << 91. << 0.<< QPointF() << 90. << "_r";
QTest::newRow("Test el arc 3") << QPointF(10, 10) << 10. << 20.0 << 1. << 91. << 90.<< QPointF() << 90. << "_r"; QTest::newRow("Test el arc 3") << QPointF(10, 10) << 10. << 20.0 << 1. << 91. << 90.<< QPointF() << 90. << "_r";
QTest::newRow("Test el arc 4") << QPointF(10, 10) << 10. << 20.0 << 0. << 90. << 90.<< QPointF() << 90. << "_r"; QTest::newRow("Test el arc 4") << QPointF(10, 10) << 10. << 20.0 << 0. << 90. << 90.<< QPointF() << 90. << "_r";
QTest::newRow("Test el arc 5") << QPointF(10, 10) << 10. << 20.0 << 0. << 180. << 90.<< QPointF() << 90. << "_r"; QTest::newRow("Test el arc 5") << QPointF(10, 10) << 10. << 20.0 << 0. << 180. << 90.<< QPointF() << 90. << "_r";
@ -448,7 +501,8 @@ void TST_VEllipticalArc::TestRotation()
const VEllipticalArc arcOrigin(VPointF(center), radius1, radius2, startAngle, endAngle, rotationAngle); const VEllipticalArc arcOrigin(VPointF(center), radius1, radius2, startAngle, endAngle, rotationAngle);
const VEllipticalArc rotatedArc = arcOrigin.Rotate(rotatePoint, degrees, prefix); const VEllipticalArc rotatedArc = arcOrigin.Rotate(rotatePoint, degrees, prefix);
QVERIFY(qAbs(arcOrigin.AngleArc() - rotatedArc.AngleArc()) <= 1.6); QVERIFY2(qAbs(arcOrigin.AngleArc() - rotatedArc.AngleArc()) <= 1.6,
qUtf8Printable(QString("a1 = %1, a2 - %2").arg(arcOrigin.AngleArc()).arg(rotatedArc.AngleArc())));
QVERIFY(qAbs(arcOrigin.GetLength() - rotatedArc.GetLength()) <= ToPixel(1, Unit::Mm)); QVERIFY(qAbs(arcOrigin.GetLength() - rotatedArc.GetLength()) <= ToPixel(1, Unit::Mm));
QCOMPARE(arcOrigin.GetRadius1(), rotatedArc.GetRadius1()); QCOMPARE(arcOrigin.GetRadius1(), rotatedArc.GetRadius1());
QCOMPARE(arcOrigin.GetRadius2(), rotatedArc.GetRadius2()); QCOMPARE(arcOrigin.GetRadius2(), rotatedArc.GetRadius2());

View File

@ -49,6 +49,8 @@ private slots:
void TestGetPoints2(); void TestGetPoints2();
void TestGetPoints3(); void TestGetPoints3();
void TestGetPoints4(); void TestGetPoints4();
void TestGetPoints5_data();
void TestGetPoints5();
void TestRotation_data(); void TestRotation_data();
void TestRotation(); void TestRotation();
void TestFlip_data(); void TestFlip_data();