Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qline.cpp
Go to the documentation of this file.
1
// Copyright (C) 2022 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#
include
"qline.h"
6
7
#
include
"qdebug.h"
8
#
include
"qdatastream.h"
9
#
include
"qmath.h"
10
#
include
<
private
/
qnumeric_p
.
h
>
11
12
QT_BEGIN_NAMESPACE
13
14
/*!
15
\class QLine
16
\inmodule QtCore
17
\ingroup painting
18
\compares equality
19
\compareswith equality QLineF
20
\endcompareswith
21
22
\brief The QLine class provides a two-dimensional vector using
23
integer precision.
24
25
A QLine describes a finite length line (or a line segment) on a
26
two-dimensional surface. The start and end points of the line are
27
specified using integer point accuracy for coordinates. Use the
28
QLineF constructor to retrieve a floating point copy.
29
30
\table
31
\row
32
\li \inlineimage qline-point.png {Line with p1, p2, dx, dy labeled}
33
\li \inlineimage qline-coordinates.png
34
{Line with x1, y1, x2, y2, dx, dy labeled}
35
\endtable
36
37
The positions of the line's start and end points can be retrieved
38
using the p1(), x1(), y1(), p2(), x2(), and y2() functions. The
39
dx() and dy() functions return the horizontal and vertical
40
components of the line. Use isNull() to determine whether the
41
QLine represents a valid line or a null line.
42
43
Finally, the line can be translated a given offset using the
44
translate() function.
45
46
\sa QLineF, QPolygon, QRect
47
*/
48
49
/*!
50
\fn QLine::QLine()
51
52
Constructs a null line.
53
*/
54
55
/*!
56
\fn QLine::QLine(const QPoint &p1, const QPoint &p2)
57
58
Constructs a line object that represents the line between \a p1 and
59
\a p2.
60
*/
61
62
/*!
63
\fn QLine::QLine(int x1, int y1, int x2, int y2)
64
65
Constructs a line object that represents the line between (\a x1, \a y1) and
66
(\a x2, \a y2).
67
*/
68
69
/*!
70
\fn bool QLine::isNull() const
71
72
Returns \c true if the line does not have distinct start and end points;
73
otherwise returns \c false.
74
*/
75
76
/*!
77
\fn QPoint QLine::p1() const
78
79
Returns the line's start point.
80
81
\sa x1(), y1(), p2()
82
*/
83
84
/*!
85
\fn QPoint QLine::p2() const
86
87
Returns the line's end point.
88
89
\sa x2(), y2(), p1()
90
*/
91
92
/*!
93
\fn int QLine::x1() const
94
95
Returns the x-coordinate of the line's start point.
96
97
\sa p1()
98
*/
99
100
/*!
101
\fn int QLine::y1() const
102
103
Returns the y-coordinate of the line's start point.
104
105
\sa p1()
106
*/
107
108
/*!
109
\fn int QLine::x2() const
110
111
Returns the x-coordinate of the line's end point.
112
113
\sa p2()
114
*/
115
116
/*!
117
\fn int QLine::y2() const
118
119
Returns the y-coordinate of the line's end point.
120
121
\sa p2()
122
*/
123
124
/*!
125
\fn int QLine::dx() const
126
127
Returns the horizontal component of the line's vector.
128
129
\sa dy()
130
*/
131
132
/*!
133
\fn int QLine::dy() const
134
135
Returns the vertical component of the line's vector.
136
137
\sa dx()
138
*/
139
140
/*!
141
\fn bool QLine::operator!=(const QLine &lhs, const QLine &rhs)
142
143
Returns \c true if the line \a lhs is not the same as line \a rhs.
144
145
A line is different from another line if any of their start or
146
end points differ, or the internal order of the points is different.
147
*/
148
149
/*!
150
\fn bool QLine::operator==(const QLine &lhs, const QLine &rhs)
151
152
Returns \c true if the line \a lhs is the same as line \a rhs.
153
154
A line is identical to another line if the start and end points
155
are identical, and the internal order of the points is the same.
156
*/
157
158
/*!
159
\fn void QLine::translate(const QPoint &offset)
160
161
Translates this line by the given \a offset.
162
*/
163
164
/*!
165
\fn void QLine::translate(int dx, int dy)
166
\overload
167
168
Translates this line the distance specified by \a dx and \a dy.
169
*/
170
171
/*!
172
\fn QLine QLine::translated(const QPoint &offset) const
173
174
\since 4.4
175
176
Returns this line translated by the given \a offset.
177
*/
178
179
/*!
180
\fn QLine QLine::translated(int dx, int dy) const
181
\overload
182
\since 4.4
183
184
Returns this line translated the distance specified by \a dx and \a dy.
185
*/
186
187
/*!
188
\fn QPoint QLine::center() const
189
190
\since 5.8
191
192
Returns the center point of this line. This is equivalent to
193
(p1() + p2()) / 2, except it will never overflow.
194
*/
195
196
/*!
197
\fn void QLine::setP1(const QPoint &p1)
198
\since 4.4
199
200
Sets the starting point of this line to \a p1.
201
202
\sa setP2(), p1()
203
*/
204
205
206
/*!
207
\fn void QLine::setP2(const QPoint &p2)
208
\since 4.4
209
210
Sets the end point of this line to \a p2.
211
212
\sa setP1(), p2()
213
*/
214
215
216
/*!
217
\fn void QLine::setPoints(const QPoint &p1, const QPoint &p2)
218
\since 4.4
219
220
Sets the start point of this line to \a p1 and the end point of this line to \a p2.
221
222
\sa setP1(), setP2(), p1(), p2()
223
*/
224
225
226
/*!
227
\fn void QLine::setLine(int x1, int y1, int x2, int y2)
228
\since 4.4
229
230
Sets this line to the start in \a x1, \a y1 and end in \a x2, \a y2.
231
232
\sa setP1(), setP2(), p1(), p2()
233
*/
234
235
/*!
236
\fn QLine::toLineF() const
237
\since 6.4
238
239
Returns this line as a line with floating point accuracy.
240
241
\sa QLineF::toLine()
242
*/
243
244
245
246
#
ifndef
QT_NO_DEBUG_STREAM
247
QDebug operator<<(QDebug dbg,
const
QLine &p)
248
{
249
QDebugStateSaver saver(dbg);
250
dbg.nospace() <<
"QLine("
<< p.p1() <<
','
<< p.p2() <<
')'
;
251
return
dbg;
252
}
253
#
endif
254
255
#
ifndef
QT_NO_DATASTREAM
256
/*!
257
\relates QLine
258
259
Writes the given \a line to the given \a stream and returns a
260
reference to the stream.
261
262
\sa {Serializing Qt Data Types}
263
*/
264
265
QDataStream &operator<<(QDataStream &stream,
const
QLine &line)
266
{
267
stream << line.p1() << line.p2();
268
return
stream;
269
}
270
271
/*!
272
\relates QLine
273
274
Reads a line from the given \a stream into the given \a line and
275
returns a reference to the stream.
276
277
\sa {Serializing Qt Data Types}
278
*/
279
280
QDataStream &
operator
>>(QDataStream &stream, QLine &line)
281
{
282
QPoint p1, p2;
283
stream >> p1;
284
stream >> p2;
285
line = QLine(p1, p2);
286
287
return
stream;
288
}
289
290
#
endif
// QT_NO_DATASTREAM
291
292
/*!
293
\class QLineF
294
\inmodule QtCore
295
\ingroup painting
296
\compares equality
297
\compareswith equality QLine
298
\endcompareswith
299
300
\brief The QLineF class provides a two-dimensional vector using
301
floating point precision.
302
303
A QLineF describes a finite length line (or line segment) on a
304
two-dimensional surface. QLineF defines the start and end points
305
of the line using floating point accuracy for coordinates. Use
306
the toLine() function to retrieve an integer-based copy of this
307
line.
308
309
\table
310
\row
311
\li \inlineimage qline-point.png {Line with p1, p2, dx, dy labeled}
312
\li \inlineimage qline-coordinates.png
313
{Line with x1, y1, x2, y2, dx, dy labeled}
314
\endtable
315
316
The positions of the line's start and end points can be retrieved
317
using the p1(), x1(), y1(), p2(), x2(), and y2() functions. The
318
dx() and dy() functions return the horizontal and vertical
319
components of the line, respectively.
320
321
The line's length can be retrieved using the length() function,
322
and altered using the setLength() function. Similarly, angle()
323
and setAngle() are respectively used for retrieving and altering
324
the angle of the line. Use the isNull()
325
function to determine whether the QLineF represents a valid line
326
or a null line.
327
328
The intersects() function determines the IntersectionType for this
329
line and a given line, while the angleTo() function returns the
330
angle between the lines. In addition, the unitVector() function
331
returns a line that has the same starting point as this line, but
332
with a length of only 1, while the normalVector() function returns
333
a line that is perpendicular to this line with the same starting
334
point and length.
335
336
Finally, the line can be translated a given offset using the
337
translate() function, and can be traversed using the pointAt()
338
function.
339
340
\section1 Constraints
341
342
QLine is limited to the minimum and maximum values for the
343
\c int type. Operations on a QLine that could potentially result
344
in values outside this range will result in undefined behavior.
345
346
\sa QLine, QPolygonF, QRectF
347
*/
348
349
/*!
350
\typealias QLineF::IntersectType
351
\deprecated [5.14] Use QLineF::IntersectionType instead.
352
*/
353
354
/*!
355
\enum QLineF::IntersectionType
356
357
Describes the intersection between two lines.
358
359
\table
360
\row
361
\li \inlineimage qlinef-unbounded.png
362
{Two lines with extensions intersecting}
363
\li \inlineimage qlinef-bounded.png {Two lines intersecting within bounds}
364
\row
365
\li QLineF::UnboundedIntersection
366
\li QLineF::BoundedIntersection
367
\endtable
368
369
\value NoIntersection Indicates that the lines do not intersect;
370
i.e. they are parallel.
371
372
\value UnboundedIntersection The two lines intersect, but not
373
within the range defined by their lengths. This will be the case
374
if the lines are not parallel. intersect() will also return this
375
value if the intersect point is within the start and end point of
376
only one of the lines.
377
378
\value BoundedIntersection The two lines intersect with each other
379
within the start and end points of each line.
380
381
\sa intersects()
382
*/
383
384
/*!
385
\fn QLineF::QLineF()
386
387
Constructs a null line.
388
*/
389
390
/*!
391
\fn QLineF::QLineF(const QPointF &p1, const QPointF &p2)
392
393
Constructs a line object that represents the line between \a p1 and
394
\a p2.
395
*/
396
397
/*!
398
\fn QLineF::QLineF(qreal x1, qreal y1, qreal x2, qreal y2)
399
400
Constructs a line object that represents the line between (\a x1, \a y1) and
401
(\a x2, \a y2).
402
*/
403
404
/*!
405
\fn QLineF::QLineF(const QLine &line)
406
407
Construct a QLineF object from the given integer-based \a line.
408
409
\sa toLine(), QLine::toLineF()
410
*/
411
412
/*!
413
\fn bool QLineF::isNull() const
414
415
Returns \c true if the line does not have distinct start and end points;
416
otherwise returns \c false. The start and end points are considered distinct
417
if qFuzzyCompare() can distinguish them in at least one coordinate.
418
419
\note Due to the use of fuzzy comparison, isNull() may return \c true for
420
lines whose length() is not zero.
421
422
\sa qFuzzyCompare(), length()
423
*/
424
425
/*!
426
\fn QPointF QLineF::p1() const
427
428
Returns the line's start point.
429
430
\sa x1(), y1(), p2()
431
*/
432
433
/*!
434
\fn QPointF QLineF::p2() const
435
436
Returns the line's end point.
437
438
\sa x2(), y2(), p1()
439
*/
440
441
/*!
442
\fn QLine QLineF::toLine() const
443
444
Returns an integer-based copy of this line.
445
446
Note that the returned line's start and end points are rounded to
447
the nearest integer.
448
449
\sa QLineF(), QLine::toLineF()
450
*/
451
/*!
452
\fn qreal QLineF::x1() const
453
454
Returns the x-coordinate of the line's start point.
455
456
\sa p1()
457
*/
458
459
/*!
460
\fn qreal QLineF::y1() const
461
462
Returns the y-coordinate of the line's start point.
463
464
\sa p1()
465
*/
466
467
/*!
468
\fn qreal QLineF::x2() const
469
470
Returns the x-coordinate of the line's end point.
471
472
\sa p2()
473
*/
474
475
/*!
476
\fn qreal QLineF::y2() const
477
478
Returns the y-coordinate of the line's end point.
479
480
\sa p2()
481
*/
482
483
/*!
484
\fn qreal QLineF::dx() const
485
486
Returns the horizontal component of the line's vector.
487
488
\sa dy(), pointAt()
489
*/
490
491
/*!
492
\fn qreal QLineF::dy() const
493
494
Returns the vertical component of the line's vector.
495
496
\sa dx(), pointAt()
497
*/
498
499
/*!
500
\fn void QLineF::setLength(qreal length)
501
502
Sets the length of the line to the given finite \a length. QLineF will move
503
the end point - p2() - of the line to give the line its new length, unless
504
length() was previously zero, in which case no scaling is attempted.
505
506
\sa length(), unitVector()
507
*/
508
509
/*!
510
\fn QLineF QLineF::normalVector() const
511
512
Returns a line that is perpendicular to this line with the same starting
513
point and length.
514
515
\image qlinef-normalvector.png {Diagram showing two vectors with the same
516
starting point: (v_x, v_y) and (vy, -vx).}
517
518
\sa unitVector()
519
*/
520
521
/*!
522
\fn bool QLineF::operator!=(const QLineF &lhs, const QLineF &rhs)
523
524
Returns \c true if the line \a lhs is not the same as line \a rhs.
525
526
A line is different from another line if their start or end points
527
differ, or the internal order of the points is different.
528
*/
529
530
/*!
531
\fn bool QLineF::operator==(const QLineF &lhs, const QLineF &rhs)
532
533
Returns \c true if the line \a lhs is the same as line \a rhs.
534
535
A line is identical to another line if the start and end points
536
are identical, and the internal order of the points is the same.
537
*/
538
539
/*!
540
\fn qreal QLineF::pointAt(qreal t) const
541
542
Returns the point at the position specified by finite parameter \a t. The
543
function returns the line's start point if t = 0, and its end point if t = 1.
544
545
\sa dx(), dy()
546
*/
547
548
/*!
549
Returns the length of the line.
550
551
\sa setLength(), isNull()
552
*/
553
qreal QLineF::length()
const
554
{
555
return
qHypot(dx(), dy());
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 = qRadiansToDegrees(qAtan2(-dy, dx));
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 = qDegreesToRadians(angle);
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 = qDegreesToRadians(angle);
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, provided the line
627
is non-null.
628
629
\sa normalVector(), setLength()
630
*/
631
QLineF QLineF::unitVector()
const
632
{
633
const
qreal x = dx();
634
const
qreal y = dy();
635
636
const
qreal len = qHypot(x, y);
637
QLineF f(p1(), QPointF(pt1.x() + x / len, pt1.y() + y / len));
638
639
#
ifndef
QT_NO_DEBUG
640
if
(qAbs(f.length() - 1) >= 0.001)
641
qWarning(
"QLine::unitVector: New line does not have unit length"
);
642
#
endif
643
644
return
f;
645
}
646
647
/*!
648
\fn QLineF::IntersectionType QLineF::intersects(const QLineF &line, QPointF *intersectionPoint) const
649
\since 5.14
650
651
Returns a value indicating whether or not \e this line intersects
652
with the given \a line.
653
654
The actual intersection point is extracted to \a intersectionPoint
655
(if the pointer is valid). If the lines are parallel, the
656
intersection point is undefined.
657
*/
658
QLineF::IntersectionType QLineF::intersects(
const
QLineF &l, QPointF *intersectionPoint)
const
659
{
660
// ipmlementation is based on Graphics Gems III's "Faster Line Segment Intersection"
661
const
QPointF a = pt2 - pt1;
662
const
QPointF b = l.pt1 - l.pt2;
663
const
QPointF c = pt1 - l.pt1;
664
665
const
qreal denominator = a.y() * b.x() - a.x() * b.y();
666
if
(denominator == 0 || !qt_is_finite(denominator))
667
return
NoIntersection;
668
669
const
qreal reciprocal = 1 / denominator;
670
const
qreal na = (b.y() * c.x() - b.x() * c.y()) * reciprocal;
671
if
(intersectionPoint)
672
*intersectionPoint = pt1 + a * na;
673
674
if
(na < 0 || na > 1)
675
return
UnboundedIntersection;
676
677
const
qreal nb = (a.x() * c.y() - a.y() * c.x()) * reciprocal;
678
if
(nb < 0 || nb > 1)
679
return
UnboundedIntersection;
680
681
return
BoundedIntersection;
682
}
683
684
/*!
685
\fn void QLineF::translate(const QPointF &offset)
686
687
Translates this line by the given \a offset.
688
*/
689
690
/*!
691
\fn void QLineF::translate(qreal dx, qreal dy)
692
\overload
693
694
Translates this line the distance specified by \a dx and \a dy.
695
*/
696
697
/*!
698
\fn QLineF QLineF::translated(const QPointF &offset) const
699
700
\since 4.4
701
702
Returns this line translated by the given \a offset.
703
*/
704
705
/*!
706
\fn QLineF QLineF::translated(qreal dx, qreal dy) const
707
\overload
708
\since 4.4
709
710
Returns this line translated the distance specified by \a dx and \a dy.
711
*/
712
713
/*!
714
\fn QPointF QLineF::center() const
715
716
\since 5.8
717
718
Returns the center point of this line. This is equivalent to
719
0.5 * p1() + 0.5 * p2().
720
*/
721
722
/*!
723
\fn void QLineF::setP1(const QPointF &p1)
724
\since 4.4
725
726
Sets the starting point of this line to \a p1.
727
728
\sa setP2(), p1()
729
*/
730
731
732
/*!
733
\fn void QLineF::setP2(const QPointF &p2)
734
\since 4.4
735
736
Sets the end point of this line to \a p2.
737
738
\sa setP1(), p2()
739
*/
740
741
742
/*!
743
\fn void QLineF::setPoints(const QPointF &p1, const QPointF &p2)
744
\since 4.4
745
746
Sets the start point of this line to \a p1 and the end point of this line to \a p2.
747
748
\sa setP1(), setP2(), p1(), p2()
749
*/
750
751
752
/*!
753
\fn void QLineF::setLine(qreal x1, qreal y1, qreal x2, qreal y2)
754
\since 4.4
755
756
Sets this line to the start in \a x1, \a y1 and end in \a x2, \a y2.
757
758
\sa setP1(), setP2(), p1(), p2()
759
*/
760
761
/*!
762
\fn qreal QLineF::angleTo(const QLineF &line) const
763
764
\since 4.4
765
766
Returns the angle (in degrees) from this line to the given \a
767
line, taking the direction of the lines into account. If the lines
768
do not \l{intersects()}{intersect} within their range, it is the
769
intersection point of the extended lines that serves as origin (see
770
QLineF::UnboundedIntersection).
771
772
The returned value represents the number of degrees you need to add
773
to this line to make it have the same angle as the given \a line,
774
going counter-clockwise.
775
776
\sa intersects()
777
*/
778
qreal QLineF::angleTo(
const
QLineF &l)
const
779
{
780
if
(isNull() || l.isNull())
781
return
0;
782
783
const
qreal a1 = angle();
784
const
qreal a2 = l.angle();
785
786
const
qreal delta = a2 - a1;
787
const
qreal delta_normalized = delta < 0 ? delta + 360 : delta;
788
789
if
(qFuzzyCompare(delta, qreal(360)))
790
return
0;
791
else
792
return
delta_normalized;
793
}
794
795
/*!
796
\fn bool QLineF::qFuzzyCompare(const QLineF &lhs, const QLineF &rhs)
797
\since 6.8
798
799
Returns \c true if line \a lhs is approximately equal to line \a rhs;
800
otherwise returns \c false.
801
802
The lines are considered approximately equal if their start and end
803
points are approximately equal.
804
*/
805
806
/*!
807
\fn bool QLineF::qFuzzyIsNull(const QLineF &line)
808
\since 6.8
809
810
Returns \c true if the start point of line \a line is approximately
811
equal to its end point; otherwise returns \c false.
812
*/
813
814
#
ifndef
QT_NO_DEBUG_STREAM
815
QDebug
operator
<<(QDebug dbg,
const
QLineF &p)
816
{
817
QDebugStateSaver saver(dbg);
818
dbg.nospace() <<
"QLineF("
<< p.p1() <<
','
<< p.p2() <<
')'
;
819
return
dbg;
820
}
821
#
endif
822
823
#
ifndef
QT_NO_DATASTREAM
824
/*!
825
\relates QLineF
826
827
Writes the given \a line to the given \a stream and returns a
828
reference to the stream.
829
830
\sa {Serializing Qt Data Types}
831
*/
832
833
QDataStream &operator<<(QDataStream &stream,
const
QLineF &line)
834
{
835
stream << line.p1() << line.p2();
836
return
stream;
837
}
838
839
/*!
840
\relates QLineF
841
842
Reads a line from the given \a stream into the given \a line and
843
returns a reference to the stream.
844
845
\sa {Serializing Qt Data Types}
846
*/
847
848
QDataStream &
operator
>>(QDataStream &stream, QLineF &line)
849
{
850
QPointF start, end;
851
stream >> start;
852
stream >> end;
853
line = QLineF(start, end);
854
855
return
stream;
856
}
857
858
#
endif
// QT_NO_DATASTREAM
859
860
QT_END_NAMESPACE
QLineF::operator>>
QDataStream & operator>>(QDataStream &stream, QLineF &line)
Reads a line from the given stream into the given line and returns a reference to the stream.
Definition
qline.cpp:848
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
operator>>
QDataStream & operator>>(QDataStream &s, QKeyCombination &combination)
Definition
qdatastream.h:699
operator<<
QDebug operator<<(QDebug dbg, const QLineF &p)
Definition
qline.cpp:815
qtbase
src
corelib
tools
qline.cpp
Generated on
for Qt by
1.18.0