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> 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.*/
|
||||
ekvPoints.append(points.at(i));
|
||||
ekvPoints.append(crosPoint);
|
||||
i = j;
|
||||
}
|
||||
/*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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,13 +65,12 @@ public:
|
|||
void setWidth(const qreal &value);
|
||||
|
||||
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:
|
||||
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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -42,6 +42,8 @@ signals:
|
|||
private slots:
|
||||
void EquidistantRemoveLoop() const;
|
||||
void SumTrapezoids() const;
|
||||
void PathRemoveLoop_data() const;
|
||||
void PathRemoveLoop() const;
|
||||
|
||||
private:
|
||||
void Case1() const;
|
||||
|
|
Loading…
Reference in New Issue
Block a user