From f1504289251636e58a8ece4fb48aa9475bc052bb Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Tue, 22 Sep 2020 17:05:18 +0300 Subject: [PATCH] Fix bug in VAbstractCurve::CurveIntersectLine. QLineF::intersects not always accurate on edge cases. We must provide additional check. --- src/libs/vgeometry/vabstractcurve.cpp | 4 +- src/test/ValentinaTest/tst_varc.cpp | 63 ++++++++++++++++++++++++++- src/test/ValentinaTest/tst_varc.h | 6 ++- 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/libs/vgeometry/vabstractcurve.cpp b/src/libs/vgeometry/vabstractcurve.cpp index 056c21bde..bf224393c 100644 --- a/src/libs/vgeometry/vabstractcurve.cpp +++ b/src/libs/vgeometry/vabstractcurve.cpp @@ -437,7 +437,9 @@ QVector VAbstractCurve::CurveIntersectLine(const QVector &poin QPointF crosPoint; auto type = Intersects(line, QLineF(points.at(i), points.at(i+1)), &crosPoint); - if (type == QLineF::BoundedIntersection) + // QLineF::intersects not always accurate on edge cases + if (type == QLineF::BoundedIntersection || + VGObject::IsPointOnLineSegment (crosPoint, points.at(i), points.at(i+1))) { intersections.append(crosPoint); } diff --git a/src/test/ValentinaTest/tst_varc.cpp b/src/test/ValentinaTest/tst_varc.cpp index d50a17b80..61752b5c1 100644 --- a/src/test/ValentinaTest/tst_varc.cpp +++ b/src/test/ValentinaTest/tst_varc.cpp @@ -32,9 +32,33 @@ #include +namespace +{ +void PrepareTestCase(const QPointF ¢er, qreal startAngle, qreal endAngle) +{ + qreal radius = UnitConvertor(1, Unit::Cm, Unit::Px); + const qreal threshold = UnitConvertor(2000, Unit::Cm, Unit::Px); + while(radius <= threshold) + { + VArc arc(VPointF(center), radius, startAngle, endAngle); + const QVector points = arc.GetPoints(); + + const QString testStartAngle = QString("Test start angel. Arc radius %1, start angle %2, end angle %3") + .arg(radius).arg(startAngle).arg(endAngle); + QTest::newRow(qUtf8Printable(testStartAngle)) << center << startAngle << points << points.first() << true; + + const QString testEndAngle = QString("Test end angel. Arc radius %1, start angle %2, end angle %3") + .arg(radius).arg(startAngle).arg(endAngle); + QTest::newRow(qUtf8Printable(testEndAngle)) << center << endAngle << points << points.last() << true; + + radius += UnitConvertor(5, Unit::Cm, Unit::Px); + } +} +} + //--------------------------------------------------------------------------------------------------------------------- TST_VArc::TST_VArc(QObject *parent) - :QObject(parent) + :AbstractTest(parent) {} //--------------------------------------------------------------------------------------------------------------------- @@ -395,3 +419,40 @@ void TST_VArc::TestCutArc() qreal segmentsLength = VAbstractCurve::PathLength(arc1.GetPoints()) + VAbstractCurve::PathLength(arc2.GetPoints()); QVERIFY(qAbs(segmentsLength - VAbstractCurve::PathLength(arc.GetPoints())) <= accuracyPointOnLine); } + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VArc::TestCurveIntersectAxis_data() +{ + QTest::addColumn("basePoint"); + QTest::addColumn("angle"); + QTest::addColumn>("curvePoints"); + QTest::addColumn("crosPoint"); + QTest::addColumn("result"); + + QPointF basePoint(10, 10); + + PrepareTestCase(basePoint, 0, 15); + PrepareTestCase(basePoint, 0, 25); + PrepareTestCase(basePoint, 0, 45); + PrepareTestCase(basePoint, 0, 90); + PrepareTestCase(basePoint, 0, 180); + PrepareTestCase(basePoint, 0, 270); + PrepareTestCase(basePoint, 180, 315); + PrepareTestCase(basePoint, 183, 312); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VArc::TestCurveIntersectAxis() +{ + QFETCH(QPointF, basePoint); + QFETCH(qreal, angle); + QFETCH(QVector, curvePoints); + QFETCH(QPointF, crosPoint); + QFETCH(bool, result); + + QPointF intersectionPoint; + const bool found = VAbstractCurve::CurveIntersectAxis(basePoint, angle, curvePoints, &intersectionPoint); + QCOMPARE(found, result); + + Comparison(intersectionPoint, crosPoint); +} diff --git a/src/test/ValentinaTest/tst_varc.h b/src/test/ValentinaTest/tst_varc.h index 0c066e687..f83655bf6 100644 --- a/src/test/ValentinaTest/tst_varc.h +++ b/src/test/ValentinaTest/tst_varc.h @@ -29,9 +29,9 @@ #ifndef TST_VARC_H #define TST_VARC_H -#include +#include "../vtest/abstracttest.h" -class TST_VArc : public QObject +class TST_VArc : public AbstractTest { Q_OBJECT public: @@ -48,6 +48,8 @@ private slots: void TestFlip(); void TestCutArc_data(); void TestCutArc(); + void TestCurveIntersectAxis_data(); + void TestCurveIntersectAxis(); }; #endif // TST_VARC_H