Add QPolygon::intersects() methods

Corresponds to the similar function QPainterPath::intersects() and is
faster than calculating the intersection and then checking if it is
empty.

Change-Id: I694bb2206ed330a456a41d4118a952a68177b7a2
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
bb10
Allan Sandfeld Jensen 2017-05-12 16:50:24 +02:00
parent acc134c8ea
commit c25bce109e
3 changed files with 89 additions and 0 deletions

View File

@ -909,6 +909,8 @@ QPolygon QPolygon::united(const QPolygon &r) const
Set operations on polygons will treat the polygons as
areas. Non-closed polygons will be treated as implicitly closed.
\sa intersects()
*/
QPolygon QPolygon::intersected(const QPolygon &r) const
@ -937,6 +939,26 @@ QPolygon QPolygon::subtracted(const QPolygon &r) const
return subject.subtracted(clip).toFillPolygon().toPolygon();
}
/*!
\since 5.10
Returns \c true if the current polygon intersects at any point the given polygon \a p.
Also returns \c true if the current polygon contains or is contained by any part of \a p.
Set operations on polygons will treat the polygons as
areas. Non-closed polygons will be treated as implicitly closed.
\sa intersected()
*/
bool QPolygon::intersects(const QPolygon &p) const
{
QPainterPath subject; subject.addPolygon(*this);
QPainterPath clip; clip.addPolygon(p);
return subject.intersects(clip);
}
/*!
\since 4.3
@ -964,6 +986,7 @@ QPolygonF QPolygonF::united(const QPolygonF &r) const
Set operations on polygons will treat the polygons as
areas. Non-closed polygons will be treated as implicitly closed.
\sa intersects()
*/
QPolygonF QPolygonF::intersected(const QPolygonF &r) const
@ -991,6 +1014,26 @@ QPolygonF QPolygonF::subtracted(const QPolygonF &r) const
return subject.subtracted(clip).toFillPolygon();
}
/*!
\since 5.10
Returns \c true if the current polygon intersects at any point the given polygon \a p.
Also returns \c true if the current polygon contains or is contained by any part of \a p.
Set operations on polygons will treat the polygons as
areas. Non-closed polygons will be treated as implicitly closed.
\sa intersected()
*/
bool QPolygonF::intersects(const QPolygonF &p) const
{
QPainterPath subject; subject.addPolygon(*this);
QPainterPath clip; clip.addPolygon(p);
return subject.intersects(clip);
}
/*!
Returns the polygon as a QVariant.
*/

View File

@ -98,6 +98,8 @@ public:
Q_REQUIRED_RESULT QPolygon united(const QPolygon &r) const;
Q_REQUIRED_RESULT QPolygon intersected(const QPolygon &r) const;
Q_REQUIRED_RESULT QPolygon subtracted(const QPolygon &r) const;
bool intersects(const QPolygon &r) const;
};
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QPolygon)
@ -175,6 +177,8 @@ public:
Q_REQUIRED_RESULT QPolygonF united(const QPolygonF &r) const;
Q_REQUIRED_RESULT QPolygonF intersected(const QPolygonF &r) const;
Q_REQUIRED_RESULT QPolygonF subtracted(const QPolygonF &r) const;
bool intersects(const QPolygonF &r) const;
};
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QPolygonF)

View File

@ -49,6 +49,8 @@ private slots:
void boundingRectF();
void makeEllipse();
void swap();
void intersections_data();
void intersections();
};
tst_QPolygon::tst_QPolygon()
@ -159,5 +161,45 @@ void tst_QPolygon::swap()
QCOMPARE(p2.count(),3);
}
void tst_QPolygon::intersections_data()
{
QTest::addColumn<QPolygon>("poly1");
QTest::addColumn<QPolygon>("poly2");
QTest::addColumn<bool>("result");
QTest::newRow("empty intersects nothing")
<< QPolygon()
<< QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10))
<< false;
QTest::newRow("identical triangles")
<< QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10))
<< QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10))
<< true;
QTest::newRow("not intersecting")
<< QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10))
<< QPolygon(QVector<QPoint>() << QPoint(0,20) << QPoint(10,12) << QPoint(-10,12))
<< false;
QTest::newRow("clean intersection of squares")
<< QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(0,10) << QPoint(10,10) << QPoint(10,0))
<< QPolygon(QVector<QPoint>() << QPoint(5,5) << QPoint(5,15) << QPoint(15,15) << QPoint(15,5))
<< true;
QTest::newRow("clean contains of squares")
<< QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(0,10) << QPoint(10,10) << QPoint(10,0))
<< QPolygon(QVector<QPoint>() << QPoint(5,5) << QPoint(5,8) << QPoint(8,8) << QPoint(8,5))
<< true;
}
void tst_QPolygon::intersections()
{
QFETCH(QPolygon, poly1);
QFETCH(QPolygon, poly2);
QFETCH(bool, result);
QCOMPARE(poly2.intersects(poly1), poly1.intersects(poly2));
QCOMPARE(poly2.intersected(poly1).isEmpty(), poly1.intersected(poly2).isEmpty());
QCOMPARE(!poly1.intersected(poly2).isEmpty(), poly1.intersects(poly2));
QCOMPARE(poly1.intersects(poly2), result);
}
QTEST_APPLESS_MAIN(tst_QPolygon)
#include "tst_qpolygon.moc"