##// END OF EJS Templates
QSplineSeries documentation added
Marek Rosa -
r433:c8744ab348e4
parent child
Show More
@@ -1,51 +1,52
1 1 /*!
2 2 \page classes.html
3 3 \title QtCommercial Charts API
4 4 \keyword All Classes
5 5
6 6 \raw HTML
7 7 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
8 8 <tr>
9 9 <th class="titleheader" width="33%">
10 10 List of classes
11 11 </th>
12 12 </tr>
13 13 <tr>
14 14 <td valign="top">
15 15 <ul>
16 16 <li><a href="qareaseries.html">QAreaSeries</a></li>
17 17 <li><a href="qbarseries.html">QBarSeries</a></li>
18 18 <li><a href="qbarset.html">QBarSet</a></li>
19 19 <li><a href="qchart.html">QChart</a></li>
20 20 <li><a href="qchartaxis.html">QChartAxis</a></li>
21 21 <li><a href="qchartview.html">QChartView</a></li>
22 22 <li><a href="qlineseries.html">QLineSeries</a></li>
23 23 <li><a href="qpercentbarseries.html">QPercentBarSeries</a></li>
24 24 <li><a href="qpieseries.html">QPieSeries</a></li>
25 25 <li><a href="qpieslice.html">QPieSlice</a></li>
26 26 <li><a href="qscatterseries.html">QScatterSeries</a></li>
27 27 <li><a href="qseries.html">QSeries</a></li>
28 <li><a href="qsplineseries.html">QSplineSeries</a></li>
28 29 <li><a href="qstackedbarseries.html">QStackedBarSeries</a></li>
29 30 </ul>
30 31 </td>
31 32 </tr>
32 33 </table>
33 34
34 35 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
35 36 <tr>
36 37 <th class="titleheader" width="33%">
37 38 Other files:
38 39 </th>
39 40 </tr>
40 41 <tr>
41 42 <td valign="top">
42 43 <ul>
43 44 <li><a href="qchartglobal.html">QChartGlobal</a></li>
44 45 </ul>
45 46 </td>
46 47 </tr>
47 48 </table>
48 49
49 50 \endraw
50 51
51 52 */
@@ -1,108 +1,142
1 1 #include "qsplineseries.h"
2 2
3 /*!
4 \class QSplineSeries
5 \brief Series type used to store data needed to draw a spline.
6
7 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
8 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
9 */
10
11 /*!
12 \fn QSeriesType QSplineSeries::type() const
13 Returns the type of the series
14 */
15
16 /*!
17 \fn QSeriesType QSplineSeries::controlPoint(int index) const
18 Returns the control point specified by \a index
19 */
20
3 21 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 22
23 /*!
24 Constructs empty series object which is a child of \a parent.
25 When series object is added to QChartView or QChart instance then the ownerships is transfered.
26 */
27
5 28 QSplineSeries::QSplineSeries(QObject *parent) :
6 29 QLineSeries(parent)
7 30 {
8 31 connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
9 32 connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
10 33 connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
11 34 }
12 35
36 /*!
37 \internal
38 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
39 */
13 40 void QSplineSeries::calculateControlPoints()
14 41 {
15 42
16 43 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
17 // CPOL Licence
44 // CPOL License
18 45
19 46 int n = m_x.size() - 1;
20 47 if (n == 1)
21 48 { // Special case: Bezier curve should be a straight line.
22 49 // firstControlPoints = new Point[1];
23 50 // 3P1 = 2P0 + P3
24 51 m_controlPoints.append(QPointF((2 * m_x[0] + m_x[1]) / 3, (2 * m_y[0] + m_y[1]) / 3));
25 52
26 53 // P2 = 2P1 P0
27 54 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - m_x[0], 2 * m_controlPoints[0].y() - m_y[0]));
28 55 return;
29 56 }
30 57
31 58 // Calculate first Bezier control points
32 59 // Right hand side vector
33 60 // Set of equations for P0 to Pn points.
34 61 //
35 62 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
36 63 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
37 64 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
38 65 // | . . . . . . . . . . . . | | ... | | ... |
39 66 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
40 67 // | . . . . . . . . . . . . | | ... | | ... |
41 68 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
42 69 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
43 70 //
44 71 QList<qreal> rhs;
45 72 rhs.append(m_x[0] + 2 * m_x[1]);
46 73
47 74 // Set right hand side X values
48 75 for (int i = 1; i < n - 1; ++i)
49 76 rhs.append(4 * m_x[i] + 2 * m_x[i + 1]);
50 77
51 78 rhs.append((8 * m_x[n - 1] + m_x[n]) / 2.0);
52 79 // Get first control points X-values
53 80 QList<qreal> x = getFirstControlPoints(rhs);
54 81 rhs[0] = m_y[0] + 2 * m_y[1];
55 82
56 83 // Set right hand side Y values
57 84 for (int i = 1; i < n - 1; ++i)
58 85 rhs[i] = 4 * m_y[i] + 2 * m_y[i + 1];
59 86
60 87 rhs[n - 1] = (8 * m_y[n - 1] + m_y[n]) / 2.0;
61 88 // Get first control points Y-values
62 89 QList<qreal> y = getFirstControlPoints(rhs);
63 90
64 91 // Fill output arrays.
65 92 for (int i = 0; i < n; ++i)
66 93 {
67 94 // First control point
68 95 m_controlPoints.append(QPointF(x[i], y[i]));
69 96 // Second control point
70 97 if (i < n - 1)
71 98 m_controlPoints.append(QPointF(2 * m_x[i + 1] - x[i + 1], 2 * m_y[i + 1] - y[i + 1]));
72 99 else
73 100 m_controlPoints.append(QPointF((m_x[n] + x[n - 1]) / 2, (m_y[n] + y[n - 1]) / 2));
74 101 }
75 102 }
76 103
104 /*!
105 \internal
106 */
77 107 QList<qreal> QSplineSeries::getFirstControlPoints(QList<qreal> rhs)
78 108 {
79 109 QList<qreal> x; // Solution vector.
80 110 QList<qreal> tmp; // Temp workspace.
81 111
82 112 qreal b = 2.0;
83 113 x.append(rhs[0] / b);
84 114 tmp.append(0);
85 115 for (int i = 1; i < rhs.size(); i++) // Decomposition and forward substitution.
86 116 {
87 117 tmp.append(1 / b);
88 118 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
89 119 x.append((rhs[i] - x[i - 1]) / b);
90 120 }
91 121 for (int i = 1; i < rhs.size(); i++)
92 122 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
93 123
94 124 return x;
95 125 }
96 126
127 /*!
128 \internal
129 Updates the control points, besed on currently avaiable knots.
130 */
97 131 void QSplineSeries::updateControlPoints()
98 132 {
99 133 if(m_x.size() > 1)
100 134 {
101 135 m_controlPoints.clear();
102 136 calculateControlPoints();
103 137 }
104 138 }
105 139
106 140 #include "moc_qsplineseries.cpp"
107 141
108 142 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,37 +1,37
1 1 #ifndef QSPLINESERIES_H
2 2 #define QSPLINESERIES_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include <QtGlobal>
6 6 #include "qlineseries.h"
7 7 #include <QList>
8 8 #include <QPointF>
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 class QSplineSeries : public QLineSeries
13 13 {
14 14 Q_OBJECT
15 15 public:
16 16
17 17 QSplineSeries(QObject *parent = 0);
18 18 QSeriesType type() const { return QSeries::SeriesTypeSpline; }
19 19
20 int count() const { return m_x.size(); }
20 // int count() const { return m_x.size(); }
21 21 QPointF controlPoint(int index) const { return m_controlPoints[index]; }
22 22
23 23 private:
24 24 void calculateControlPoints();
25 25 QList<qreal> getFirstControlPoints(QList<qreal> rhs);
26 26
27 27 private slots:
28 28 void updateControlPoints();
29 29
30 30 private:
31 31 QList<QPointF> m_controlPoints;
32 32
33 33 };
34 34
35 35 QTCOMMERCIALCHART_END_NAMESPACE
36 36
37 37 #endif // QSPLINESERIES_H
General Comments 0
You need to be logged in to leave comments. Login now