Port changes from develop branch.
--HG-- branch : feature
This commit is contained in:
parent
5a95ce9c8a
commit
12162e49e8
|
@ -34,6 +34,7 @@
|
||||||
#include <QLineF>
|
#include <QLineF>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
#include <QPainterPath>
|
||||||
|
|
||||||
const qreal maxL = 2.4;
|
const qreal maxL = 2.4;
|
||||||
|
|
||||||
|
@ -207,7 +208,6 @@ QVector<QPointF> VAbstractPiece::CheckLoops(const QVector<QPointF> &points)
|
||||||
/*If we got less than 4 points no need seek loops.*/
|
/*If we got less than 4 points no need seek loops.*/
|
||||||
if (count < 4)
|
if (count < 4)
|
||||||
{
|
{
|
||||||
qDebug()<<"Less then 4 points. Doesn't need check for loops.";
|
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +235,6 @@ QVector<QPointF> VAbstractPiece::CheckLoops(const QVector<QPointF> &points)
|
||||||
// That's why we parse from the end
|
// That's why we parse from the end
|
||||||
for (j = count-1; j >= i+2; --j)
|
for (j = count-1; j >= i+2; --j)
|
||||||
{
|
{
|
||||||
|
|
||||||
j == count-1 ? jNext = 0 : jNext = j+1;
|
j == count-1 ? jNext = 0 : jNext = j+1;
|
||||||
QLineF line2(points.at(j), points.at(jNext));
|
QLineF line2(points.at(j), points.at(jNext));
|
||||||
|
|
||||||
|
@ -257,11 +256,7 @@ QVector<QPointF> VAbstractPiece::CheckLoops(const QVector<QPointF> &points)
|
||||||
// Method IsPointOnLineviaPDP will check it.
|
// Method IsPointOnLineviaPDP will check it.
|
||||||
if (VGObject::IsPointOnLineviaPDP(points.at(j), points.at(i), points.at(i+1))
|
if (VGObject::IsPointOnLineviaPDP(points.at(j), points.at(i), points.at(i+1))
|
||||||
// Lines are not neighbors
|
// Lines are not neighbors
|
||||||
&& uniqueVertices.size() == 4
|
&& uniqueVertices.size() == 4)
|
||||||
&& line1.p2() != line2.p2()
|
|
||||||
&& line1.p1() != line2.p1()
|
|
||||||
&& line1.p2() != line2.p1()
|
|
||||||
&& line1.p1() != line2.p2())
|
|
||||||
{
|
{
|
||||||
// Left to catch case where segments are on the same line, but do not have real intersections.
|
// Left to catch case where segments are on the same line, but do not have real intersections.
|
||||||
QLineF tmpLine1 = line1;
|
QLineF tmpLine1 = line1;
|
||||||
|
@ -279,57 +274,42 @@ QVector<QPointF> VAbstractPiece::CheckLoops(const QVector<QPointF> &points)
|
||||||
|
|
||||||
if (tmpIntrs1 == QLineF::BoundedIntersection || tmpIntrs2 == QLineF::BoundedIntersection)
|
if (tmpIntrs1 == QLineF::BoundedIntersection || tmpIntrs2 == QLineF::BoundedIntersection)
|
||||||
{ // Now we really sure that lines are on the same lines and have real intersections.
|
{ // Now we really sure that lines are on the same lines and have real intersections.
|
||||||
|
QPointF cPoint;
|
||||||
|
const bool caseFlag = ParallelCrossPoint(line1, line2, cPoint);
|
||||||
|
if (not caseFlag || CheckIntersection(points, i, i+1, j, jNext, cPoint))
|
||||||
|
{
|
||||||
status = ParallelIntersection;
|
status = ParallelIntersection;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (intersect == QLineF::BoundedIntersection)
|
else if (intersect == QLineF::BoundedIntersection)
|
||||||
{
|
{
|
||||||
if (uniqueVertices.size() == 4
|
if (uniqueVertices.size() == 4)
|
||||||
&& line1.p1() != crosPoint
|
{ // Break, but not if lines are neighbors
|
||||||
|
if ((line1.p1() != crosPoint
|
||||||
&& line1.p2() != crosPoint
|
&& line1.p2() != crosPoint
|
||||||
&& line2.p1() != crosPoint
|
&& line2.p1() != crosPoint
|
||||||
&& line2.p2() != crosPoint)
|
&& line2.p2() != crosPoint) || CheckIntersection(points, i, i+1, j, jNext, crosPoint))
|
||||||
{ // Break, but not if lines are neighbors
|
{
|
||||||
status = BoundedIntersection;
|
status = BoundedIntersection;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
status = NoIntersection;
|
status = NoIntersection;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case ParallelIntersection:
|
case ParallelIntersection:
|
||||||
{
|
|
||||||
/*We have found a loop.*/
|
/*We have found a loop.*/
|
||||||
// Very tricky case
|
|
||||||
// See the file "collection/bugs/Issue_#603.val"
|
|
||||||
const QLineF line1(points.at(i+1), points.at(j));
|
|
||||||
const QLineF line2(points.at(i), points.at(jNext));
|
|
||||||
|
|
||||||
if (line1.length() <= line2.length())
|
|
||||||
{
|
|
||||||
// In this case we did not check a loop edges and can just skip them
|
|
||||||
ekvPoints.append(points.at(i));
|
ekvPoints.append(points.at(i));
|
||||||
ekvPoints.append(points.at(jNext));
|
ekvPoints.append(points.at(jNext));
|
||||||
|
jNext > j ? i = jNext : i = j; // Skip a loop
|
||||||
i = j; // Skip a loo
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// In this case a loop edges probably was also chacked and added to the list
|
|
||||||
ekvPoints.clear();// Previous data is wrong and belong to loop.
|
|
||||||
ekvPoints.append(points.at(j));
|
|
||||||
ekvPoints.append(points.at(i+1));
|
|
||||||
|
|
||||||
count = j+1;// All beyond this belong to loop.
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case BoundedIntersection:
|
case BoundedIntersection:
|
||||||
/*We have found a loop.*/
|
|
||||||
ekvPoints.append(points.at(i));
|
ekvPoints.append(points.at(i));
|
||||||
ekvPoints.append(crosPoint);
|
ekvPoints.append(crosPoint);
|
||||||
i = j;
|
i = j;
|
||||||
|
@ -831,3 +811,128 @@ qreal VAbstractPiece::AngleBetweenBisectors(const QLineF &b1, const QLineF &b2)
|
||||||
return angle2;
|
return angle2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool VAbstractPiece::CheckIntersection(const QVector<QPointF> &points, int i, int iNext, int j, int jNext,
|
||||||
|
const QPointF &crossPoint)
|
||||||
|
{
|
||||||
|
QVector<QPointF> sub1 = SubPath(points, iNext, j);
|
||||||
|
sub1.append(crossPoint);
|
||||||
|
sub1 = CheckLoops(CorrectEquidistantPoints(sub1, false));
|
||||||
|
const qreal sub1Sum = SumTrapezoids(sub1);
|
||||||
|
|
||||||
|
QVector<QPointF> sub2 = SubPath(points, jNext, i);
|
||||||
|
sub2.append(crossPoint);
|
||||||
|
sub2 = CheckLoops(CorrectEquidistantPoints(sub2, false));
|
||||||
|
const qreal sub2Sum = SumTrapezoids(sub2);
|
||||||
|
|
||||||
|
if (sub1Sum < 0 && sub2Sum < 0)
|
||||||
|
{
|
||||||
|
if (Crossing(sub1, sub2))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (not Crossing(sub1, sub2))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool VAbstractPiece::ParallelCrossPoint(const QLineF &line1, const QLineF &line2, QPointF &point)
|
||||||
|
{
|
||||||
|
const bool l1p1el2p1 = (line1.p1() == line2.p1());
|
||||||
|
const bool l1p2el2p2 = (line1.p2() == line2.p2());
|
||||||
|
const bool l1p1el2p2 = (line1.p1() == line2.p2());
|
||||||
|
const bool l1p2el2p1 = (line1.p2() == line2.p1());
|
||||||
|
|
||||||
|
if (l1p2el2p2 || l1p2el2p1)
|
||||||
|
{
|
||||||
|
point = line1.p2();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (l1p1el2p1 || l1p1el2p2)
|
||||||
|
{
|
||||||
|
point = line1.p1();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
point = QPointF();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool VAbstractPiece::Crossing(const QVector<QPointF> &sub1, const QVector<QPointF> &sub2)
|
||||||
|
{
|
||||||
|
if (sub1.isEmpty() || sub2.isEmpty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QRectF sub1Rect = QPolygonF(sub1).boundingRect();
|
||||||
|
const QRectF sub2Rect = QPolygonF(sub2).boundingRect();
|
||||||
|
if (not sub1Rect.intersects(sub2Rect))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainterPath sub1Path;
|
||||||
|
sub1Path.setFillRule(Qt::WindingFill);
|
||||||
|
sub1Path.moveTo(sub1.at(0));
|
||||||
|
for (qint32 i = 1; i < sub1.count(); ++i)
|
||||||
|
{
|
||||||
|
sub1Path.lineTo(sub1.at(i));
|
||||||
|
}
|
||||||
|
sub1Path.lineTo(sub1.at(0));
|
||||||
|
|
||||||
|
QPainterPath sub2Path;
|
||||||
|
sub2Path.setFillRule(Qt::WindingFill);
|
||||||
|
sub2Path.moveTo(sub2.at(0));
|
||||||
|
for (qint32 i = 1; i < sub2.count(); ++i)
|
||||||
|
{
|
||||||
|
sub2Path.lineTo(sub2.at(i));
|
||||||
|
}
|
||||||
|
sub2Path.lineTo(sub2.at(0));
|
||||||
|
|
||||||
|
if (not sub1Path.intersects(sub2Path))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
QVector<QPointF> VAbstractPiece::SubPath(const QVector<QPointF> &path, int startIndex, int endIndex)
|
||||||
|
{
|
||||||
|
if (path.isEmpty()
|
||||||
|
|| startIndex < 0 || startIndex >= path.size()
|
||||||
|
|| endIndex < 0 || endIndex >= path.size()
|
||||||
|
|| startIndex == endIndex)
|
||||||
|
{
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QPointF> subPath;
|
||||||
|
int i = startIndex - 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if (i >= path.size())
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
subPath.append(path.at(i));
|
||||||
|
} while (i != endIndex);
|
||||||
|
|
||||||
|
return subPath;
|
||||||
|
}
|
||||||
|
|
|
@ -170,6 +170,11 @@ protected:
|
||||||
private:
|
private:
|
||||||
QSharedDataPointer<VAbstractPieceData> d;
|
QSharedDataPointer<VAbstractPieceData> d;
|
||||||
|
|
||||||
|
static bool CheckIntersection(const QVector<QPointF> &points, int i, int iNext, int j, int jNext,
|
||||||
|
const QPointF &crossPoint);
|
||||||
|
static bool ParallelCrossPoint(const QLineF &line1, const QLineF &line2, QPointF &point);
|
||||||
|
static bool Crossing(const QVector<QPointF> &sub1, const QVector<QPointF> &sub2);
|
||||||
|
static QVector<QPointF> SubPath(const QVector<QPointF> &path, int startIndex, int endIndex);
|
||||||
static Q_DECL_CONSTEXPR qreal PointPosition(const QPointF &p, const QLineF &line);
|
static Q_DECL_CONSTEXPR qreal PointPosition(const QPointF &p, const QLineF &line);
|
||||||
static qreal MaxLocalSA(const VSAPoint &p, qreal width);
|
static qreal MaxLocalSA(const VSAPoint &p, qreal width);
|
||||||
static QVector<QPointF> EkvPoint(const VSAPoint &p1Line1, const VSAPoint &p2Line1,
|
static QVector<QPointF> EkvPoint(const VSAPoint &p1Line1, const VSAPoint &p2Line1,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user