1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtCore module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 #include "qdatastream.h"
46 #include <private/qnumeric_p.h>
54 \brief The QLine class provides a two-dimensional vector using
57 A QLine describes a finite length line (or a line segment) on a
58 two-dimensional surface. The start and end points of the line are
59 specified using integer point accuracy for coordinates. Use the
60 QLineF constructor to retrieve a floating point copy.
64 \li \inlineimage qline-point.png
65 \li \inlineimage qline-coordinates.png
68 The positions of the line's start and end points can be retrieved
69 using the p1(), x1(), y1(), p2(), x2(), and y2() functions. The
70 dx() and dy() functions return the horizontal and vertical
71 components of the line. Use isNull() to determine whether the
72 QLine represents a valid line or a null line.
74 Finally, the line can be translated a given offset using the
77 \sa QLineF, QPolygon, QRect
83 Constructs a null line.
87 \fn QLine::QLine(const QPoint &p1, const QPoint &p2)
89 Constructs a line object that represents the line between \a p1 and
94 \fn QLine::QLine(int x1, int y1, int x2, int y2)
96 Constructs a line object that represents the line between (\a x1, \a y1) and
101 \fn bool QLine::isNull() const
103 Returns true if the line is not set up with valid start and end point;
104 otherwise returns false.
108 \fn QPoint QLine::p1() const
110 Returns the line's start point.
116 \fn QPoint QLine::p2() const
118 Returns the line's end point.
124 \fn int QLine::x1() const
126 Returns the x-coordinate of the line's start point.
132 \fn int QLine::y1() const
134 Returns the y-coordinate of the line's start point.
140 \fn int QLine::x2() const
142 Returns the x-coordinate of the line's end point.
148 \fn int QLine::y2() const
150 Returns the y-coordinate of the line's end point.
156 \fn int QLine::dx() const
158 Returns the horizontal component of the line's vector.
164 \fn int QLine::dy() const
166 Returns the vertical component of the line's vector.
172 \fn bool QLine::operator!=(const QLine &line) const
174 Returns true if the given \a line is not the same as \e this line.
176 A line is different from another line if any of their start or
177 end points differ, or the internal order of the points is different.
181 \fn bool QLine::operator==(const QLine &line) const
183 Returns true if the given \a line is the same as \e this line.
185 A line is identical to another line if the start and end points
186 are identical, and the internal order of the points is the same.
190 \fn void QLine::translate(const QPoint &offset)
192 Translates this line by the given \a offset.
196 \fn void QLine::translate(int dx, int dy)
199 Translates this line the distance specified by \a dx and \a dy.
203 \fn QLine QLine::translated(const QPoint &offset) const
207 Returns this line translated by the given \a offset.
211 \fn QLine QLine::translated(int dx, int dy) const
215 Returns this line translated the distance specified by \a dx and \a dy.
220 \fn void QLine::setP1(const QPoint &p1)
223 Sets the starting point of this line to \a p1.
230 \fn void QLine::setP2(const QPoint &p2)
233 Sets the end point of this line to \a p2.
240 \fn void QLine::setPoints(const QPoint &p1, const QPoint &p2)
243 Sets the start point of this line to \a p1 and the end point of this line to \a p2.
245 \sa setP1(), setP2(), p1(), p2()
250 \fn void QLine::setLine(int x1, int y1, int x2, int y2)
253 Sets this line to the start in \a x1, \a y1 and end in \a x2, \a y2.
255 \sa setP1(), setP2(), p1(), p2()
260 #ifndef QT_NO_DEBUG_STREAM
261 QDebug operator<<(QDebug d, const QLine &p)
263 d << "QLine(" << p.p1() << ',' << p.p2() << ')';
268 #ifndef QT_NO_DATASTREAM
272 Writes the given \a line to the given \a stream and returns a
273 reference to the stream.
275 \sa {Serializing Qt Data Types}
278 QDataStream &operator<<(QDataStream &stream, const QLine &line)
280 stream << line.p1() << line.p2();
287 Reads a line from the given \a stream into the given \a line and
288 returns a reference to the stream.
290 \sa {Serializing Qt Data Types}
293 QDataStream &operator>>(QDataStream &stream, QLine &line)
298 line = QLine(p1, p2);
303 #endif // QT_NO_DATASTREAM
307 #define M_2PI 6.28318530717958647692528676655900576
314 \brief The QLineF class provides a two-dimensional vector using
315 floating point precision.
317 A QLineF describes a finite length line (or line segment) on a
318 two-dimensional surface. QLineF defines the start and end points
319 of the line using floating point accuracy for coordinates. Use
320 the toLine() function to retrieve an integer based copy of this
325 \li \inlineimage qline-point.png
326 \li \inlineimage qline-coordinates.png
329 The positions of the line's start and end points can be retrieved
330 using the p1(), x1(), y1(), p2(), x2(), and y2() functions. The
331 dx() and dy() functions return the horizontal and vertical
332 components of the line, respectively.
334 The line's length can be retrieved using the length() function,
335 and altered using the setLength() function. Similarly, angle()
336 and setAngle() are respectively used for retrieving and altering
337 the angle of the line. Use the isNull()
338 function to determine whether the QLineF represents a valid line
341 The intersect() function determines the IntersectType for this
342 line and a given line, while the angle() function returns the
343 angle between the lines. In addition, the unitVector() function
344 returns a line that has the same starting point as this line, but
345 with a length of only 1, while the normalVector() function returns
346 a line that is perpendicular to this line with the same starting
349 Finally, the line can be translated a given offset using the
350 translate() function, and can be traversed using the pointAt()
353 \sa QLine, QPolygonF, QRectF
357 \enum QLineF::IntersectType
359 Describes the intersection between two lines.
363 \li \inlineimage qlinef-unbounded.png
364 \li \inlineimage qlinef-bounded.png
366 \li QLineF::UnboundedIntersection
367 \li QLineF::BoundedIntersection
370 \value NoIntersection Indicates that the lines do not intersect;
371 i.e. they are parallel.
373 \value UnboundedIntersection The two lines intersect, but not
374 within the range defined by their lengths. This will be the case
375 if the lines are not parallel.
377 intersect() will also return this value if the intersect point is
378 within the start and end point of only one of the lines.
380 \value BoundedIntersection The two lines intersect with each other
381 within the start and end points of each line.
389 Constructs a null line.
393 \fn QLineF::QLineF(const QPointF &p1, const QPointF &p2)
395 Constructs a line object that represents the line between \a p1 and
400 \fn QLineF::QLineF(qreal x1, qreal y1, qreal x2, qreal y2)
402 Constructs a line object that represents the line between (\a x1, \a y1) and
407 \fn QLineF::QLineF(const QLine &line)
409 Construct a QLineF object from the given integer-based \a line.
415 \fn bool QLineF::isNull() const
417 Returns true if the line is not set up with valid start and end point;
418 otherwise returns false.
422 \fn QPointF QLineF::p1() const
424 Returns the line's start point.
430 \fn QPointF QLineF::p2() const
432 Returns the line's end point.
438 \fn QLine QLineF::toLine() const
440 Returns an integer based copy of this line.
442 Note that the returned line's start and end points are rounded to
448 \fn qreal QLineF::x1() const
450 Returns the x-coordinate of the line's start point.
456 \fn qreal QLineF::y1() const
458 Returns the y-coordinate of the line's start point.
464 \fn qreal QLineF::x2() const
466 Returns the x-coordinate of the line's end point.
472 \fn qreal QLineF::y2() const
474 Returns the y-coordinate of the line's end point.
480 \fn qreal QLineF::dx() const
482 Returns the horizontal component of the line's vector.
488 \fn qreal QLineF::dy() const
490 Returns the vertical component of the line's vector.
496 \fn QLineF::setLength(qreal length)
498 Sets the length of the line to the given \a length. QLineF will
499 move the end point - p2() - of the line to give the line its new length.
501 If the line is a null line, the length will remain zero regardless
502 of the length specified.
504 \sa length(), isNull()
508 \fn QLineF QLineF::normalVector() const
510 Returns a line that is perpendicular to this line with the same starting
513 \image qlinef-normalvector.png
519 \fn bool QLineF::operator!=(const QLineF &line) const
521 Returns true if the given \a line is not the same as \e this line.
523 A line is different from another line if their start or end points
524 differ, or the internal order of the points is different.
528 \fn bool QLineF::operator==(const QLineF &line) const
530 Returns true if the given \a line is the same as this line.
532 A line is identical to another line if the start and end points
533 are identical, and the internal order of the points is the same.
537 \fn qreal QLineF::pointAt(qreal t) const
539 Returns the point at the parameterized position specified by \a
540 t. The function returns the line's start point if t = 0, and its end
547 Returns the length of the line.
551 qreal QLineF::length() const
553 qreal x = pt2.x() - pt1.x();
554 qreal y = pt2.y() - pt1.y();
555 return qSqrt(x*x + y*y);
561 Returns the angle of the line in degrees.
563 The return value will be in the range of values from 0.0 up to but not
564 including 360.0. The angles are measured counter-clockwise from a point
565 on the x-axis to the right of the origin (x > 0).
569 qreal QLineF::angle() const
571 const qreal dx = pt2.x() - pt1.x();
572 const qreal dy = pt2.y() - pt1.y();
574 const qreal theta = qAtan2(-dy, dx) * 360.0 / M_2PI;
576 const qreal theta_normalized = theta < 0 ? theta + 360 : theta;
578 if (qFuzzyCompare(theta_normalized, qreal(360)))
581 return theta_normalized;
587 Sets the angle of the line to the given \a angle (in degrees).
588 This will change the position of the second point of the line such that
589 the line has the given angle.
591 Positive values for the angles mean counter-clockwise while negative values
592 mean the clockwise direction. Zero degrees is at the 3 o'clock position.
596 void QLineF::setAngle(qreal angle)
598 const qreal angleR = angle * M_2PI / 360.0;
599 const qreal l = length();
601 const qreal dx = qCos(angleR) * l;
602 const qreal dy = -qSin(angleR) * l;
604 pt2.rx() = pt1.x() + dx;
605 pt2.ry() = pt1.y() + dy;
611 Returns a QLineF with the given \a length and \a angle.
613 The first point of the line will be on the origin.
615 Positive values for the angles mean counter-clockwise while negative values
616 mean the clockwise direction. Zero degrees is at the 3 o'clock position.
618 QLineF QLineF::fromPolar(qreal length, qreal angle)
620 const qreal angleR = angle * M_2PI / 360.0;
621 return QLineF(0, 0, qCos(angleR) * length, -qSin(angleR) * length);
625 Returns the unit vector for this line, i.e a line starting at the
626 same point as \e this line with a length of 1.0.
630 QLineF QLineF::unitVector() const
632 qreal x = pt2.x() - pt1.x();
633 qreal y = pt2.y() - pt1.y();
635 qreal len = qSqrt(x*x + y*y);
636 QLineF f(p1(), QPointF(pt1.x() + x/len, pt1.y() + y/len));
639 if (qAbs(f.length() - 1) >= 0.001)
640 qWarning("QLine::unitVector: New line does not have unit length");
647 \fn QLineF::IntersectType QLineF::intersect(const QLineF &line, QPointF *intersectionPoint) const
649 Returns a value indicating whether or not \e this line intersects
650 with the given \a line.
652 The actual intersection point is extracted to \a intersectionPoint
653 (if the pointer is valid). If the lines are parallel, the
654 intersection point is undefined.
657 QLineF::IntersectType QLineF::intersect(const QLineF &l, QPointF *intersectionPoint) const
659 // ipmlementation is based on Graphics Gems III's "Faster Line Segment Intersection"
660 const QPointF a = pt2 - pt1;
661 const QPointF b = l.pt1 - l.pt2;
662 const QPointF c = pt1 - l.pt1;
664 const qreal denominator = a.y() * b.x() - a.x() * b.y();
665 if (denominator == 0 || !qt_is_finite(denominator))
666 return NoIntersection;
668 const qreal reciprocal = 1 / denominator;
669 const qreal na = (b.y() * c.x() - b.x() * c.y()) * reciprocal;
670 if (intersectionPoint)
671 *intersectionPoint = pt1 + a * na;
673 if (na < 0 || na > 1)
674 return UnboundedIntersection;
676 const qreal nb = (a.x() * c.y() - a.y() * c.x()) * reciprocal;
677 if (nb < 0 || nb > 1)
678 return UnboundedIntersection;
680 return BoundedIntersection;
684 \fn void QLineF::translate(const QPointF &offset)
686 Translates this line by the given \a offset.
690 \fn void QLineF::translate(qreal dx, qreal dy)
693 Translates this line the distance specified by \a dx and \a dy.
697 \fn QLineF QLineF::translated(const QPointF &offset) const
701 Returns this line translated by the given \a offset.
705 \fn QLineF QLineF::translated(qreal dx, qreal dy) const
709 Returns this line translated the distance specified by \a dx and \a dy.
713 \fn void QLineF::setP1(const QPointF &p1)
716 Sets the starting point of this line to \a p1.
723 \fn void QLineF::setP2(const QPointF &p2)
726 Sets the end point of this line to \a p2.
733 \fn void QLineF::setPoints(const QPointF &p1, const QPointF &p2)
736 Sets the start point of this line to \a p1 and the end point of this line to \a p2.
738 \sa setP1(), setP2(), p1(), p2()
743 \fn void QLineF::setLine(qreal x1, qreal y1, qreal x2, qreal y2)
746 Sets this line to the start in \a x1, \a y1 and end in \a x2, \a y2.
748 \sa setP1(), setP2(), p1(), p2()
752 \fn qreal QLineF::angleTo(const QLineF &line) const
756 Returns the angle (in degrees) from this line to the given \a
757 line, taking the direction of the lines into account. If the lines
758 do not intersect within their range, it is the intersection point of
759 the extended lines that serves as origin (see
760 QLineF::UnboundedIntersection).
762 The returned value represents the number of degrees you need to add
763 to this line to make it have the same angle as the given \a line,
764 going counter-clockwise.
768 qreal QLineF::angleTo(const QLineF &l) const
770 if (isNull() || l.isNull())
773 const qreal a1 = angle();
774 const qreal a2 = l.angle();
776 const qreal delta = a2 - a1;
777 const qreal delta_normalized = delta < 0 ? delta + 360 : delta;
779 if (qFuzzyCompare(delta, qreal(360)))
782 return delta_normalized;
786 \fn qreal QLineF::angle(const QLineF &line) const
790 Returns the angle (in degrees) between this line and the given \a
791 line, taking the direction of the lines into account. If the lines
792 do not intersect within their range, it is the intersection point of
793 the extended lines that serves as origin (see
794 QLineF::UnboundedIntersection).
798 \li \inlineimage qlinef-angle-identicaldirection.png
799 \li \inlineimage qlinef-angle-oppositedirection.png
802 When the lines are parallel, this function returns 0 if they have
803 the same direction; otherwise it returns 180.
807 qreal QLineF::angle(const QLineF &l) const
809 if (isNull() || l.isNull())
811 qreal cos_line = (dx()*l.dx() + dy()*l.dy()) / (length()*l.length());
813 // only accept cos_line in the range [-1,1], if it is outside, use 0 (we return 0 rather than PI for those cases)
814 if (cos_line >= -1.0 && cos_line <= 1.0) rad = qAcos( cos_line );
815 return rad * 360 / M_2PI;
819 #ifndef QT_NO_DEBUG_STREAM
820 QDebug operator<<(QDebug d, const QLineF &p)
822 d << "QLineF(" << p.p1() << ',' << p.p2() << ')';
827 #ifndef QT_NO_DATASTREAM
831 Writes the given \a line to the given \a stream and returns a
832 reference to the stream.
834 \sa {Serializing Qt Data Types}
837 QDataStream &operator<<(QDataStream &stream, const QLineF &line)
839 stream << line.p1() << line.p2();
846 Reads a line from the given \a stream into the given \a line and
847 returns a reference to the stream.
849 \sa {Serializing Qt Data Types}
852 QDataStream &operator>>(QDataStream &stream, QLineF &line)
857 line = QLineF(start, end);
862 #endif // QT_NO_DATASTREAM