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:
parent
975a528560
commit
c2976614ba
|
@ -300,57 +300,59 @@ QVector<QPointF> VAbstractDetail::CorrectEquidistantPoints(const QVector<QPointF
|
||||||
*/
|
*/
|
||||||
QVector<QPointF> VAbstractDetail::CheckLoops(const QVector<QPointF> &points)
|
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 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.";
|
qDebug()<<"Less then 4 points. Doesn't need check for loops.";
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool closed = false;
|
bool closed = false;
|
||||||
if (points.at(0) == points.at(points.size()-1))
|
if (points.first() == points.last())
|
||||||
{
|
{
|
||||||
closed = true;
|
closed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<QPointF> ekvPoints;
|
||||||
|
|
||||||
qint32 i, j;
|
qint32 i, j;
|
||||||
for (i = 0; i < points.size(); ++i)
|
for (i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
/*Last three points no need check.*/
|
/*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));
|
ekvPoints.append(points.at(i));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF crosPoint;
|
QPointF crosPoint;
|
||||||
QLineF::IntersectType intersect = QLineF::NoIntersection;
|
QLineF::IntersectType intersect = QLineF::NoIntersection;
|
||||||
QLineF line1(points.at(i), points.at(i+1));
|
const QLineF line1(points.at(i), points.at(i+1));
|
||||||
for (j = i+2; j < points.size()-1; ++j)
|
// 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);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
intersect = QLineF::NoIntersection;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intersect == QLineF::BoundedIntersection)
|
if (intersect == QLineF::BoundedIntersection)
|
||||||
{
|
{
|
||||||
if (i == 0 && j+1 == points.size()-1 && closed)
|
/*We have found loop.*/
|
||||||
{
|
ekvPoints.append(points.at(i));
|
||||||
/*We got closed contour.*/
|
ekvPoints.append(crosPoint);
|
||||||
ekvPoints.append(points.at(i));
|
i = j;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*We found loop.*/
|
|
||||||
ekvPoints.append(points.at(i));
|
|
||||||
ekvPoints.append(crosPoint);
|
|
||||||
i = j;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*We did not found loop.*/
|
/*We have not found loop.*/
|
||||||
ekvPoints.append(points.at(i));
|
ekvPoints.append(points.at(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,13 +65,12 @@ public:
|
||||||
void setWidth(const qreal &value);
|
void setWidth(const qreal &value);
|
||||||
|
|
||||||
static QVector<QPointF> Equidistant(const QVector<QPointF> &points, const EquidistantType &eqv, qreal width);
|
static QVector<QPointF> Equidistant(const QVector<QPointF> &points, const EquidistantType &eqv, qreal width);
|
||||||
static qreal SumTrapezoids(const QVector<QPointF> &points);
|
static qreal SumTrapezoids(const QVector<QPointF> &points);
|
||||||
|
static QVector<QPointF> CheckLoops(const QVector<QPointF> &points);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static QVector<QPointF> RemoveDublicates(const QVector<QPointF> &points);
|
static QVector<QPointF> RemoveDublicates(const QVector<QPointF> &points);
|
||||||
static QVector<QPointF> CorrectEquidistantPoints(const QVector<QPointF> &points);
|
static QVector<QPointF> CorrectEquidistantPoints(const QVector<QPointF> &points);
|
||||||
static QVector<QPointF> CheckLoops(const QVector<QPointF> &points);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedDataPointer<VAbstractDetailData> d;
|
QSharedDataPointer<VAbstractDetailData> d;
|
||||||
|
|
|
@ -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
|
void TST_VAbstractDetail::Case1() const
|
||||||
{
|
{
|
||||||
const QVector<QPointF> points = InputPointsCase1(); // Input points.
|
const QVector<QPointF> points = InputPointsCase1(); // Input points.
|
||||||
|
|
|
@ -42,6 +42,8 @@ signals:
|
||||||
private slots:
|
private slots:
|
||||||
void EquidistantRemoveLoop() const;
|
void EquidistantRemoveLoop() const;
|
||||||
void SumTrapezoids() const;
|
void SumTrapezoids() const;
|
||||||
|
void PathRemoveLoop_data() const;
|
||||||
|
void PathRemoveLoop() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Case1() const;
|
void Case1() const;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user