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


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:18