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 line2(static_cast<QPointF>(*p1Line2), static_cast<QPointF>(*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;
}

View File

@ -112,7 +112,14 @@ VToolPointOfIntersectionArcs *VToolPointOfIntersectionArcs::Create(VToolPointOfI
const QSharedPointer<VArc> firstArc = initData.data->GeometricObject<VArc>(initData.firstArcId);
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);
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<QPointF>(arc1->GetCenter());
const QPointF centerArc2 = static_cast<QPointF>(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;
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -67,7 +67,8 @@ public:
static VToolPointOfIntersectionArcs *Create(QSharedPointer<DialogTool> 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<int>(Tool::PointOfIntersectionArcs) };

View File

@ -124,8 +124,15 @@ VToolPointOfIntersectionCircles::Create(VToolPointOfIntersectionCirclesInitData
const VPointF c1Point = *initData.data->GeometricObject<VPointF>(initData.firstCircleCenterId);
const VPointF c2Point = *initData.data->GeometricObject<VPointF>(initData.secondCircleCenterId);
const QPointF point = FindPoint(static_cast<QPointF>(c1Point), static_cast<QPointF>(c2Point), calcC1Radius,
calcC2Radius, initData.crossPoint);
QPointF point;
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);
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;
}
}

View File

@ -71,8 +71,8 @@ public:
static VToolPointOfIntersectionCircles *Create(QSharedPointer<DialogTool> 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<int>(Tool::PointOfIntersectionCircles) };

View File

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

View File

@ -69,8 +69,8 @@ public:
static VToolPointOfIntersectionCurves *Create(QSharedPointer<DialogTool> dialog, VMainGraphicsScene *scene,
VAbstractPattern *doc, VContainer *data);
static VToolPointOfIntersectionCurves *Create(VToolPointOfIntersectionCurvesInitData initData);
static QPointF FindPoint(const QVector<QPointF> &curve1Points, const QVector<QPointF> &curve2Points,
VCrossCurvesPoint vCrossPoint, HCrossCurvesPoint hCrossPoint);
static bool FindPoint(const QVector<QPointF> &curve1Points, const QVector<QPointF> &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<int>(Tool::PointOfIntersectionCurves) };

View File

@ -78,7 +78,8 @@ void VisToolPointOfIntersectionArcs::RefreshGeometry()
const QSharedPointer<VArc> arc2 = Visualization::data->GeometricObject<VArc>(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);
}
}

View File

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

View File

@ -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);
}
}

View File

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