diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index b004f74be9..8942292a3d 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -214,6 +214,14 @@ QT_BEGIN_NAMESPACE Returns this line translated the distance specified by \a dx and \a dy. */ +/*! + \fn QPoint QLine::center() const + + \since 5.8 + + Returns the center point of this line. This is equivalent to + (p1() + p2()) / 2, except it will never overflow. +*/ /*! \fn void QLine::setP1(const QPoint &p1) @@ -351,6 +359,12 @@ QDataStream &operator>>(QDataStream &stream, QLine &line) translate() function, and can be traversed using the pointAt() function. + \section1 Constraints + + QLine is limited to the minimum and maximum values for the + \c int type. Operations on a QLine that could potentially result + in values outside this range will result in undefined behavior. + \sa QLine, QPolygonF, QRectF */ @@ -710,6 +724,15 @@ QLineF::IntersectType QLineF::intersect(const QLineF &l, QPointF *intersectionPo Returns this line translated the distance specified by \a dx and \a dy. */ +/*! + \fn QPointF QLineF::center() const + + \since 5.8 + + Returns the center point of this line. This is equivalent to + 0.5 * p1() + 0.5 * p2(). +*/ + /*! \fn void QLineF::setP1(const QPointF &p1) \since 4.4 diff --git a/src/corelib/tools/qline.h b/src/corelib/tools/qline.h index 819dd3fd3b..5b5ca3b4c8 100644 --- a/src/corelib/tools/qline.h +++ b/src/corelib/tools/qline.h @@ -76,6 +76,8 @@ public: Q_DECL_CONSTEXPR inline QLine translated(const QPoint &p) const Q_REQUIRED_RESULT; Q_DECL_CONSTEXPR inline QLine translated(int dx, int dy) const Q_REQUIRED_RESULT; + Q_DECL_CONSTEXPR inline QPoint center() const Q_REQUIRED_RESULT; + inline void setP1(const QPoint &p1); inline void setP2(const QPoint &p2); inline void setPoints(const QPoint &p1, const QPoint &p2); @@ -165,6 +167,11 @@ Q_DECL_CONSTEXPR inline QLine QLine::translated(int adx, int ady) const return translated(QPoint(adx, ady)); } +Q_DECL_CONSTEXPR inline QPoint QLine::center() const +{ + return QPoint(int((qint64(pt1.x()) + pt2.x()) / 2), int((qint64(pt1.y()) + pt2.y()) / 2)); +} + inline void QLine::setP1(const QPoint &aP1) { pt1 = aP1; @@ -253,6 +260,8 @@ public: Q_DECL_CONSTEXPR inline QLineF translated(const QPointF &p) const Q_REQUIRED_RESULT; Q_DECL_CONSTEXPR inline QLineF translated(qreal dx, qreal dy) const Q_REQUIRED_RESULT; + Q_DECL_CONSTEXPR inline QPointF center() const Q_REQUIRED_RESULT; + inline void setP1(const QPointF &p1); inline void setP2(const QPointF &p2); inline void setPoints(const QPointF &p1, const QPointF &p2); @@ -357,6 +366,11 @@ Q_DECL_CONSTEXPR inline QLineF QLineF::translated(qreal adx, qreal ady) const return translated(QPointF(adx, ady)); } +Q_DECL_CONSTEXPR inline QPointF QLineF::center() const +{ + return QPointF(0.5 * pt1.x() + 0.5 * pt2.x(), 0.5 * pt1.y() + 0.5 * pt2.y()); +} + inline void QLineF::setLength(qreal len) { if (isNull()) diff --git a/tests/auto/corelib/tools/qline/tst_qline.cpp b/tests/auto/corelib/tools/qline/tst_qline.cpp index 3aee0ff17d..6e020ac35b 100644 --- a/tests/auto/corelib/tools/qline/tst_qline.cpp +++ b/tests/auto/corelib/tools/qline/tst_qline.cpp @@ -44,6 +44,12 @@ private slots: void testLength(); void testLength_data(); + void testCenter(); + void testCenter_data(); + + void testCenterF(); + void testCenterF_data(); + void testNormalVector(); void testNormalVector_data(); @@ -268,6 +274,77 @@ void tst_QLine::testLength() QCOMPARE(l.dy(), qreal(vy)); } +void tst_QLine::testCenter() +{ + QFETCH(int, x1); + QFETCH(int, y1); + QFETCH(int, x2); + QFETCH(int, y2); + QFETCH(int, centerX); + QFETCH(int, centerY); + + const QPoint c = QLine(x1, y1, x2, y2).center(); + QCOMPARE(centerX, c.x()); + QCOMPARE(centerY, c.y()); +} + +void tst_QLine::testCenter_data() +{ + QTest::addColumn("x1"); + QTest::addColumn("y1"); + QTest::addColumn("x2"); + QTest::addColumn("y2"); + QTest::addColumn("centerX"); + QTest::addColumn("centerY"); + + QTest::newRow("[0, 0]") << 0 << 0 << 0 << 0 << 0 << 0; + QTest::newRow("top") << 0 << 0 << 2 << 0 << 1 << 0; + QTest::newRow("right") << 0 << 0 << 0 << 2 << 0 << 1; + QTest::newRow("bottom") << 0 << 0 << -2 << 0 << -1 << 0; + QTest::newRow("left") << 0 << 0 << 0 << -2 << 0 << -1; + + QTest::newRow("precision+") << 0 << 0 << 1 << 1 << 0 << 0; + QTest::newRow("precision-") << -1 << -1 << 0 << 0 << 0 << 0; + + const int max = std::numeric_limits::max(); + const int min = std::numeric_limits::min(); + QTest::newRow("max") << max << max << max << max << max << max; + QTest::newRow("min") << min << min << min << min << min << min; + QTest::newRow("minmax") << min << min << max << max << 0 << 0; +} + +void tst_QLine::testCenterF() +{ + QFETCH(double, x1); + QFETCH(double, y1); + QFETCH(double, x2); + QFETCH(double, y2); + QFETCH(double, centerX); + QFETCH(double, centerY); + + const QPointF c = QLineF(x1, y1, x2, y2).center(); + QCOMPARE(centerX, c.x()); + QCOMPARE(centerY, c.y()); +} + +void tst_QLine::testCenterF_data() +{ + QTest::addColumn("x1"); + QTest::addColumn("y1"); + QTest::addColumn("x2"); + QTest::addColumn("y2"); + QTest::addColumn("centerX"); + QTest::addColumn("centerY"); + + QTest::newRow("[0, 0]") << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0; + QTest::newRow("top") << 0.0 << 0.0 << 1.0 << 0.0 << 0.5 << 0.0; + QTest::newRow("right") << 0.0 << 0.0 << 0.0 << 1.0 << 0.0 << 0.5; + QTest::newRow("bottom") << 0.0 << 0.0 << -1.0 << 0.0 << -0.5 << 0.0; + QTest::newRow("left") << 0.0 << 0.0 << 0.0 << -1.0 << 0.0 << -0.5; + + const double max = std::numeric_limits::max(); + QTest::newRow("max") << max << max << max << max << max << max; +} void tst_QLine::testNormalVector_data() {