@@ -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 Licen |
|
|
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