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
This commit is contained in:
Roman Telezhynskyi 2018-05-25 17:52:35 +03:00
parent bb95c3162b
commit 270f3b44a1
11 changed files with 128 additions and 78 deletions

View File

@ -140,47 +140,50 @@ VToolLineIntersect* VToolLineIntersect::Create(VToolLineIntersectInitData initDa
QLineF line1(static_cast<QPointF>(*p1Line1), static_cast<QPointF>(*p2Line1)); QLineF line1(static_cast<QPointF>(*p1Line1), static_cast<QPointF>(*p2Line1));
QLineF line2(static_cast<QPointF>(*p1Line2), static_cast<QPointF>(*p2Line2)); QLineF line2(static_cast<QPointF>(*p1Line2), static_cast<QPointF>(*p2Line2));
QPointF fPoint; QPointF fPoint;
QLineF::IntersectType intersect = line1.intersect(line2, &fPoint); const QLineF::IntersectType intersect = line1.intersect(line2, &fPoint);
if (intersect == QLineF::UnboundedIntersection || intersect == QLineF::BoundedIntersection) if (intersect == QLineF::NoIntersection)
{ {
VPointF *p = new VPointF(fPoint, initData.name, initData.mx, initData.my); qWarning() << tr("Error calculating point '%1'. Lines (%2;%3) and (%4;%5) have no point of intersection")
p->SetShowLabel(initData.showLabel); .arg(initData.name, p1Line1->name(), p2Line1->name(), p1Line2->name(), p2Line2->name());
}
if (initData.typeCreation == Source::FromGui) VPointF *p = new VPointF(fPoint, initData.name, initData.mx, initData.my);
{ p->SetShowLabel(initData.showLabel);
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);
}
}
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); initData.doc->UpdateToolData(initData.id, initData.data);
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;
} }
} }
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; return nullptr;
} }

View File

@ -112,7 +112,14 @@ VToolPointOfIntersectionArcs *VToolPointOfIntersectionArcs::Create(VToolPointOfI
const QSharedPointer<VArc> firstArc = initData.data->GeometricObject<VArc>(initData.firstArcId); const QSharedPointer<VArc> firstArc = initData.data->GeometricObject<VArc>(initData.firstArcId);
const QSharedPointer<VArc> secondArc = initData.data->GeometricObject<VArc>(initData.secondArcId); const QSharedPointer<VArc> secondArc = initData.data->GeometricObject<VArc>(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); VPointF *p = new VPointF(point, initData.name, initData.mx, initData.my);
p->SetShowLabel(initData.showLabel); 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; QPointF p1, p2;
const QPointF centerArc1 = static_cast<QPointF>(arc1->GetCenter()); const QPointF centerArc1 = static_cast<QPointF>(arc1->GetCenter());
const QPointF centerArc2 = static_cast<QPointF>(arc2->GetCenter()); const QPointF centerArc2 = static_cast<QPointF>(arc2->GetCenter());
@ -187,24 +197,28 @@ QPointF VToolPointOfIntersectionArcs::FindPoint(const VArc *arc1, const VArc *ar
case 2: case 2:
if (pType == CrossCirclesPoint::FirstPoint) if (pType == CrossCirclesPoint::FirstPoint)
{ {
return p1; *intersectionPoint = p1;
return true;
} }
else else
{ {
return p2; *intersectionPoint = p2;
return true;
} }
case 1: case 1:
if (flagP1) if (flagP1)
{ {
return p1; *intersectionPoint = p1;
return true;
} }
else else
{ {
return p2; *intersectionPoint = p2;
return true;
} }
case 0: case 0:
default: default:
return QPointF(); return false;
} }
break; break;
@ -212,18 +226,20 @@ QPointF VToolPointOfIntersectionArcs::FindPoint(const VArc *arc1, const VArc *ar
case 1: case 1:
if (arc1->IsIntersectLine(r1Arc1) && arc2->IsIntersectLine(r1Arc2)) if (arc1->IsIntersectLine(r1Arc1) && arc2->IsIntersectLine(r1Arc2))
{ {
return p1; *intersectionPoint = p1;
return true;
} }
else else
{ {
return QPointF(); return false;
} }
case 3: case 3:
case 0: case 0:
default: default:
break; break;
} }
return QPointF();
return false;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -67,7 +67,8 @@ public:
static VToolPointOfIntersectionArcs *Create(QSharedPointer<DialogTool> dialog, VMainGraphicsScene *scene, static VToolPointOfIntersectionArcs *Create(QSharedPointer<DialogTool> dialog, VMainGraphicsScene *scene,
VAbstractPattern *doc, VContainer *data); VAbstractPattern *doc, VContainer *data);
static VToolPointOfIntersectionArcs *Create(VToolPointOfIntersectionArcsInitData initData); 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; static const QString ToolType;
virtual int type() const Q_DECL_OVERRIDE {return Type;} virtual int type() const Q_DECL_OVERRIDE {return Type;}
enum { Type = UserType + static_cast<int>(Tool::PointOfIntersectionArcs) }; enum { Type = UserType + static_cast<int>(Tool::PointOfIntersectionArcs) };

View File

@ -124,8 +124,15 @@ VToolPointOfIntersectionCircles::Create(VToolPointOfIntersectionCirclesInitData
const VPointF c1Point = *initData.data->GeometricObject<VPointF>(initData.firstCircleCenterId); const VPointF c1Point = *initData.data->GeometricObject<VPointF>(initData.firstCircleCenterId);
const VPointF c2Point = *initData.data->GeometricObject<VPointF>(initData.secondCircleCenterId); const VPointF c2Point = *initData.data->GeometricObject<VPointF>(initData.secondCircleCenterId);
const QPointF point = FindPoint(static_cast<QPointF>(c1Point), static_cast<QPointF>(c2Point), calcC1Radius, QPointF point;
calcC2Radius, initData.crossPoint); const bool success = FindPoint(static_cast<QPointF>(c1Point), static_cast<QPointF>(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); VPointF *p = new VPointF(point, initData.name, initData.mx, initData.my);
p->SetShowLabel(initData.showLabel); p->SetShowLabel(initData.showLabel);
@ -158,9 +165,12 @@ VToolPointOfIntersectionCircles::Create(VToolPointOfIntersectionCirclesInitData
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPointF VToolPointOfIntersectionCircles::FindPoint(const QPointF &c1Point, const QPointF &c2Point, qreal c1Radius, bool VToolPointOfIntersectionCircles::FindPoint(const QPointF &c1Point, const QPointF &c2Point, qreal c1Radius,
qreal c2Radius, const CrossCirclesPoint crossPoint) qreal c2Radius, const CrossCirclesPoint crossPoint,
QPointF *intersectionPoint)
{ {
SCASSERT(intersectionPoint != nullptr)
QPointF p1, p2; QPointF p1, p2;
const int res = VGObject::IntersectionCircles(c1Point, c1Radius, c2Point, c2Radius, 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: case 2:
if (crossPoint == CrossCirclesPoint::FirstPoint) if (crossPoint == CrossCirclesPoint::FirstPoint)
{ {
return p1; *intersectionPoint = p1;
return true;
} }
else else
{ {
return p2; *intersectionPoint = p2;
return true;
} }
case 1: case 1:
return p1; *intersectionPoint = p1;
return true;
case 3: case 3:
case 0: case 0:
default: default:
return QPointF(); return false;
} }
} }

View File

@ -71,8 +71,8 @@ public:
static VToolPointOfIntersectionCircles *Create(QSharedPointer<DialogTool> dialog, VMainGraphicsScene *scene, static VToolPointOfIntersectionCircles *Create(QSharedPointer<DialogTool> dialog, VMainGraphicsScene *scene,
VAbstractPattern *doc, VContainer *data); VAbstractPattern *doc, VContainer *data);
static VToolPointOfIntersectionCircles *Create(VToolPointOfIntersectionCirclesInitData &initData); static VToolPointOfIntersectionCircles *Create(VToolPointOfIntersectionCirclesInitData &initData);
static QPointF FindPoint(const QPointF &c1Point, const QPointF &c2Point, qreal c1Radius, qreal c2Radius, static bool FindPoint(const QPointF &c1Point, const QPointF &c2Point, qreal c1Radius, qreal c2Radius,
const CrossCirclesPoint crossPoint); const CrossCirclesPoint crossPoint, QPointF *intersectionPoint);
static const QString ToolType; static const QString ToolType;
virtual int type() const Q_DECL_OVERRIDE {return Type;} virtual int type() const Q_DECL_OVERRIDE {return Type;}
enum { Type = UserType + static_cast<int>(Tool::PointOfIntersectionCircles) }; enum { Type = UserType + static_cast<int>(Tool::PointOfIntersectionCircles) };

View File

@ -115,8 +115,15 @@ VToolPointOfIntersectionCurves *VToolPointOfIntersectionCurves::Create(VToolPoin
auto curve1 = initData.data->GeometricObject<VAbstractCurve>(initData.firstCurveId); auto curve1 = initData.data->GeometricObject<VAbstractCurve>(initData.firstCurveId);
auto curve2 = initData.data->GeometricObject<VAbstractCurve>(initData.secondCurveId); auto curve2 = initData.data->GeometricObject<VAbstractCurve>(initData.secondCurveId);
const QPointF point = VToolPointOfIntersectionCurves::FindPoint(curve1->GetPoints(), curve2->GetPoints(), QPointF point;
initData.vCrossPoint, initData.hCrossPoint); 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); VPointF *p = new VPointF(point, initData.name, initData.mx, initData.my);
p->SetShowLabel(initData.showLabel); p->SetShowLabel(initData.showLabel);
@ -149,13 +156,16 @@ VToolPointOfIntersectionCurves *VToolPointOfIntersectionCurves::Create(VToolPoin
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPointF VToolPointOfIntersectionCurves::FindPoint(const QVector<QPointF> &curve1Points, bool VToolPointOfIntersectionCurves::FindPoint(const QVector<QPointF> &curve1Points,
const QVector<QPointF> &curve2Points, const QVector<QPointF> &curve2Points,
VCrossCurvesPoint vCrossPoint, HCrossCurvesPoint hCrossPoint) VCrossCurvesPoint vCrossPoint, HCrossCurvesPoint hCrossPoint,
QPointF *intersectionPoint)
{ {
SCASSERT(intersectionPoint != nullptr)
if (curve1Points.isEmpty() || curve2Points.isEmpty()) if (curve1Points.isEmpty() || curve2Points.isEmpty())
{ {
return QPointF(); return false;
} }
QVector<QPointF> intersections; QVector<QPointF> intersections;
@ -167,12 +177,13 @@ QPointF VToolPointOfIntersectionCurves::FindPoint(const QVector<QPointF> &curve1
if (intersections.isEmpty()) if (intersections.isEmpty())
{ {
return QPointF(); return false;
} }
if (intersections.size() == 1) if (intersections.size() == 1)
{ {
return intersections.at(0); *intersectionPoint = intersections.at(0);
return true;
} }
QVector<QPointF> vIntersections; QVector<QPointF> vIntersections;
@ -219,12 +230,13 @@ QPointF VToolPointOfIntersectionCurves::FindPoint(const QVector<QPointF> &curve1
if (vIntersections.isEmpty()) if (vIntersections.isEmpty())
{ {
return QPointF(); return false;
} }
if (vIntersections.size() == 1) if (vIntersections.size() == 1)
{ {
return vIntersections.at(0); *intersectionPoint = vIntersections.at(0);
return true;
} }
QPointF crossPoint = vIntersections.at(0); QPointF crossPoint = vIntersections.at(0);
@ -258,7 +270,8 @@ QPointF VToolPointOfIntersectionCurves::FindPoint(const QVector<QPointF> &curve1
} }
} }
return crossPoint; *intersectionPoint = crossPoint;
return true;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -69,8 +69,8 @@ public:
static VToolPointOfIntersectionCurves *Create(QSharedPointer<DialogTool> dialog, VMainGraphicsScene *scene, static VToolPointOfIntersectionCurves *Create(QSharedPointer<DialogTool> dialog, VMainGraphicsScene *scene,
VAbstractPattern *doc, VContainer *data); VAbstractPattern *doc, VContainer *data);
static VToolPointOfIntersectionCurves *Create(VToolPointOfIntersectionCurvesInitData initData); static VToolPointOfIntersectionCurves *Create(VToolPointOfIntersectionCurvesInitData initData);
static QPointF FindPoint(const QVector<QPointF> &curve1Points, const QVector<QPointF> &curve2Points, static bool FindPoint(const QVector<QPointF> &curve1Points, const QVector<QPointF> &curve2Points,
VCrossCurvesPoint vCrossPoint, HCrossCurvesPoint hCrossPoint); VCrossCurvesPoint vCrossPoint, HCrossCurvesPoint hCrossPoint, QPointF *intersectionPoint);
static const QString ToolType; static const QString ToolType;
virtual int type() const Q_DECL_OVERRIDE {return Type;} virtual int type() const Q_DECL_OVERRIDE {return Type;}
enum { Type = UserType + static_cast<int>(Tool::PointOfIntersectionCurves) }; enum { Type = UserType + static_cast<int>(Tool::PointOfIntersectionCurves) };

View File

@ -78,7 +78,8 @@ void VisToolPointOfIntersectionArcs::RefreshGeometry()
const QSharedPointer<VArc> arc2 = Visualization::data->GeometricObject<VArc>(arc2Id); const QSharedPointer<VArc> arc2 = Visualization::data->GeometricObject<VArc>(arc2Id);
DrawPath(arc2Path, arc2->GetPath(), arc2->DirectionArrows(), Qt::darkRed, Qt::SolidLine, Qt::RoundCap); 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); DrawPoint(point, fPoint, mainColor);
} }
} }

View File

@ -80,9 +80,10 @@ void VisToolPointOfIntersectionCircles::RefreshGeometry()
c2Path->setRect(PointRect(c2Radius)); c2Path->setRect(PointRect(c2Radius));
DrawPoint(c2Path, static_cast<QPointF>(*second), Qt::darkRed, Qt::DashLine); DrawPoint(c2Path, static_cast<QPointF>(*second), Qt::darkRed, Qt::DashLine);
const QPointF fPoint = VToolPointOfIntersectionCircles::FindPoint(static_cast<QPointF>(*first), QPointF fPoint;
static_cast<QPointF>(*second), VToolPointOfIntersectionCircles::FindPoint(static_cast<QPointF>(*first),
c1Radius, c2Radius, crossPoint); static_cast<QPointF>(*second),
c1Radius, c2Radius, crossPoint, &fPoint);
DrawPoint(point, fPoint, mainColor); DrawPoint(point, fPoint, mainColor);
} }
} }

View File

@ -72,8 +72,9 @@ void VisToolPointOfIntersectionCurves::RefreshGeometry()
DrawPath(visCurve2, curve2->GetPath(), curve2->DirectionArrows(), supportColor, Qt::SolidLine, DrawPath(visCurve2, curve2->GetPath(), curve2->DirectionArrows(), supportColor, Qt::SolidLine,
Qt::RoundCap); Qt::RoundCap);
auto p = VToolPointOfIntersectionCurves::FindPoint(curve1->GetPoints(), curve2->GetPoints(), vCrossPoint, QPointF p;
hCrossPoint); VToolPointOfIntersectionCurves::FindPoint(curve1->GetPoints(), curve2->GetPoints(), vCrossPoint,
hCrossPoint, &p);
DrawPoint(point, p, mainColor); DrawPoint(point, p, mainColor);
} }
} }

View File

@ -165,9 +165,10 @@ void TST_FindPoint::TestPointOfIntersectionCurves()
QFETCH(int, hCross); QFETCH(int, hCross);
QFETCH(QPointF, expect); QFETCH(QPointF, expect);
const QPointF result = VToolPointOfIntersectionCurves::FindPoint(curve1Points, curve2Points, QPointF result;
static_cast<VCrossCurvesPoint>(vCross), VToolPointOfIntersectionCurves::FindPoint(curve1Points, curve2Points,
static_cast<HCrossCurvesPoint>(hCross)); static_cast<VCrossCurvesPoint>(vCross),
static_cast<HCrossCurvesPoint>(hCross), &result);
QCOMPARE(result.toPoint(), expect.toPoint()); QCOMPARE(result.toPoint(), expect.toPoint());
} }