Merge remote-tracking branch 'origin/master' into api_changes
[profile/ivi/qtbase.git] / src / corelib / tools / qline.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qline.h"
43 #include "qdebug.h"
44 #include "qdatastream.h"
45 #include "qmath.h"
46 #include <private/qnumeric_p.h>
47
48 QT_BEGIN_NAMESPACE
49
50 /*!
51     \class QLine
52     \ingroup painting
53
54     \brief The QLine class provides a two-dimensional vector using
55     integer precision.
56
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.
61
62     \table
63     \row
64         \li \inlineimage qline-point.png
65         \li \inlineimage qline-coordinates.png
66     \endtable
67
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.
73
74     Finally, the line can be translated a given offset using the
75     translate() function.
76
77     \sa QLineF, QPolygon, QRect
78 */
79
80 /*!
81     \fn QLine::QLine()
82
83     Constructs a null line.
84 */
85
86 /*!
87     \fn QLine::QLine(const QPoint &p1, const QPoint &p2)
88
89     Constructs a line object that represents the line between \a p1 and
90     \a p2.
91 */
92
93 /*!
94     \fn QLine::QLine(int x1, int y1, int x2, int y2)
95
96     Constructs a line object that represents the line between (\a x1, \a y1) and
97     (\a x2, \a y2).
98 */
99
100 /*!
101     \fn bool QLine::isNull() const
102
103     Returns true if the line is not set up with valid start and end point;
104     otherwise returns false.
105 */
106
107 /*!
108     \fn QPoint QLine::p1() const
109
110     Returns the line's start point.
111
112     \sa x1(), y1(), p2()
113 */
114
115 /*!
116     \fn QPoint QLine::p2() const
117
118     Returns the line's end point.
119
120     \sa x2(), y2(), p1()
121 */
122
123 /*!
124     \fn int QLine::x1() const
125
126     Returns the x-coordinate of the line's start point.
127
128     \sa p1()
129 */
130
131 /*!
132     \fn int QLine::y1() const
133
134     Returns the y-coordinate of the line's start point.
135
136     \sa p1()
137 */
138
139 /*!
140     \fn int QLine::x2() const
141
142     Returns the x-coordinate of the line's end point.
143
144     \sa p2()
145 */
146
147 /*!
148     \fn int QLine::y2() const
149
150     Returns the y-coordinate of the line's end point.
151
152     \sa p2()
153 */
154
155 /*!
156     \fn int QLine::dx() const
157
158     Returns the horizontal component of the line's vector.
159
160     \sa dy()
161 */
162
163 /*!
164     \fn int QLine::dy() const
165
166     Returns the vertical component of the line's vector.
167
168     \sa dx()
169 */
170
171 /*!
172     \fn bool QLine::operator!=(const QLine &line) const
173
174     Returns true if the given \a line is not the same as \e this line.
175
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.
178 */
179
180 /*!
181     \fn bool QLine::operator==(const QLine &line) const
182
183     Returns true if the given \a line is the same as \e this line.
184
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.
187 */
188
189 /*!
190     \fn void QLine::translate(const QPoint &offset)
191
192     Translates this line by the given \a offset.
193 */
194
195 /*!
196     \fn void QLine::translate(int dx, int dy)
197     \overload
198
199     Translates this line the distance specified by \a dx and \a dy.
200 */
201
202 /*!
203     \fn QLine QLine::translated(const QPoint &offset) const
204
205     \since 4.4
206
207     Returns this line translated by the given \a offset.
208 */
209
210 /*!
211     \fn QLine QLine::translated(int dx, int dy) const
212     \overload
213     \since 4.4
214
215     Returns this line translated the distance specified by \a dx and \a dy.
216 */
217
218
219 /*!
220     \fn void QLine::setP1(const QPoint &p1)
221     \since 4.4
222
223     Sets the starting point of this line to \a p1.
224
225     \sa setP2(), p1()
226 */
227
228
229 /*!
230     \fn void QLine::setP2(const QPoint &p2)
231     \since 4.4
232
233     Sets the end point of this line to \a p2.
234
235     \sa setP1(), p2()
236 */
237
238
239 /*!
240     \fn void QLine::setPoints(const QPoint &p1, const QPoint &p2)
241     \since 4.4
242
243     Sets the start point of this line to \a p1 and the end point of this line to \a p2.
244
245     \sa setP1(), setP2(), p1(), p2()
246 */
247
248
249 /*!
250     \fn void QLine::setLine(int x1, int y1, int x2, int y2)
251     \since 4.4
252
253     Sets this line to the start in \a x1, \a y1 and end in \a x2, \a y2.
254
255     \sa setP1(), setP2(), p1(), p2()
256 */
257
258
259
260 #ifndef QT_NO_DEBUG_STREAM
261 QDebug operator<<(QDebug d, const QLine &p)
262 {
263     d << "QLine(" << p.p1() << ',' << p.p2() << ')';
264     return d;
265 }
266 #endif
267
268 #ifndef QT_NO_DATASTREAM
269 /*!
270     \relates QLine
271
272     Writes the given \a line to the given \a stream and returns a
273     reference to the stream.
274
275     \sa {Serializing Qt Data Types}
276 */
277
278 QDataStream &operator<<(QDataStream &stream, const QLine &line)
279 {
280     stream << line.p1() << line.p2();
281     return stream;
282 }
283
284 /*!
285     \relates QLine
286
287     Reads a line from the given \a stream into the given \a line and
288     returns a reference to the stream.
289
290     \sa {Serializing Qt Data Types}
291 */
292
293 QDataStream &operator>>(QDataStream &stream, QLine &line)
294 {
295     QPoint p1, p2;
296     stream >> p1;
297     stream >> p2;
298     line = QLine(p1, p2);
299
300     return stream;
301 }
302
303 #endif // QT_NO_DATASTREAM
304
305
306 #ifndef M_2PI
307 #define M_2PI 6.28318530717958647692528676655900576
308 #endif
309
310 /*!
311     \class QLineF
312     \ingroup painting
313
314     \brief The QLineF class provides a two-dimensional vector using
315     floating point precision.
316
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
321     line.
322
323     \table
324     \row
325         \li \inlineimage qline-point.png
326         \li \inlineimage qline-coordinates.png
327     \endtable
328
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.
333
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
339     or a null line.
340
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
347     point and length.
348
349     Finally, the line can be translated a given offset using the
350     translate() function, and can be traversed using the pointAt()
351     function.
352
353     \sa QLine, QPolygonF, QRectF
354 */
355
356 /*!
357     \enum QLineF::IntersectType
358
359     Describes the intersection between two lines.
360
361     \table
362     \row
363     \li \inlineimage qlinef-unbounded.png
364     \li \inlineimage qlinef-bounded.png
365     \row
366     \li QLineF::UnboundedIntersection
367     \li QLineF::BoundedIntersection
368     \endtable
369
370     \value NoIntersection Indicates that the lines do not intersect;
371     i.e. they are parallel.
372
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. 
376
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.
379
380     \value BoundedIntersection The two lines intersect with each other
381     within the start and end points of each line.
382
383     \sa intersect()
384 */
385
386 /*!
387     \fn QLineF::QLineF()
388
389     Constructs a null line.
390 */
391
392 /*!
393     \fn QLineF::QLineF(const QPointF &p1, const QPointF &p2)
394
395     Constructs a line object that represents the line between \a p1 and
396     \a p2.
397 */
398
399 /*!
400     \fn QLineF::QLineF(qreal x1, qreal y1, qreal x2, qreal y2)
401
402     Constructs a line object that represents the line between (\a x1, \a y1) and
403     (\a x2, \a y2).
404 */
405
406 /*!
407     \fn QLineF::QLineF(const QLine &line)
408
409     Construct a QLineF object from the given integer-based \a line.
410
411     \sa toLine()
412 */
413
414 /*!
415     \fn bool QLineF::isNull() const
416
417     Returns true if the line is not set up with valid start and end point;
418     otherwise returns false.
419 */
420
421 /*!
422     \fn QPointF QLineF::p1() const
423
424     Returns the line's start point.
425
426     \sa x1(), y1(), p2()
427 */
428
429 /*!
430     \fn QPointF QLineF::p2() const
431
432     Returns the line's end point.
433
434     \sa x2(), y2(), p1()
435 */
436
437 /*!
438     \fn QLine QLineF::toLine() const
439
440     Returns an integer based copy of this line.
441
442     Note that the returned line's start and end points are rounded to
443     the nearest integer.
444
445     \sa QLineF()
446 */
447 /*!
448     \fn qreal QLineF::x1() const
449
450     Returns the x-coordinate of the line's start point.
451
452     \sa p1()
453 */
454
455 /*!
456     \fn qreal QLineF::y1() const
457
458     Returns the y-coordinate of the line's start point.
459
460     \sa p1()
461 */
462
463 /*!
464     \fn qreal QLineF::x2() const
465
466     Returns the x-coordinate of the line's end point.
467
468     \sa p2()
469 */
470
471 /*!
472     \fn qreal QLineF::y2() const
473
474     Returns the y-coordinate of the line's end point.
475
476     \sa p2()
477 */
478
479 /*!
480     \fn qreal QLineF::dx() const
481
482     Returns the horizontal component of the line's vector.
483
484     \sa dy(), pointAt()
485 */
486
487 /*!
488     \fn qreal QLineF::dy() const
489
490     Returns the vertical component of the line's vector.
491
492     \sa dx(), pointAt()
493 */
494
495 /*!
496     \fn QLineF::setLength(qreal length)
497
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.
500     
501     If the line is a null line, the length will remain zero regardless
502     of the length specified. 
503
504     \sa length(), isNull()
505 */
506
507 /*!
508     \fn QLineF QLineF::normalVector() const
509
510     Returns a line that is perpendicular to this line with the same starting
511     point and length.
512
513     \image qlinef-normalvector.png
514
515     \sa unitVector()
516 */
517
518 /*!
519     \fn bool QLineF::operator!=(const QLineF &line) const
520
521     Returns true if the given \a line is not the same as \e this line.
522
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.
525 */
526
527 /*!
528     \fn bool QLineF::operator==(const QLineF &line) const
529
530     Returns true if the given \a line is the same as this line.
531
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.
534 */
535
536 /*!
537   \fn qreal QLineF::pointAt(qreal t) const
538
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
541   point if t = 1.
542
543   \sa dx(), dy()
544 */
545
546 /*!
547     Returns the length of the line.
548
549     \sa setLength()
550 */
551 qreal QLineF::length() const
552 {
553     qreal x = pt2.x() - pt1.x();
554     qreal y = pt2.y() - pt1.y();
555     return qSqrt(x*x + y*y);
556 }
557
558 /*!
559     \since 4.4
560
561     Returns the angle of the line in degrees.
562
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).
566
567     \sa setAngle()
568 */
569 qreal QLineF::angle() const
570 {
571     const qreal dx = pt2.x() - pt1.x();
572     const qreal dy = pt2.y() - pt1.y();
573
574     const qreal theta = qAtan2(-dy, dx) * 360.0 / M_2PI;
575
576     const qreal theta_normalized = theta < 0 ? theta + 360 : theta;
577
578     if (qFuzzyCompare(theta_normalized, qreal(360)))
579         return qreal(0);
580     else
581         return theta_normalized;
582 }
583
584 /*!
585     \since 4.4
586
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.
590
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.
593
594     \sa angle()
595 */
596 void QLineF::setAngle(qreal angle)
597 {
598     const qreal angleR = angle * M_2PI / 360.0;
599     const qreal l = length();
600
601     const qreal dx = qCos(angleR) * l;
602     const qreal dy = -qSin(angleR) * l;
603
604     pt2.rx() = pt1.x() + dx;
605     pt2.ry() = pt1.y() + dy;
606 }
607
608 /*!
609     \since 4.4
610
611     Returns a QLineF with the given \a length and \a angle.
612
613     The first point of the line will be on the origin.
614
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.
617 */
618 QLineF QLineF::fromPolar(qreal length, qreal angle)
619 {
620     const qreal angleR = angle * M_2PI / 360.0;
621     return QLineF(0, 0, qCos(angleR) * length, -qSin(angleR) * length);
622 }
623
624 /*!
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.
627
628     \sa normalVector()
629 */
630 QLineF QLineF::unitVector() const
631 {
632     qreal x = pt2.x() - pt1.x();
633     qreal y = pt2.y() - pt1.y();
634
635     qreal len = qSqrt(x*x + y*y);
636     QLineF f(p1(), QPointF(pt1.x() + x/len, pt1.y() + y/len));
637
638 #ifndef QT_NO_DEBUG
639     if (qAbs(f.length() - 1) >= 0.001)
640         qWarning("QLine::unitVector: New line does not have unit length");
641 #endif
642
643     return f;
644 }
645
646 /*!
647     \fn QLineF::IntersectType QLineF::intersect(const QLineF &line, QPointF *intersectionPoint) const
648
649     Returns a value indicating whether or not \e this line intersects
650     with the given \a line.
651
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.
655 */
656
657 QLineF::IntersectType QLineF::intersect(const QLineF &l, QPointF *intersectionPoint) const
658 {
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;
663
664     const qreal denominator = a.y() * b.x() - a.x() * b.y();
665     if (denominator == 0 || !qt_is_finite(denominator))
666         return NoIntersection;
667
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;
672
673     if (na < 0 || na > 1)
674         return UnboundedIntersection;
675
676     const qreal nb = (a.x() * c.y() - a.y() * c.x()) * reciprocal;
677     if (nb < 0 || nb > 1)
678         return UnboundedIntersection;
679
680     return BoundedIntersection;
681 }
682
683 /*!
684     \fn void QLineF::translate(const QPointF &offset)
685
686     Translates this line by the given \a offset.
687 */
688
689 /*!
690     \fn void QLineF::translate(qreal dx, qreal dy)
691     \overload
692
693     Translates this line the distance specified by \a dx and \a dy.
694 */
695
696 /*!
697     \fn QLineF QLineF::translated(const QPointF &offset) const
698
699     \since 4.4
700
701     Returns this line translated by the given \a offset.
702 */
703
704 /*!
705     \fn QLineF QLineF::translated(qreal dx, qreal dy) const
706     \overload
707     \since 4.4
708
709     Returns this line translated the distance specified by \a dx and \a dy.
710 */
711
712 /*!
713     \fn void QLineF::setP1(const QPointF &p1)
714     \since 4.4
715
716     Sets the starting point of this line to \a p1.
717
718     \sa setP2(), p1()
719 */
720
721
722 /*!
723     \fn void QLineF::setP2(const QPointF &p2)
724     \since 4.4
725
726     Sets the end point of this line to \a p2.
727
728     \sa setP1(), p2()
729 */
730
731
732 /*!
733     \fn void QLineF::setPoints(const QPointF &p1, const QPointF &p2)
734     \since 4.4
735
736     Sets the start point of this line to \a p1 and the end point of this line to \a p2.
737
738     \sa setP1(), setP2(), p1(), p2()
739 */
740
741
742 /*!
743     \fn void QLineF::setLine(qreal x1, qreal y1, qreal x2, qreal y2)
744     \since 4.4
745
746     Sets this line to the start in \a x1, \a y1 and end in \a x2, \a y2.
747
748     \sa setP1(), setP2(), p1(), p2()
749 */
750
751 /*!
752   \fn qreal QLineF::angleTo(const QLineF &line) const
753
754   \since 4.4
755
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).
761
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.
765
766   \sa intersect()
767 */
768 qreal QLineF::angleTo(const QLineF &l) const
769 {
770     if (isNull() || l.isNull())
771         return 0;
772
773     const qreal a1 = angle();
774     const qreal a2 = l.angle();
775
776     const qreal delta = a2 - a1;
777     const qreal delta_normalized = delta < 0 ? delta + 360 : delta;
778
779     if (qFuzzyCompare(delta, qreal(360)))
780         return 0;
781     else
782         return delta_normalized;
783 }
784
785 /*!
786   \fn qreal QLineF::angle(const QLineF &line) const
787
788   \obsolete
789
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).
795
796   \table
797   \row
798   \li \inlineimage qlinef-angle-identicaldirection.png
799   \li \inlineimage qlinef-angle-oppositedirection.png
800   \endtable
801
802   When the lines are parallel, this function returns 0 if they have
803   the same direction; otherwise it returns 180.
804
805   \sa intersect()
806 */
807 qreal QLineF::angle(const QLineF &l) const
808 {
809     if (isNull() || l.isNull())
810         return 0;
811     qreal cos_line = (dx()*l.dx() + dy()*l.dy()) / (length()*l.length());
812     qreal rad = 0;
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;
816 }
817
818
819 #ifndef QT_NO_DEBUG_STREAM
820 QDebug operator<<(QDebug d, const QLineF &p)
821 {
822     d << "QLineF(" << p.p1() << ',' << p.p2() << ')';
823     return d;
824 }
825 #endif
826
827 #ifndef QT_NO_DATASTREAM
828 /*!
829     \relates QLineF
830
831     Writes the given \a line to the given \a stream and returns a
832     reference to the stream.
833
834     \sa {Serializing Qt Data Types}
835 */
836
837 QDataStream &operator<<(QDataStream &stream, const QLineF &line)
838 {
839     stream << line.p1() << line.p2();
840     return stream;
841 }
842
843 /*!
844     \relates QLineF
845
846     Reads a line from the given \a stream into the given \a line and
847     returns a reference to the stream.
848
849     \sa {Serializing Qt Data Types}
850 */
851
852 QDataStream &operator>>(QDataStream &stream, QLineF &line)
853 {
854     QPointF start, end;
855     stream >> start;
856     stream >> end;
857     line = QLineF(start, end);
858
859     return stream;
860 }
861
862 #endif // QT_NO_DATASTREAM
863
864 QT_END_NAMESPACE