qwt_spline_basis.cpp
Go to the documentation of this file.
1 #include "qwt_spline_basis.h"
3 #include <qpainterpath.h>
4 
5 #if 0
6 static QPolygonF qwtBasisUniformKnots( const QPolygonF& points )
7 {
8  const int n = points.size();
9 
10  if ( n < 3 )
11  return points;
12 
13  QVector<double> u( n - 2 );
14  QVector<double> kx( n - 2 );
15  QVector<double> ky( n - 2 );
16 
17  u[n-3] = 4.0;
18  kx[n-3] = 6.0 * points[n-2].x() - points[n-1].x();
19  ky[n-3] = 6.0 * points[n-2].y() - points[n-1].y();
20 
21  for ( int i = n - 4; i >= 0; i-- )
22  {
23  u[i] = 4.0 - 1.0 / u[i+1];
24  kx[i] = 6.0 * points[i+1].x() - kx[i+1] / u[i+1];
25  ky[i] = 6.0 * points[i+1].y() - ky[i+1] / u[i+1];
26  }
27 
28  QVector<QPointF> knots( n );
29 
30  knots[0] = points[0];
31 
32  for ( int i = 1; i < n - 1; i++ )
33  {
34  knots[i].rx() = ( kx[i-1] - knots[i-1].x() ) / u[i-1];
35  knots[i].ry() = ( ky[i-1] - knots[i-1].y() ) / u[i-1];
36  }
37 
38  knots[n-1] = points[n-1];
39 
40  return knots;
41 }
42 #endif
43 
44 #if 0
45 static inline void qwtSplineBezierControlPoints( const QwtSplineParametrization *param,
46  const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4,
47  QPointF &cp1, QPointF &cp2 )
48 {
49  const double t1 = param->valueIncrement( p1, p2 );
50  const double t2 = param->valueIncrement( p2, p3 );
51  const double t3 = param->valueIncrement( p3, p4 );
52 
53  const double t123 = t1 + t2 + t3;
54 
55  cp1 = ( t2 + t3 ) / t123 * p2 + t1 / t123 * p3;
56  cp2 = ( t3 * p2 + ( t1 + t2 ) * p3 ) / t123;
57 }
58 #endif
59 
60 static QPainterPath qwtSplineBasisPathUniform( const QPolygonF& points,
61  QwtSpline::BoundaryType boundaryType )
62 {
63  const int n = points.size();
64  const QPointF *pd = points.constData();
65 
66  QPainterPath path;
67 
68  QPointF cp1 = ( 2.0 * pd[0] + pd[1] ) / 3.0;;
69 
70  if ( boundaryType == QwtSpline::ConditionalBoundaries )
71  {
72  path.moveTo( pd[0] );
73  }
74  else
75  {
76  const QPointF cpN = ( pd[n-1] + 2.0 * pd[0] ) / 3.0;
77  path.moveTo( 0.5 * ( cpN + cp1 ) );
78  }
79 
80  for ( int i = 1; i < n - 1; i++ )
81  {
82  const QPointF cp2 = ( pd[i-1] + 2.0 * pd[i] ) / 3.0;
83  const QPointF cp3 = ( 2.0 * pd[i] + pd[i+1] ) / 3.0;
84 
85  path.cubicTo( cp1, cp2, 0.5 * ( cp2 + cp3 ) );
86 
87  cp1 = cp3;
88  }
89 
90  if ( boundaryType == QwtSpline::ConditionalBoundaries )
91  {
92  const QPointF cp2 = ( pd[n-2] + 2.0 * pd[n-1] ) / 3.0;
93  path.cubicTo( cp1, cp2, pd[n-1] );
94  }
95  else
96  {
97  const QPointF cp2 = ( pd[n-2] + 2.0 * pd[n-1] ) / 3.0;
98  const QPointF cp3 = ( 2.0 * pd[n-1] + pd[0] ) / 3.0;
99 
100  path.cubicTo( cp1, cp2, 0.5 * ( cp2 + cp3 ) );
101 
102  if ( boundaryType == QwtSpline::ClosedPolygon )
103  {
104  const QPointF cp4 = ( pd[n-1] + 2.0 * pd[0] ) / 3.0;
105  const QPointF cp5 = ( 2.0 * pd[0] + pd[1] ) / 3.0;
106 
107  path.cubicTo( cp3, cp4, 0.5 * ( cp4 + cp5 ) );
108  }
109  }
110 
111  return path;
112 }
113 
114 static QPainterPath qwtSplineBasisPath( const QPolygonF &points,
115  const QwtSplineParametrization *param,
116  QwtSpline::BoundaryType boundaryType )
117 {
118  const int n = points.size();
119  const QPointF *pd = points.constData();
120 
121  QPointF p0;
122 
123  double t1 = param->valueIncrement( pd[0], pd[1] );
124  double t2 = param->valueIncrement( pd[1], pd[2] );
125 
126  double t0;
127  if ( boundaryType == QwtSpline::ConditionalBoundaries )
128  t0 = t1;
129  else
130  t0 = param->valueIncrement( pd[n-1], pd[0] );
131 
132  double t012 = t0 + t1 + t2;
133  QPointF cp1 = ( ( t1 + t2 ) * pd[0] + t0 * pd[1] ) / t012;
134 
135  if ( boundaryType == QwtSpline::ConditionalBoundaries )
136  {
137  p0 = pd[0];
138  }
139  else
140  {
141  const double tN = param->valueIncrement( pd[n-2], pd[n-1] );
142  const QPointF cpN = ( t1 * pd[n-1] + ( tN + t0 ) * pd[0] ) / ( tN + t0 + t1 );
143 
144  p0 = ( t1 * cpN + t0 * cp1 ) / ( t0 + t1 );
145  }
146 
147  QPainterPath path;
148  path.moveTo( p0 );
149 
150  for ( int i = 1; i < n - 2; i++ )
151  {
152  const double t3 = param->valueIncrement( pd[i+1], pd[i+2] );
153  const double t123 = t1 + t2 + t3;
154 
155  const QPointF cp2 = ( t2 * pd[i-1] + ( t0 + t1 ) * pd[i] ) / t012;
156  const QPointF cp3 = ( ( t2 + t3 ) * pd[i] + t1 * pd[i+1] ) / t123;
157 
158  const QPointF p2 = ( t2 * cp2 + t1 * cp3 ) / ( t1 + t2 );
159 
160  path.cubicTo( cp1, cp2, p2 );
161 
162  cp1 = cp3;
163 
164  t0 = t1;
165  t1 = t2;
166  t2 = t3;
167  t012 = t123;
168  }
169 
170  {
171  double t3;
172  if ( boundaryType == QwtSpline::ConditionalBoundaries )
173  t3 = t2;
174  else
175  t3 = param->valueIncrement( pd[n-1], pd[0] );
176 
177  const double t123 = t1 + t2 + t3;
178 
179  const QPointF cp2 = ( t2 * pd[n-3] + ( t0 + t1 ) * pd[n-2] ) / t012;
180  const QPointF cp3 = ( ( t2 + t3 ) * pd[n-2] + t1 * pd[n-1] ) / t123;
181 
182  const QPointF p2 = ( t2 * cp2 + t1 * cp3 ) / ( t1 + t2 );
183 
184  path.cubicTo( cp1, cp2, p2 );
185 
186  cp1 = cp3;
187 
188  t0 = t1;
189  t1 = t2;
190  t2 = t3;
191  t012 = t123;
192  }
193 
194  const QPointF cp2 = ( t2 * pd[n-2] + ( t0 + t1 ) * pd[n-1] ) / t012;
195 
196  if ( boundaryType == QwtSpline::ConditionalBoundaries )
197  {
198  path.cubicTo( cp1, cp2, pd[n-1] );
199  }
200  else
201  {
202  const double t3 = param->valueIncrement( pd[0], pd[1] );
203  const double t123 = t1 + t2 + t3;
204 
205  const QPointF cp3 = ( t2 + t3 ) / t123 * pd[n-1] + t1 / t123 * pd[0];
206  const QPointF cp4 = ( t3 * pd[n-1] + ( t1 + t2 ) * pd[0] ) / t123;
207 
208  const QPointF pN = ( t2 * cp2 + t1 * cp3 ) / ( t1 + t2 );
209 
210  path.cubicTo( cp1, cp2, pN );
211  path.cubicTo( cp3, cp4, p0 );
212  }
213 
214  return path;
215 }
216 
219 {
220 }
221 
224 {
225 }
226 
229 {
230  return 2;
231 }
232 
240 QPainterPath QwtSplineBasis::painterPath( const QPolygonF &points ) const
241 {
242  if ( points.size() < 4 )
243  return QPainterPath();
244 
245  QPainterPath path;
246 
247  switch( parametrization()->type() )
248  {
250  {
251  path = qwtSplineBasisPathUniform( points, boundaryType() );
252  break;
253  }
254  default:
255  {
256  path = qwtSplineBasisPath( points, parametrization(), boundaryType() );
257  }
258  }
259 
260  return path;
261 }
Curve parametrization used for a spline interpolation.
virtual uint locality() const QWT_OVERRIDE
The locality is always 2.
const QwtSplineParametrization * parametrization() const
Definition: qwt_spline.cpp:605
virtual double valueIncrement(const QPointF &, const QPointF &) const
Calculate the parameter value increment for 2 points.
virtual QPainterPath painterPath(const QPolygonF &) const QWT_OVERRIDE
static QPainterPath qwtSplineBasisPath(const QPolygonF &points, const QwtSplineParametrization *param, QwtSpline::BoundaryType boundaryType)
static QPainterPath qwtSplineBasisPathUniform(const QPolygonF &points, QwtSpline::BoundaryType boundaryType)
BoundaryType boundaryType() const
Definition: qwt_spline.cpp:626
QwtSplineBasis()
Constructor.
virtual ~QwtSplineBasis()
Destructor.


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:10