diff --git a/src/libs/vgeometry/vgobject.cpp b/src/libs/vgeometry/vgobject.cpp index 1ca2235a0..d7bb0cea7 100644 --- a/src/libs/vgeometry/vgobject.cpp +++ b/src/libs/vgeometry/vgobject.cpp @@ -450,12 +450,12 @@ void VGObject::LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c * * Original idea http://www.sunshine2k.de/coding/java/PointOnLine/PointOnLine.html */ -bool VGObject::IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const QPointF &p2) +bool VGObject::IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const QPointF &p2, qreal accuracy) { - auto InsideRange = [](qreal p1, qreal p2, qreal t) + auto InsideRange = [accuracy](qreal p1, qreal p2, qreal t) { return not ( not ((p1 <= t && t <= p2) || (p2 <= t && t <= p1)) - && not (qAbs(p1 - t) <= accuracyPointOnLine) && not (qAbs(p2 - t) <= accuracyPointOnLine)); + && not (qAbs(p1 - t) <= accuracy) && not (qAbs(p2 - t) <= accuracy)); }; if (not InsideRange(p1.x(), p2.x(), t.x())) @@ -469,7 +469,7 @@ bool VGObject::IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const Q } // Test via the perp dot product (PDP) - return IsPointOnLineviaPDP(t, p1, p2); + return IsPointOnLineviaPDP(t, p1, p2, accuracy); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vgeometry/vgobject.h b/src/libs/vgeometry/vgobject.h index b913d0599..be1790b7b 100644 --- a/src/libs/vgeometry/vgobject.h +++ b/src/libs/vgeometry/vgobject.h @@ -96,7 +96,8 @@ public: static QPointF ClosestPoint(const QLineF &line, const QPointF &point); static QPointF addVector (const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k); static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c); - static bool IsPointOnLineSegment (const QPointF &t, const QPointF &p1, const QPointF &p2); + static bool IsPointOnLineSegment (const QPointF &t, const QPointF &p1, const QPointF &p2, + qreal accuracy = accuracyPointOnLine); static QPointF CorrectDistortion(const QPointF &t, const QPointF &p1, const QPointF &p2); static bool IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2, qreal accuracy = accuracyPointOnLine); diff --git a/src/libs/vlayout/vcontour.cpp b/src/libs/vlayout/vcontour.cpp index 88d957263..acb485904 100644 --- a/src/libs/vlayout/vcontour.cpp +++ b/src/libs/vlayout/vcontour.cpp @@ -57,6 +57,43 @@ void AppendToContour(QVector &contour, QPointF point) contour.append(point); } } + +//--------------------------------------------------------------------------------------------------------------------- +QVector OptimizeCombining(const QVector &contour, const QPointF &withdrawEnd) +{ + if (contour.size() < 2) + { + return contour; + } + + QPointF withdrawFirst = contour.last(); + bool optimize = false; + int count = 0; + int cutIndex = -1; + + for (int i = contour.size() - 2; i >= 0; --i) + { + if (not VGObject::IsPointOnLineSegment(contour.at(i), withdrawFirst, withdrawEnd, accuracyPointOnLine*2)) + { + optimize = true; + cutIndex = i+1; + break; + } + else + { + ++count; + } + } + + if (optimize && count > 0) + { + return contour.mid(0, cutIndex+1); + } + else + { + return contour; + } +} } //--------------------------------------------------------------------------------------------------------------------- @@ -306,6 +343,9 @@ void VContour::AppendWhole(QVector &contour, const VLayoutPiece &detail int processedEdges = 0; const int nD = detail.LayoutEdgesCount(); int j = detJ; + + contour = OptimizeCombining(contour, detail.LayoutEdge(j).p2()); + do { if (j >= nD) @@ -329,6 +369,9 @@ void VContour::InsertDetail(QVector &contour, const VLayoutPiece &detai int processedEdges = 0; const int nD = detail.LayoutEdgesCount(); int j = detJ; + + contour = OptimizeCombining(contour, detail.LayoutEdge(j).p2()); + do { if (j >= nD)