diff --git a/ChangeLog.txt b/ChangeLog.txt index 6ee79cf10..cd101c510 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -3,6 +3,7 @@ - [smart-pattern/valentina#119] Improve tool Point of intersection curves. - [smart-pattern/valentina#120] Incorrect seam allowance. - Fix export to DXF AAMA/ASTM. +- [smart-pattern/valentina#121] Incorrect elliptical arc end angle. # Version 0.7.46 Mar 31, 2021 - Fix incorrect calculation of value for multisize measurements in Valentina. diff --git a/src/libs/vgeometry/vellipticalarc.cpp b/src/libs/vgeometry/vellipticalarc.cpp index 5db2a4b95..a616055cd 100644 --- a/src/libs/vgeometry/vellipticalarc.cpp +++ b/src/libs/vgeometry/vellipticalarc.cpp @@ -290,7 +290,7 @@ QVector VEllipticalArc::GetPoints() const QLineF endLine = startLine; startLine.setAngle(VAbstractArc::GetStartAngle()); - endLine.setAngle(VAbstractArc::GetEndAngle()); + endLine.setAngle(RealEndAngle()); qreal sweepAngle = startLine.angleTo(endLine); if (qFuzzyIsNull(sweepAngle)) @@ -508,6 +508,26 @@ QPointF VEllipticalArc::GetP(qreal angle) const return line2.p2() + VAbstractArc::GetCenter().toQPointF(); } +//--------------------------------------------------------------------------------------------------------------------- +qreal VEllipticalArc::RealEndAngle() const +{ + qreal endAngle = VEllipticalArc::OptimizeAngle(VAbstractArc::GetEndAngle()); + + if (qFuzzyIsNull(endAngle) || + VFuzzyComparePossibleNulls(endAngle, 90) || + VFuzzyComparePossibleNulls(endAngle, 180) || + VFuzzyComparePossibleNulls(endAngle, 270) || + VFuzzyComparePossibleNulls(endAngle, 360)) + { + return endAngle; + } + + endAngle = qRadiansToDegrees(qAtan2(d->radius1 * qSin(qDegreesToRadians(endAngle)), + d->radius2 * qCos(qDegreesToRadians(endAngle)))); + + return endAngle; +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief GetFormulaRadius1 return formula for major radius. diff --git a/src/libs/vgeometry/vellipticalarc.h b/src/libs/vgeometry/vellipticalarc.h index 2c23ca104..481afcfaf 100644 --- a/src/libs/vgeometry/vellipticalarc.h +++ b/src/libs/vgeometry/vellipticalarc.h @@ -112,6 +112,8 @@ private: qreal MaxLength() const; QPointF GetP(qreal angle) const; + + qreal RealEndAngle() const; }; Q_DECLARE_METATYPE(VEllipticalArc) diff --git a/src/libs/vtest/abstracttest.cpp b/src/libs/vtest/abstracttest.cpp index 318c934fe..4e814f445 100644 --- a/src/libs/vtest/abstracttest.cpp +++ b/src/libs/vtest/abstracttest.cpp @@ -311,23 +311,18 @@ void AbstractTest::Comparison(const QVector &ekv, const QVector &ekv, const QVector &ekvOrig) const; - void Comparison(const QPointF &result, const QPointF &expected) const; + void Comparison(const QPointF &result, const QPointF &expected, qreal testAccuracy) const; void Comparison(const QVector &result, const QVector &expected) const; QString ValentinaPath() const; diff --git a/src/test/ValentinaTest/tst_findpoint.cpp b/src/test/ValentinaTest/tst_findpoint.cpp index 9847bf3fb..86982d028 100644 --- a/src/test/ValentinaTest/tst_findpoint.cpp +++ b/src/test/ValentinaTest/tst_findpoint.cpp @@ -170,7 +170,7 @@ void TST_FindPoint::TestPointOfIntersectionCurves() static_cast(vCross), static_cast(hCross), &result); - Comparison(result, expect); + Comparison(result, expect, accuracyPointOnLine); } //--------------------------------------------------------------------------------------------------------------------- @@ -211,8 +211,8 @@ void TST_FindPoint::TestTrueDarts() VToolTrueDarts::FindPoint(baseLineP1, baseLineP2, dartP1, dartP2, dartP3, p1, p2); - Comparison(p1, expectP1); - Comparison(p2, expectP2); + Comparison(p1, expectP1, accuracyPointOnLine); + Comparison(p2, expectP2, accuracyPointOnLine); } //--------------------------------------------------------------------------------------------------------------------- @@ -239,7 +239,7 @@ void TST_FindPoint::TestLineIntersectAxis() QPointF resultPoint; VToolLineIntersectAxis::FindPoint(axis, line, &resultPoint); - Comparison(resultPoint, point); + Comparison(resultPoint, point, accuracyPointOnLine); } //--------------------------------------------------------------------------------------------------------------------- @@ -272,7 +272,7 @@ void TST_FindPoint::TestTriangle() QPointF resultPoint; VToolTriangle::FindPoint(axisP1, axisP2, firstPoint, secondPoint, &resultPoint); - Comparison(point, resultPoint); + Comparison(point, resultPoint, accuracyPointOnLine); } //--------------------------------------------------------------------------------------------------------------------- @@ -312,7 +312,7 @@ void TST_FindPoint::TestShoulderPoint() QPointF resultPoint = VToolShoulderPoint::FindPoint(p1, p2, pShoulder, length); - Comparison(point, resultPoint); + Comparison(point, resultPoint, accuracyPointOnLine); } //--------------------------------------------------------------------------------------------------------------------- @@ -745,5 +745,5 @@ void TST_FindPoint::TestCurveIntersectAxis() QPointF resultPoint; VToolCurveIntersectAxis::FindPoint(basePoint, angle, curvePoints, &resultPoint); - Comparison(resultPoint, result); + Comparison(resultPoint, result, accuracyPointOnLine); } diff --git a/src/test/ValentinaTest/tst_varc.cpp b/src/test/ValentinaTest/tst_varc.cpp index 61752b5c1..0ef8b1a7e 100644 --- a/src/test/ValentinaTest/tst_varc.cpp +++ b/src/test/ValentinaTest/tst_varc.cpp @@ -454,5 +454,5 @@ void TST_VArc::TestCurveIntersectAxis() const bool found = VAbstractCurve::CurveIntersectAxis(basePoint, angle, curvePoints, &intersectionPoint); QCOMPARE(found, result); - Comparison(intersectionPoint, crosPoint); + Comparison(intersectionPoint, crosPoint, accuracyPointOnLine); } diff --git a/src/test/ValentinaTest/tst_vellipticalarc.cpp b/src/test/ValentinaTest/tst_vellipticalarc.cpp index fc872ac32..938b00033 100644 --- a/src/test/ValentinaTest/tst_vellipticalarc.cpp +++ b/src/test/ValentinaTest/tst_vellipticalarc.cpp @@ -34,7 +34,7 @@ #include //--------------------------------------------------------------------------------------------------------------------- -TST_VEllipticalArc::TST_VEllipticalArc(QObject *parent) : QObject(parent) +TST_VEllipticalArc::TST_VEllipticalArc(QObject *parent) : AbstractTest(parent) {} //--------------------------------------------------------------------------------------------------------------------- @@ -168,7 +168,7 @@ void TST_VEllipticalArc::TestData() 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; start 0") << 1500.0 << 1000.0 << 0.0 << 360.0 << 0.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; start 0") << 90000.0 << 80000.0 << 0.0 << 360.0 + QTest::newRow("Full circle: radiuses 15000, 10000, rotation 90; start 0") << 15000.0 << 10000.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; @@ -177,21 +177,21 @@ void TST_VEllipticalArc::TestData() 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 + QTest::newRow("Full circle: radiuses 15000, 10000, rotation 90; start 90") << 15000.0 << 10000.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 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") + QTest::newRow("Arc less than 45 degree, radiuses 15000, 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 less than 45 degree, radiuses 15000, 10000") << 15000.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 45 degree, radiuses 15000, 15000") << 15000.0 << 15000.0 << 0.0 << 45.0 << 0.0; + QTest::newRow("Arc 45 degree, radiuses 15000, 10000, rotation 270") << 15000.0 << 10000.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; @@ -205,65 +205,65 @@ void TST_VEllipticalArc::TestData() 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 90 degree, radiuses 15000, 5000, rotation 30") << 15000.0 << 1500.0 << 0.0 << 90.0 << 30.0; + QTest::newRow("Arc 90 degree, radiuses 15000, 14000, rotation 235") << 15000.0 << 14000.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 less than 135 degree, radiuses 15000, 1500, rotation 290") + << 15000.0 << 1500.0 << 0.0 << 110.6 << 290.0; + QTest::newRow("Arc less than 135 degree, radiuses 15000, 1500") << 15000.0 << 1500.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 135 degree, radiuses 15000, 1500, rotation 20") << 15000.0 << 1500.0 << 0.0 << 135.0 << 20.0; + QTest::newRow("Arc 135 degree, radiuses 15000, 10000") << 15000.0 << 10000.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 less than 180 degree, radiuses 15000, 1500, rotation 270") + << 15000.0 << 1500.0 << 0.0 << 160.7 << 270.0; + QTest::newRow("Arc less than 180 degree, radiuses 15000, 10000") << 15000.0 << 10000.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 180 degree, radiuses 15000, 1500, rotation 60") << 15000.0 << 1500.0 << 0.0 << 180.0 << 60.0; + QTest::newRow("Arc 180 degree, radiuses 15000, 10000") << 15000.0 << 10000.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 less than 270 degree, radiuses 15000, 1500, rotation 20") + << 15000.0 << 1500.0 << 0.0 << 150.3 << 20.0; + QTest::newRow("Arc less than 270 degree, radiuses 15000, 10000") << 15000.0 << 10000.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 270 degree, radiuses 15000, 1500, rotation 90") << 15000.0 << 1500.0 << 0.0 << 270.0 << 90.0; + QTest::newRow("Arc 270 degree, radiuses 15000, 10000") << 15000.0 << 10000.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 less than 360 degree, radiuses 12000, 1200, rotation 30") + << 12000.0 << 1200.0 << 0.0 << 340.0 << 30.0; + QTest::newRow("Arc less than 360 degree, radiuses 12000, 10000") << 15000.0 << 10000.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; + QTest::newRow("Arc start 90 degree, angle 45 degree, radiuses 13000, 1000") + << 15000.0 << 1000.0 << 90.0 << 135.0 << 0.0; + QTest::newRow("Arc start 90 degree, angle 45 degree, radiuses 15000, 10000") + << 15000.0 << 10000.0 << 90.0 << 135.0 << 0.0; } //--------------------------------------------------------------------------------------------------------------------- @@ -460,6 +460,23 @@ void TST_VEllipticalArc::TestGetPoints5() QCOMPARE(f1, stAngle); QCOMPARE(f2, enAngle); + + QVector points = arc.GetPoints(); + + if (points.size() > 2 && qFuzzyIsNull(rotationAngle)) + { + const qreal testAccuracy = (1.5/*mm*/ / 25.4) * PrintDPI; + Comparison(arc.GetP1(), ConstFirst(points), testAccuracy); + Comparison(arc.GetP2(), ConstLast(points), testAccuracy); + + const qreal eps = 0.15; + + f1 = QLineF(static_cast(center), ConstFirst(points)).angle(); + QVERIFY2(f1 - stAngle <= eps, qUtf8Printable(QStringLiteral("f1: %1; expected: %2").arg(f1).arg(stAngle))); + + f2 = QLineF(static_cast(center), ConstLast(points)).angle(); + QVERIFY2(f2 - enAngle <= eps, qUtf8Printable(QStringLiteral("f2: %1; expected: %2").arg(f2).arg(enAngle))); + } } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/test/ValentinaTest/tst_vellipticalarc.h b/src/test/ValentinaTest/tst_vellipticalarc.h index 3c795e8c3..99f4486dc 100644 --- a/src/test/ValentinaTest/tst_vellipticalarc.h +++ b/src/test/ValentinaTest/tst_vellipticalarc.h @@ -29,9 +29,9 @@ #ifndef TST_VELLIPTICALARC_H #define TST_VELLIPTICALARC_H -#include +#include "../vtest/abstracttest.h" -class TST_VEllipticalArc : public QObject +class TST_VEllipticalArc : public AbstractTest { Q_OBJECT public: