From 270f3b44a105afe057eda2a0e037457ba870d443 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Fri, 25 May 2018 17:52:35 +0300 Subject: [PATCH] Improve handling errors cases for points of intersection. Instead of silence setting coordinate to (0;0) show a warning message. Also for tool "Point of Lines intersection" set coordinates to (0;0) instead of skipping creating a point. This will prevent failing to open a pattern file. --HG-- branch : develop --- .../toolsinglepoint/vtoollineintersect.cpp | 73 ++++++++++--------- .../vtoolpointofintersectionarcs.cpp | 36 ++++++--- .../vtoolpointofintersectionarcs.h | 3 +- .../vtoolpointofintersectioncircles.cpp | 29 ++++++-- .../vtoolpointofintersectioncircles.h | 4 +- .../vtoolpointofintersectioncurves.cpp | 35 ++++++--- .../vtoolpointofintersectioncurves.h | 4 +- .../line/vistoolpointofintersectionarcs.cpp | 3 +- .../vistoolpointofintersectioncircles.cpp | 7 +- .../path/vistoolpointofintersectioncurves.cpp | 5 +- src/test/ValentinaTest/tst_findpoint.cpp | 7 +- 11 files changed, 128 insertions(+), 78 deletions(-) diff --git a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoollineintersect.cpp b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoollineintersect.cpp index 47022c0af..47250b7ab 100644 --- a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoollineintersect.cpp +++ b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoollineintersect.cpp @@ -140,47 +140,50 @@ VToolLineIntersect* VToolLineIntersect::Create(VToolLineIntersectInitData initDa QLineF line1(static_cast(*p1Line1), static_cast(*p2Line1)); QLineF line2(static_cast(*p1Line2), static_cast(*p2Line2)); QPointF fPoint; - QLineF::IntersectType intersect = line1.intersect(line2, &fPoint); - if (intersect == QLineF::UnboundedIntersection || intersect == QLineF::BoundedIntersection) + const QLineF::IntersectType intersect = line1.intersect(line2, &fPoint); + if (intersect == QLineF::NoIntersection) { - VPointF *p = new VPointF(fPoint, initData.name, initData.mx, initData.my); - p->SetShowLabel(initData.showLabel); + qWarning() << tr("Error calculating point '%1'. Lines (%2;%3) and (%4;%5) have no point of intersection") + .arg(initData.name, p1Line1->name(), p2Line1->name(), p1Line2->name(), p2Line2->name()); + } - if (initData.typeCreation == Source::FromGui) - { - initData.id = initData.data->AddGObject(p); - initData.data->AddLine(initData.p1Line1Id, initData.id); - initData.data->AddLine(initData.id, initData.p2Line1Id); - initData.data->AddLine(initData.p1Line2Id, initData.id); - initData.data->AddLine(initData.id, initData.p2Line2Id); - } - else - { - initData.data->UpdateGObject(initData.id, p); - initData.data->AddLine(initData.p1Line1Id, initData.id); - initData.data->AddLine(initData.id, initData.p2Line1Id); - initData.data->AddLine(initData.p1Line2Id, initData.id); - initData.data->AddLine(initData.id, initData.p2Line2Id); - if (initData.parse != Document::FullParse) - { - initData.doc->UpdateToolData(initData.id, initData.data); - } - } + VPointF *p = new VPointF(fPoint, initData.name, initData.mx, initData.my); + p->SetShowLabel(initData.showLabel); - if (initData.parse == Document::FullParse) + if (initData.typeCreation == Source::FromGui) + { + initData.id = initData.data->AddGObject(p); + initData.data->AddLine(initData.p1Line1Id, initData.id); + initData.data->AddLine(initData.id, initData.p2Line1Id); + initData.data->AddLine(initData.p1Line2Id, initData.id); + initData.data->AddLine(initData.id, initData.p2Line2Id); + } + else + { + initData.data->UpdateGObject(initData.id, p); + initData.data->AddLine(initData.p1Line1Id, initData.id); + initData.data->AddLine(initData.id, initData.p2Line1Id); + initData.data->AddLine(initData.p1Line2Id, initData.id); + initData.data->AddLine(initData.id, initData.p2Line2Id); + if (initData.parse != Document::FullParse) { - VAbstractTool::AddRecord(initData.id, Tool::LineIntersect, initData.doc); - VToolLineIntersect *point = new VToolLineIntersect(initData); - initData.scene->addItem(point); - InitToolConnections(initData.scene, point); - VAbstractPattern::AddTool(initData.id, point); - initData.doc->IncrementReferens(p1Line1->getIdTool()); - initData.doc->IncrementReferens(p2Line1->getIdTool()); - initData.doc->IncrementReferens(p1Line2->getIdTool()); - initData.doc->IncrementReferens(p2Line2->getIdTool()); - return point; + initData.doc->UpdateToolData(initData.id, initData.data); } } + + if (initData.parse == Document::FullParse) + { + VAbstractTool::AddRecord(initData.id, Tool::LineIntersect, initData.doc); + VToolLineIntersect *point = new VToolLineIntersect(initData); + initData.scene->addItem(point); + InitToolConnections(initData.scene, point); + VAbstractPattern::AddTool(initData.id, point); + initData.doc->IncrementReferens(p1Line1->getIdTool()); + initData.doc->IncrementReferens(p2Line1->getIdTool()); + initData.doc->IncrementReferens(p1Line2->getIdTool()); + initData.doc->IncrementReferens(p2Line2->getIdTool()); + return point; + } return nullptr; } diff --git a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectionarcs.cpp b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectionarcs.cpp index 96f3bd674..411ad7bb4 100644 --- a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectionarcs.cpp +++ b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectionarcs.cpp @@ -112,7 +112,14 @@ VToolPointOfIntersectionArcs *VToolPointOfIntersectionArcs::Create(VToolPointOfI const QSharedPointer firstArc = initData.data->GeometricObject(initData.firstArcId); const QSharedPointer secondArc = initData.data->GeometricObject(initData.secondArcId); - const QPointF point = FindPoint(firstArc.data(), secondArc.data(), initData.pType); + QPointF point; + const bool success = FindPoint(firstArc.data(), secondArc.data(), initData.pType, &point); + + if (not success) + { + qWarning() << tr("Error calculating point '%1'. Arcs '%2' and '%3' have no point of intersection") + .arg(initData.name, firstArc->name(), secondArc->name()); + } VPointF *p = new VPointF(point, initData.name, initData.mx, initData.my); p->SetShowLabel(initData.showLabel); @@ -145,8 +152,11 @@ VToolPointOfIntersectionArcs *VToolPointOfIntersectionArcs::Create(VToolPointOfI } //--------------------------------------------------------------------------------------------------------------------- -QPointF VToolPointOfIntersectionArcs::FindPoint(const VArc *arc1, const VArc *arc2, const CrossCirclesPoint pType) +bool VToolPointOfIntersectionArcs::FindPoint(const VArc *arc1, const VArc *arc2, const CrossCirclesPoint pType, + QPointF *intersectionPoint) { + SCASSERT(intersectionPoint != nullptr) + QPointF p1, p2; const QPointF centerArc1 = static_cast(arc1->GetCenter()); const QPointF centerArc2 = static_cast(arc2->GetCenter()); @@ -187,24 +197,28 @@ QPointF VToolPointOfIntersectionArcs::FindPoint(const VArc *arc1, const VArc *ar case 2: if (pType == CrossCirclesPoint::FirstPoint) { - return p1; + *intersectionPoint = p1; + return true; } else { - return p2; + *intersectionPoint = p2; + return true; } case 1: if (flagP1) { - return p1; + *intersectionPoint = p1; + return true; } else { - return p2; + *intersectionPoint = p2; + return true; } case 0: default: - return QPointF(); + return false; } break; @@ -212,18 +226,20 @@ QPointF VToolPointOfIntersectionArcs::FindPoint(const VArc *arc1, const VArc *ar case 1: if (arc1->IsIntersectLine(r1Arc1) && arc2->IsIntersectLine(r1Arc2)) { - return p1; + *intersectionPoint = p1; + return true; } else { - return QPointF(); + return false; } case 3: case 0: default: break; } - return QPointF(); + + return false; } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectionarcs.h b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectionarcs.h index 6dcd8bbf9..d03193ea7 100644 --- a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectionarcs.h +++ b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectionarcs.h @@ -67,7 +67,8 @@ public: static VToolPointOfIntersectionArcs *Create(QSharedPointer dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data); static VToolPointOfIntersectionArcs *Create(VToolPointOfIntersectionArcsInitData initData); - static QPointF FindPoint(const VArc *arc1, const VArc *arc2, const CrossCirclesPoint pType); + static bool FindPoint(const VArc *arc1, const VArc *arc2, const CrossCirclesPoint pType, + QPointF *intersectionPoint); static const QString ToolType; virtual int type() const Q_DECL_OVERRIDE {return Type;} enum { Type = UserType + static_cast(Tool::PointOfIntersectionArcs) }; diff --git a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncircles.cpp b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncircles.cpp index 95314ff21..b16257968 100644 --- a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncircles.cpp +++ b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncircles.cpp @@ -124,8 +124,15 @@ VToolPointOfIntersectionCircles::Create(VToolPointOfIntersectionCirclesInitData const VPointF c1Point = *initData.data->GeometricObject(initData.firstCircleCenterId); const VPointF c2Point = *initData.data->GeometricObject(initData.secondCircleCenterId); - const QPointF point = FindPoint(static_cast(c1Point), static_cast(c2Point), calcC1Radius, - calcC2Radius, initData.crossPoint); + QPointF point; + const bool success = FindPoint(static_cast(c1Point), static_cast(c2Point), calcC1Radius, + calcC2Radius, initData.crossPoint, &point); + + if (not success) + { + qWarning() << tr("Error calculating point '%1'. Circles with centers in points '%2' and '%3' have no point " + "of intersection").arg(initData.name, c1Point.name(), c2Point.name()); + } VPointF *p = new VPointF(point, initData.name, initData.mx, initData.my); p->SetShowLabel(initData.showLabel); @@ -158,9 +165,12 @@ VToolPointOfIntersectionCircles::Create(VToolPointOfIntersectionCirclesInitData } //--------------------------------------------------------------------------------------------------------------------- -QPointF VToolPointOfIntersectionCircles::FindPoint(const QPointF &c1Point, const QPointF &c2Point, qreal c1Radius, - qreal c2Radius, const CrossCirclesPoint crossPoint) +bool VToolPointOfIntersectionCircles::FindPoint(const QPointF &c1Point, const QPointF &c2Point, qreal c1Radius, + qreal c2Radius, const CrossCirclesPoint crossPoint, + QPointF *intersectionPoint) { + SCASSERT(intersectionPoint != nullptr) + QPointF p1, p2; const int res = VGObject::IntersectionCircles(c1Point, c1Radius, c2Point, c2Radius, p1, p2); @@ -169,18 +179,21 @@ QPointF VToolPointOfIntersectionCircles::FindPoint(const QPointF &c1Point, const case 2: if (crossPoint == CrossCirclesPoint::FirstPoint) { - return p1; + *intersectionPoint = p1; + return true; } else { - return p2; + *intersectionPoint = p2; + return true; } case 1: - return p1; + *intersectionPoint = p1; + return true; case 3: case 0: default: - return QPointF(); + return false; } } diff --git a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncircles.h b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncircles.h index 7a8820bd6..af7369852 100644 --- a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncircles.h +++ b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncircles.h @@ -71,8 +71,8 @@ public: static VToolPointOfIntersectionCircles *Create(QSharedPointer dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data); static VToolPointOfIntersectionCircles *Create(VToolPointOfIntersectionCirclesInitData &initData); - static QPointF FindPoint(const QPointF &c1Point, const QPointF &c2Point, qreal c1Radius, qreal c2Radius, - const CrossCirclesPoint crossPoint); + static bool FindPoint(const QPointF &c1Point, const QPointF &c2Point, qreal c1Radius, qreal c2Radius, + const CrossCirclesPoint crossPoint, QPointF *intersectionPoint); static const QString ToolType; virtual int type() const Q_DECL_OVERRIDE {return Type;} enum { Type = UserType + static_cast(Tool::PointOfIntersectionCircles) }; diff --git a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncurves.cpp b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncurves.cpp index 9627e9eac..3fc03cebb 100644 --- a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncurves.cpp +++ b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncurves.cpp @@ -115,8 +115,15 @@ VToolPointOfIntersectionCurves *VToolPointOfIntersectionCurves::Create(VToolPoin auto curve1 = initData.data->GeometricObject(initData.firstCurveId); auto curve2 = initData.data->GeometricObject(initData.secondCurveId); - const QPointF point = VToolPointOfIntersectionCurves::FindPoint(curve1->GetPoints(), curve2->GetPoints(), - initData.vCrossPoint, initData.hCrossPoint); + QPointF point; + const bool success = VToolPointOfIntersectionCurves::FindPoint(curve1->GetPoints(), curve2->GetPoints(), + initData.vCrossPoint, initData.hCrossPoint, &point); + + if (not success) + { + qWarning() << tr("Error calculating point '%1'. Curves '%2' and '%3' have no point of intersection") + .arg(initData.name, curve1->name(), curve2->name()); + } VPointF *p = new VPointF(point, initData.name, initData.mx, initData.my); p->SetShowLabel(initData.showLabel); @@ -149,13 +156,16 @@ VToolPointOfIntersectionCurves *VToolPointOfIntersectionCurves::Create(VToolPoin } //--------------------------------------------------------------------------------------------------------------------- -QPointF VToolPointOfIntersectionCurves::FindPoint(const QVector &curve1Points, - const QVector &curve2Points, - VCrossCurvesPoint vCrossPoint, HCrossCurvesPoint hCrossPoint) +bool VToolPointOfIntersectionCurves::FindPoint(const QVector &curve1Points, + const QVector &curve2Points, + VCrossCurvesPoint vCrossPoint, HCrossCurvesPoint hCrossPoint, + QPointF *intersectionPoint) { + SCASSERT(intersectionPoint != nullptr) + if (curve1Points.isEmpty() || curve2Points.isEmpty()) { - return QPointF(); + return false; } QVector intersections; @@ -167,12 +177,13 @@ QPointF VToolPointOfIntersectionCurves::FindPoint(const QVector &curve1 if (intersections.isEmpty()) { - return QPointF(); + return false; } if (intersections.size() == 1) { - return intersections.at(0); + *intersectionPoint = intersections.at(0); + return true; } QVector vIntersections; @@ -219,12 +230,13 @@ QPointF VToolPointOfIntersectionCurves::FindPoint(const QVector &curve1 if (vIntersections.isEmpty()) { - return QPointF(); + return false; } if (vIntersections.size() == 1) { - return vIntersections.at(0); + *intersectionPoint = vIntersections.at(0); + return true; } QPointF crossPoint = vIntersections.at(0); @@ -258,7 +270,8 @@ QPointF VToolPointOfIntersectionCurves::FindPoint(const QVector &curve1 } } - return crossPoint; + *intersectionPoint = crossPoint; + return true; } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncurves.h b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncurves.h index 8f5a3171d..c86c1f2e5 100644 --- a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncurves.h +++ b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncurves.h @@ -69,8 +69,8 @@ public: static VToolPointOfIntersectionCurves *Create(QSharedPointer dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data); static VToolPointOfIntersectionCurves *Create(VToolPointOfIntersectionCurvesInitData initData); - static QPointF FindPoint(const QVector &curve1Points, const QVector &curve2Points, - VCrossCurvesPoint vCrossPoint, HCrossCurvesPoint hCrossPoint); + static bool FindPoint(const QVector &curve1Points, const QVector &curve2Points, + VCrossCurvesPoint vCrossPoint, HCrossCurvesPoint hCrossPoint, QPointF *intersectionPoint); static const QString ToolType; virtual int type() const Q_DECL_OVERRIDE {return Type;} enum { Type = UserType + static_cast(Tool::PointOfIntersectionCurves) }; diff --git a/src/libs/vtools/visualization/line/vistoolpointofintersectionarcs.cpp b/src/libs/vtools/visualization/line/vistoolpointofintersectionarcs.cpp index 136f5c277..2fe6e106e 100644 --- a/src/libs/vtools/visualization/line/vistoolpointofintersectionarcs.cpp +++ b/src/libs/vtools/visualization/line/vistoolpointofintersectionarcs.cpp @@ -78,7 +78,8 @@ void VisToolPointOfIntersectionArcs::RefreshGeometry() const QSharedPointer arc2 = Visualization::data->GeometricObject(arc2Id); DrawPath(arc2Path, arc2->GetPath(), arc2->DirectionArrows(), Qt::darkRed, Qt::SolidLine, Qt::RoundCap); - const QPointF fPoint = VToolPointOfIntersectionArcs::FindPoint(arc1.data(), arc2.data(), crossPoint); + QPointF fPoint; + VToolPointOfIntersectionArcs::FindPoint(arc1.data(), arc2.data(), crossPoint, &fPoint); DrawPoint(point, fPoint, mainColor); } } diff --git a/src/libs/vtools/visualization/line/vistoolpointofintersectioncircles.cpp b/src/libs/vtools/visualization/line/vistoolpointofintersectioncircles.cpp index 526469859..db203ade2 100644 --- a/src/libs/vtools/visualization/line/vistoolpointofintersectioncircles.cpp +++ b/src/libs/vtools/visualization/line/vistoolpointofintersectioncircles.cpp @@ -80,9 +80,10 @@ void VisToolPointOfIntersectionCircles::RefreshGeometry() c2Path->setRect(PointRect(c2Radius)); DrawPoint(c2Path, static_cast(*second), Qt::darkRed, Qt::DashLine); - const QPointF fPoint = VToolPointOfIntersectionCircles::FindPoint(static_cast(*first), - static_cast(*second), - c1Radius, c2Radius, crossPoint); + QPointF fPoint; + VToolPointOfIntersectionCircles::FindPoint(static_cast(*first), + static_cast(*second), + c1Radius, c2Radius, crossPoint, &fPoint); DrawPoint(point, fPoint, mainColor); } } diff --git a/src/libs/vtools/visualization/path/vistoolpointofintersectioncurves.cpp b/src/libs/vtools/visualization/path/vistoolpointofintersectioncurves.cpp index cd2d6afe2..0bdbf2893 100644 --- a/src/libs/vtools/visualization/path/vistoolpointofintersectioncurves.cpp +++ b/src/libs/vtools/visualization/path/vistoolpointofintersectioncurves.cpp @@ -72,8 +72,9 @@ void VisToolPointOfIntersectionCurves::RefreshGeometry() DrawPath(visCurve2, curve2->GetPath(), curve2->DirectionArrows(), supportColor, Qt::SolidLine, Qt::RoundCap); - auto p = VToolPointOfIntersectionCurves::FindPoint(curve1->GetPoints(), curve2->GetPoints(), vCrossPoint, - hCrossPoint); + QPointF p; + VToolPointOfIntersectionCurves::FindPoint(curve1->GetPoints(), curve2->GetPoints(), vCrossPoint, + hCrossPoint, &p); DrawPoint(point, p, mainColor); } } diff --git a/src/test/ValentinaTest/tst_findpoint.cpp b/src/test/ValentinaTest/tst_findpoint.cpp index 3228f1f61..77712d0ac 100644 --- a/src/test/ValentinaTest/tst_findpoint.cpp +++ b/src/test/ValentinaTest/tst_findpoint.cpp @@ -165,9 +165,10 @@ void TST_FindPoint::TestPointOfIntersectionCurves() QFETCH(int, hCross); QFETCH(QPointF, expect); - const QPointF result = VToolPointOfIntersectionCurves::FindPoint(curve1Points, curve2Points, - static_cast(vCross), - static_cast(hCross)); + QPointF result; + VToolPointOfIntersectionCurves::FindPoint(curve1Points, curve2Points, + static_cast(vCross), + static_cast(hCross), &result); QCOMPARE(result.toPoint(), expect.toPoint()); }