Qt 4.8
qbezier_p.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QBEZIER_P_H
43 #define QBEZIER_P_H
44 
45 //
46 // W A R N I N G
47 // -------------
48 //
49 // This file is not part of the Qt API. It exists for the convenience
50 // of other Qt classes. This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55 
56 #include "QtCore/qpoint.h"
57 #include "QtCore/qline.h"
58 #include "QtCore/qrect.h"
59 #include "QtCore/qvector.h"
60 #include "QtCore/qlist.h"
61 #include "QtCore/qpair.h"
62 #include "QtGui/qtransform.h"
63 
65 
66 class QPolygonF;
67 
69 {
70 public:
71  static QBezier fromPoints(const QPointF &p1, const QPointF &p2,
72  const QPointF &p3, const QPointF &p4);
73 
74  static void coefficients(qreal t, qreal &a, qreal &b, qreal &c, qreal &d);
75 
76  inline QPointF pointAt(qreal t) const;
77  inline QPointF normalVector(qreal t) const;
78 
79  inline QPointF derivedAt(qreal t) const;
80  inline QPointF secondDerivedAt(qreal t) const;
81 
82  QPolygonF toPolygon(qreal bezier_flattening_threshold = 0.5) const;
83  void addToPolygon(QPolygonF *p, qreal bezier_flattening_threshold = 0.5) const;
84 
85  QRectF bounds() const;
86  qreal length(qreal error = 0.01) const;
87  void addIfClose(qreal *length, qreal error) const;
88 
89  qreal tAtLength(qreal len) const;
90 
91  int stationaryYPoints(qreal &t0, qreal &t1) const;
92  qreal tForY(qreal t0, qreal t1, qreal y) const;
93 
94  QPointF pt1() const { return QPointF(x1, y1); }
95  QPointF pt2() const { return QPointF(x2, y2); }
96  QPointF pt3() const { return QPointF(x3, y3); }
97  QPointF pt4() const { return QPointF(x4, y4); }
98 
99  QBezier mapBy(const QTransform &transform) const;
100 
101  inline QPointF midPoint() const;
102  inline QLineF midTangent() const;
103 
104  inline QLineF startTangent() const;
105  inline QLineF endTangent() const;
106 
107  inline void parameterSplitLeft(qreal t, QBezier *left);
108  inline void split(QBezier *firstHalf, QBezier *secondHalf) const;
109 
110  int shifted(QBezier *curveSegments, int maxSegmets,
111  qreal offset, float threshold) const;
112 
113  QBezier bezierOnInterval(qreal t0, qreal t1) const;
114  QBezier getSubRange(qreal t0, qreal t1) const;
115 
116  qreal x1, y1, x2, y2, x3, y3, x4, y4;
117 };
118 
120 {
121  return QPointF((x1 + x4 + 3*(x2 + x3))/8., (y1 + y4 + 3*(y2 + y3))/8.);
122 }
123 
125 {
126  QPointF mid = midPoint();
127  QLineF dir(QLineF(x1, y1, x2, y2).pointAt(0.5), QLineF(x3, y3, x4, y4).pointAt(0.5));
128  return QLineF(mid.x() - dir.dx(), mid.y() - dir.dy(),
129  mid.x() + dir.dx(), mid.y() + dir.dy());
130 }
131 
133 {
134  QLineF tangent(pt1(), pt2());
135  if (tangent.isNull())
136  tangent = QLineF(pt1(), pt3());
137  if (tangent.isNull())
138  tangent = QLineF(pt1(), pt4());
139  return tangent;
140 }
141 
143 {
144  QLineF tangent(pt4(), pt3());
145  if (tangent.isNull())
146  tangent = QLineF(pt4(), pt2());
147  if (tangent.isNull())
148  tangent = QLineF(pt4(), pt1());
149  return tangent;
150 }
151 
153 {
154  qreal m_t = 1. - t;
155  b = m_t * m_t;
156  c = t * t;
157  d = c * t;
158  a = b * m_t;
159  b *= 3. * t;
160  c *= 3. * m_t;
161 }
162 
164 {
165  // numerically more stable:
166  qreal x, y;
167 
168  qreal m_t = 1. - t;
169  {
170  qreal a = x1*m_t + x2*t;
171  qreal b = x2*m_t + x3*t;
172  qreal c = x3*m_t + x4*t;
173  a = a*m_t + b*t;
174  b = b*m_t + c*t;
175  x = a*m_t + b*t;
176  }
177  {
178  qreal a = y1*m_t + y2*t;
179  qreal b = y2*m_t + y3*t;
180  qreal c = y3*m_t + y4*t;
181  a = a*m_t + b*t;
182  b = b*m_t + c*t;
183  y = a*m_t + b*t;
184  }
185  return QPointF(x, y);
186 }
187 
189 {
190  qreal m_t = 1. - t;
191  qreal a = m_t * m_t;
192  qreal b = t * m_t;
193  qreal c = t * t;
194 
195  return QPointF((y2-y1) * a + (y3-y2) * b + (y4-y3) * c, -(x2-x1) * a - (x3-x2) * b - (x4-x3) * c);
196 }
197 
199 {
200  // p'(t) = 3 * (-(1-2t+t^2) * p0 + (1 - 4 * t + 3 * t^2) * p1 + (2 * t - 3 * t^2) * p2 + t^2 * p3)
201 
202  qreal m_t = 1. - t;
203 
204  qreal d = t * t;
205  qreal a = -m_t * m_t;
206  qreal b = 1 - 4 * t + 3 * d;
207  qreal c = 2 * t - 3 * d;
208 
209  return 3 * QPointF(a * x1 + b * x2 + c * x3 + d * x4,
210  a * y1 + b * y2 + c * y3 + d * y4);
211 }
212 
214 {
215  qreal a = 2. - 2. * t;
216  qreal b = -4 + 6 * t;
217  qreal c = 2 - 6 * t;
218  qreal d = 2 * t;
219 
220  return 3 * QPointF(a * x1 + b * x2 + c * x3 + d * x4,
221  a * y1 + b * y2 + c * y3 + d * y4);
222 }
223 
224 inline void QBezier::split(QBezier *firstHalf, QBezier *secondHalf) const
225 {
226  Q_ASSERT(firstHalf);
227  Q_ASSERT(secondHalf);
228 
229  qreal c = (x2 + x3)*.5;
230  firstHalf->x2 = (x1 + x2)*.5;
231  secondHalf->x3 = (x3 + x4)*.5;
232  firstHalf->x1 = x1;
233  secondHalf->x4 = x4;
234  firstHalf->x3 = (firstHalf->x2 + c)*.5;
235  secondHalf->x2 = (secondHalf->x3 + c)*.5;
236  firstHalf->x4 = secondHalf->x1 = (firstHalf->x3 + secondHalf->x2)*.5;
237 
238  c = (y2 + y3)/2;
239  firstHalf->y2 = (y1 + y2)*.5;
240  secondHalf->y3 = (y3 + y4)*.5;
241  firstHalf->y1 = y1;
242  secondHalf->y4 = y4;
243  firstHalf->y3 = (firstHalf->y2 + c)*.5;
244  secondHalf->y2 = (secondHalf->y3 + c)*.5;
245  firstHalf->y4 = secondHalf->y1 = (firstHalf->y3 + secondHalf->y2)*.5;
246 }
247 
249 {
250  left->x1 = x1;
251  left->y1 = y1;
252 
253  left->x2 = x1 + t * ( x2 - x1 );
254  left->y2 = y1 + t * ( y2 - y1 );
255 
256  left->x3 = x2 + t * ( x3 - x2 ); // temporary holding spot
257  left->y3 = y2 + t * ( y3 - y2 ); // temporary holding spot
258 
259  x3 = x3 + t * ( x4 - x3 );
260  y3 = y3 + t * ( y4 - y3 );
261 
262  x2 = left->x3 + t * ( x3 - left->x3);
263  y2 = left->y3 + t * ( y3 - left->y3);
264 
265  left->x3 = left->x2 + t * ( left->x3 - left->x2 );
266  left->y3 = left->y2 + t * ( left->y3 - left->y2 );
267 
268  left->x4 = x1 = left->x3 + t * (x2 - left->x3);
269  left->y4 = y1 = left->y3 + t * (y2 - left->y3);
270 }
271 
273 
274 #endif // QBEZIER_P_H
double d
Definition: qnumeric_p.h:62
QPointF pt4() const
Definition: qbezier_p.h:97
QLineF startTangent() const
Definition: qbezier_p.h:132
double qreal
Definition: qglobal.h:1193
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void parameterSplitLeft(qreal t, QBezier *left)
Definition: qbezier_p.h:248
QLineF endTangent() const
Definition: qbezier_p.h:142
#define Q_GUI_EXPORT
Definition: qglobal.h:1450
#define error(msg)
qreal x2
Definition: qbezier_p.h:116
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
static void coefficients(qreal t, qreal &a, qreal &b, qreal &c, qreal &d)
Definition: qbezier_p.h:152
long ASN1_INTEGER_get ASN1_INTEGER * a
qreal dy() const
Returns the vertical component of the line's vector.
Definition: qline.h:329
QPointF pointAt(qreal t) const
Definition: qbezier_p.h:163
QPointF pt1() const
Definition: qbezier_p.h:94
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
qreal y2
Definition: qbezier_p.h:116
qreal x4
Definition: qbezier_p.h:116
qreal x() const
Returns the x-coordinate of this point.
Definition: qpoint.h:282
The QLineF class provides a two-dimensional vector using floating point precision.
Definition: qline.h:212
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
QPointF normalVector(qreal t) const
Definition: qbezier_p.h:188
The QPolygonF class provides a vector of points using floating point precision.
Definition: qpolygon.h:134
static void split(QT_FT_Vector *b)
qreal dx() const
Returns the horizontal component of the line's vector.
Definition: qline.h:324
qreal y4
Definition: qbezier_p.h:116
QPointF derivedAt(qreal t) const
Definition: qbezier_p.h:198
QLineF midTangent() const
Definition: qbezier_p.h:124
QPointF pt2() const
Definition: qbezier_p.h:95
qreal x3
Definition: qbezier_p.h:116
static QPointF midPoint(const QWingedEdge &list, int ei)
qreal x1
Definition: qbezier_p.h:116
QPointF midPoint() const
Definition: qbezier_p.h:119
void split(QBezier *firstHalf, QBezier *secondHalf) const
Definition: qbezier_p.h:224
QPointF pt3() const
Definition: qbezier_p.h:96
qreal y() const
Returns the y-coordinate of this point.
Definition: qpoint.h:287
qreal y1
Definition: qbezier_p.h:116
QPointF secondDerivedAt(qreal t) const
Definition: qbezier_p.h:213
Q_CORE_EXPORT QTextStream & left(QTextStream &s)
qreal y3
Definition: qbezier_p.h:116
bool isNull() const
Returns true if the line is not set up with valid start and end point; otherwise returns false...
Definition: qline.cpp:517
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:65