Correct removing loop if a path contains them several. Seek and remove the last.

In this way we will correct remove them all.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2016-01-09 23:53:17 +02:00
parent 975a528560
commit c2976614ba
4 changed files with 149 additions and 26 deletions

View File

@ -300,57 +300,59 @@ QVector<QPointF> VAbstractDetail::CorrectEquidistantPoints(const QVector<QPointF
*/
QVector<QPointF> VAbstractDetail::CheckLoops(const QVector<QPointF> &points)
{
QVector<QPointF> ekvPoints;
const int count = points.size();
/*If we got less than 4 points no need seek loops.*/
if (points.size() < 4)
if (count < 4)
{
qDebug()<<"Less then 4 points. Doesn't need check for loops.";
return points;
}
bool closed = false;
if (points.at(0) == points.at(points.size()-1))
if (points.first() == points.last())
{
closed = true;
}
QVector<QPointF> ekvPoints;
qint32 i, j;
for (i = 0; i < points.size(); ++i)
for (i = 0; i < count; ++i)
{
/*Last three points no need check.*/
if (i >= points.size()-3)
/*Triangle has not contain loops*/
if (i >= count-3)
{
ekvPoints.append(points.at(i));
continue;
}
QPointF crosPoint;
QLineF::IntersectType intersect = QLineF::NoIntersection;
QLineF line1(points.at(i), points.at(i+1));
for (j = i+2; j < points.size()-1; ++j)
const QLineF line1(points.at(i), points.at(i+1));
// Because a path can contains several loops we will seek the last and only then remove the loop(s)
// That's why we parse from the end
for (j = count-2; j >= i+2; --j)
{
QLineF line2(points.at(j), points.at(j+1));
const QLineF line2(points.at(j), points.at(j+1));
intersect = line1.intersect(line2, &crosPoint);
if (intersect == QLineF::BoundedIntersection)
{
if (intersect == QLineF::BoundedIntersection && not (i == 0 && j+1 == count-1 && closed))
{ // Break, but not if intersects the first edge and the last edge in closed path
break;
}
intersect = QLineF::NoIntersection;
}
if (intersect == QLineF::BoundedIntersection)
{
if (i == 0 && j+1 == points.size()-1 && closed)
{
/*We got closed contour.*/
ekvPoints.append(points.at(i));
}
else
{
/*We found loop.*/
/*We have found loop.*/
ekvPoints.append(points.at(i));
ekvPoints.append(crosPoint);
i = j;
}
}
else
{
/*We did not found loop.*/
/*We have not found loop.*/
ekvPoints.append(points.at(i));
}
}

View File

@ -66,12 +66,11 @@ public:
static QVector<QPointF> Equidistant(const QVector<QPointF> &points, const EquidistantType &eqv, qreal width);
static qreal SumTrapezoids(const QVector<QPointF> &points);
static QVector<QPointF> CheckLoops(const QVector<QPointF> &points);
protected:
static QVector<QPointF> RemoveDublicates(const QVector<QPointF> &points);
static QVector<QPointF> CorrectEquidistantPoints(const QVector<QPointF> &points);
static QVector<QPointF> CheckLoops(const QVector<QPointF> &points);
private:
QSharedDataPointer<VAbstractDetailData> d;

View File

@ -64,7 +64,127 @@ void TST_VAbstractDetail::SumTrapezoids() const
}
//---------------------------------------------------------------------------------------------------------------------
void TST_VAbstractDetail::PathRemoveLoop_data() const
{
QTest::addColumn<QVector<QPointF>>("path");
QTest::addColumn<QVector<QPointF>>("expect");
QVector<QPointF> path;
path << QPointF(10, 10);
path << QPointF(20, 10);
path << QPointF(20, 20);
path << QPointF(10, 20);
path << QPointF(10, 10);
QTest::newRow("Correct closed a path (four unique points)") << path << path;
path.removeLast();
QTest::newRow("Correct unclosed a path (four unique points)") << path << path;
path.clear();
path << QPointF(0, 10);
path << QPointF(10, 10);
path << QPointF(20, 10);
path << QPointF(20, 20);
path << QPointF(10, 20);
path << QPointF(0, 20);
path << QPointF(0, 10);
QTest::newRow("Correct closed a path (six unique points)") << path << path;
path.removeLast();
QTest::newRow("Correct unclosed a path (six unique points)") << path << path;
path.clear();
path << QPointF(20, 10);
path << QPointF(10, 20);
path << QPointF(10, 10);
path << QPointF(20, 20);
path << QPointF(20, 10);
QVector<QPointF> res;
res << QPointF(20, 10);
res << QPointF(15, 15);
res << QPointF(20, 20);
res << QPointF(20, 10);
QTest::newRow("One loop, closed a path (four unique points)") << path << res;
path.removeLast();
res.removeLast();
QTest::newRow("One loop, unclosed a path (four unique points)") << path << res;
path.clear();
path << QPointF(20, 10);
path << QPointF(10, 20);
path << QPointF(0, 10);
path << QPointF(0, 20);
path << QPointF(10, 10);
path << QPointF(20, 20);
path << QPointF(20, 10);
res.clear();
res << QPointF(20, 10);
res << QPointF(15, 15);
res << QPointF(20, 20);
res << QPointF(20, 10);
QTest::newRow("Two loops, closed a path (six unique points)") << path << res;
path.removeLast();
res.removeLast();
QTest::newRow("Two loops, unclosed a path (six unique points)") << path << res;
path.clear();
path << QPointF(20, 10);
path << QPointF(10, 20);
path << QPointF(0, 20);
path << QPointF(0, 10);
path << QPointF(10, 10);
path << QPointF(20, 20);
path << QPointF(20, 10);
res.clear();
res << QPointF(20, 10);
res << QPointF(15, 15);
res << QPointF(20, 20);
res << QPointF(20, 10);
QTest::newRow("One loop, the first loop, closed a path (six unique points)") << path << res;
path.removeLast();
res.removeLast();
QTest::newRow("One loop, the first loop, unclosed a path (six unique points)") << path << res;
path.clear();
path << QPointF(20, 10);
path << QPointF(10, 10);
path << QPointF(0, 20);
path << QPointF(0, 10);
path << QPointF(10, 20);
path << QPointF(20, 20);
path << QPointF(20, 10);
res.clear();
res << QPointF(20, 10);
res << QPointF(10, 10);
res << QPointF(5, 15);
res << QPointF(10, 20);
res << QPointF(20, 20);
res << QPointF(20, 10);
QTest::newRow("One loop, the second loop, closed a path (six unique points)") << path << res;
path.removeLast();
res.removeLast();
QTest::newRow("One loop, the second loop, unclosed a path (six unique points)") << path << res;
}
//---------------------------------------------------------------------------------------------------------------------
void TST_VAbstractDetail::PathRemoveLoop() const
{
QFETCH(QVector<QPointF>, path);
QFETCH(QVector<QPointF>, expect);
QVector<QPointF> res = VAbstractDetail::CheckLoops(path);
Comparison(res, expect);
}
//---------------------------------------------------------------------------------------------------------------------
void TST_VAbstractDetail::Case1() const
{
const QVector<QPointF> points = InputPointsCase1(); // Input points.

View File

@ -42,6 +42,8 @@ signals:
private slots:
void EquidistantRemoveLoop() const;
void SumTrapezoids() const;
void PathRemoveLoop_data() const;
void PathRemoveLoop() const;
private:
void Case1() const;