qwt_spline.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2  * Qwt Widget Library
3  * Copyright (C) 1997 Josef Wilgen
4  * Copyright (C) 2002 Uwe Rathmann
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the Qwt License, Version 1.0
8  *****************************************************************************/
9 
10 #include "qwt_spline.h"
12 #include "qwt_bezier.h"
13 #include "qwt_math.h"
14 
15 namespace QwtSplineC1P
16 {
17  struct param
18  {
20  parameter( p )
21  {
22  }
23 
24  inline double operator()( const QPointF &p1, const QPointF &p2 ) const
25  {
26  return parameter->valueIncrement( p1, p2 );
27  }
28 
30  };
31 
32  struct paramY
33  {
34  inline double operator()( const QPointF &p1, const QPointF &p2 ) const
35  {
37  }
38  };
39 
40  struct paramUniform
41  {
42  inline double operator()( const QPointF &p1, const QPointF &p2 ) const
43  {
45  }
46  };
47 
49  {
50  inline double operator()( const QPointF &p1, const QPointF &p2 ) const
51  {
53  }
54  };
55 
56  struct paramChordal
57  {
58  inline double operator()( const QPointF &p1, const QPointF &p2 ) const
59  {
61  }
62  };
63 
65  {
66  inline double operator()( const QPointF &p1, const QPointF &p2 ) const
67  {
69  }
70  };
71 
72  class PathStore
73  {
74  public:
75  inline void init( int size )
76  {
77  Q_UNUSED(size);
78  }
79 
80  inline void start( double x1, double y1 )
81  {
82  path.moveTo( x1, y1 );
83  }
84 
85  inline void addCubic( double cx1, double cy1,
86  double cx2, double cy2, double x2, double y2 )
87  {
88  path.cubicTo( cx1, cy1, cx2, cy2, x2, y2 );
89  }
90 
91  inline void end()
92  {
93  path.closeSubpath();
94  }
95 
96  QPainterPath path;
97  };
98 
100  {
101  public:
103  d_cp( NULL )
104  {
105  }
106 
107  inline void init( int size )
108  {
109  controlPoints.resize( size );
110  d_cp = controlPoints.data();
111  }
112 
113  inline void start( double x1, double y1 )
114  {
115  Q_UNUSED( x1 );
116  Q_UNUSED( y1 );
117  }
118 
119  inline void addCubic( double cx1, double cy1,
120  double cx2, double cy2, double x2, double y2 )
121  {
122  Q_UNUSED( x2 );
123  Q_UNUSED( y2 );
124 
125  QLineF &l = *d_cp++;
126  l.setLine( cx1, cy1, cx2, cy2 );
127  }
128 
129  inline void end()
130  {
131  }
132 
133  QVector<QLineF> controlPoints;
134 
135  private:
136  QLineF* d_cp;
137  };
138 
139  double slopeBoundary( int boundaryCondition, double boundaryValue,
140  const QPointF &p1, const QPointF &p2, double slope1 )
141  {
142  const double dx = p2.x() - p1.x();
143  const double dy = p2.y() - p1.y();
144 
145  double m = 0.0;
146 
147  switch( boundaryCondition )
148  {
149  case QwtSpline::Clamped1:
150  {
151  m = boundaryValue;
152  break;
153  }
154  case QwtSpline::Clamped2:
155  {
156  const double c2 = 0.5 * boundaryValue;
157  const double c1 = slope1;
158 
159  m = 0.5 * ( 3.0 * dy / dx - c1 - c2 * dx );
160  break;
161  }
162  case QwtSpline::Clamped3:
163  {
164  const double c3 = boundaryValue / 6.0;
165  m = c3 * dx * dx + 2 * dy / dx - slope1;
166  break;
167  }
169  {
170  const double s = dy / dx;
171  const double r = qBound( 0.0, boundaryValue, 1.0 );
172 
173  m = s - r * ( s - slope1 );
174  break;
175  }
176  default:
177  {
178  m = dy / dx; // something
179  }
180  }
181 
182  return m;
183  }
184 }
185 
186 template< class SplineStore >
187 static inline SplineStore qwtSplineC1PathParamX(
188  const QwtSplineC1 *spline, const QPolygonF &points )
189 {
190  const int n = points.size();
191 
192  const QVector<double> m = spline->slopes( points );
193  if ( m.size() != n )
194  return SplineStore();
195 
196  const QPointF *pd = points.constData();
197  const double *md = m.constData();
198 
199  SplineStore store;
200  store.init( m.size() - 1 );
201  store.start( pd[0].x(), pd[0].y() );
202 
203  for ( int i = 0; i < n - 1; i++ )
204  {
205  const double dx3 = ( pd[i+1].x() - pd[i].x() ) / 3.0;
206 
207  store.addCubic( pd[i].x() + dx3, pd[i].y() + md[i] * dx3,
208  pd[i+1].x() - dx3, pd[i+1].y() - md[i+1] * dx3,
209  pd[i+1].x(), pd[i+1].y() );
210  }
211 
212  return store;
213 }
214 
215 template< class SplineStore >
216 static inline SplineStore qwtSplineC1PathParamY(
217  const QwtSplineC1 *spline, const QPolygonF &points )
218 {
219  const int n = points.size();
220 
221  QPolygonF pointsFlipped( n );
222  for ( int i = 0; i < n; i++ )
223  {
224  pointsFlipped[i].setX( points[i].y() );
225  pointsFlipped[i].setY( points[i].x() );
226  }
227 
228  const QVector<double> m = spline->slopes( pointsFlipped );
229  if ( m.size() != n )
230  return SplineStore();
231 
232  const QPointF *pd = pointsFlipped.constData();
233  const double *md = m.constData();
234 
235  SplineStore store;
236  store.init( m.size() - 1 );
237  store.start( pd[0].y(), pd[0].x() );
238 
239  QVector<QLineF> lines( n );
240  for ( int i = 0; i < n - 1; i++ )
241  {
242  const double dx3 = ( pd[i+1].x() - pd[i].x() ) / 3.0;
243 
244  store.addCubic( pd[i].y() + md[i] * dx3, pd[i].x() + dx3,
245  pd[i+1].y() - md[i+1] * dx3, pd[i+1].x() - dx3,
246  pd[i+1].y(), pd[i+1].x() );
247  }
248 
249  return store;
250 }
251 
252 template< class SplineStore, class Param >
253 static inline SplineStore qwtSplineC1PathParametric(
254  const QwtSplineC1 *spline, const QPolygonF &points, Param param )
255 {
256  const bool isClosing = ( spline->boundaryType() == QwtSpline::ClosedPolygon );
257  const int n = points.size();
258 
259  QPolygonF pointsX, pointsY;
260  pointsX.resize( isClosing ? n + 1 : n );
261  pointsY.resize( isClosing ? n + 1 : n );
262 
263  QPointF *px = pointsX.data();
264  QPointF *py = pointsY.data();
265  const QPointF *p = points.constData();
266 
267  double t = 0.0;
268 
269  px[0].rx() = py[0].rx() = t;
270  px[0].ry() = p[0].x();
271  py[0].ry() = p[0].y();
272 
273  int numParamPoints = 1;
274  for ( int i = 1; i < n; i++ )
275  {
276  const double td = param( points[i-1], points[i] );
277  if ( td > 0.0 )
278  {
279  t += td;
280 
281  px[numParamPoints].rx() = py[numParamPoints].rx() = t;
282 
283  px[numParamPoints].ry() = p[i].x();
284  py[numParamPoints].ry() = p[i].y();
285 
286  numParamPoints++;
287  }
288  }
289 
290  if ( isClosing )
291  {
292  const double td = param( points[n-1], points[0] );
293 
294  if ( td > 0.0 )
295  {
296  t += td;
297 
298  px[numParamPoints].rx() = py[numParamPoints].rx() = t;
299 
300  px[numParamPoints].ry() = p[0].x();
301  py[numParamPoints].ry() = p[0].y();
302 
303  numParamPoints++;
304  }
305  }
306 
307  if ( pointsX.size() != numParamPoints )
308  {
309  pointsX.resize( numParamPoints );
310  pointsY.resize( numParamPoints );
311  }
312 
313  const QVector<double> slopesX = spline->slopes( pointsX );
314  const QVector<double> slopesY = spline->slopes( pointsY );
315 
316  const double *mx = slopesX.constData();
317  const double *my = slopesY.constData();
318 
319  // we don't need it anymore
320  pointsX.clear();
321  pointsY.clear();
322 
323  SplineStore store;
324  store.init( isClosing ? n : n - 1 );
325  store.start( points[0].x(), points[0].y() );
326 
327  int j = 0;
328 
329  for ( int i = 0; i < n - 1; i++ )
330  {
331  const QPointF &p1 = p[i];
332  const QPointF &p2 = p[i+1];
333 
334  const double td = param( p1, p2 );
335 
336  if ( td != 0.0 )
337  {
338  const double t3 = td / 3.0;
339 
340  const double cx1 = p1.x() + mx[j] * t3;
341  const double cy1 = p1.y() + my[j] * t3;
342 
343  const double cx2 = p2.x() - mx[j+1] * t3;
344  const double cy2 = p2.y() - my[j+1] * t3;
345 
346  store.addCubic( cx1, cy1, cx2, cy2, p2.x(), p2.y() );
347 
348  j++;
349  }
350  else
351  {
352  // setting control points to the ends
353  store.addCubic( p1.x(), p1.y(), p2.x(), p2.y(), p2.x(), p2.y() );
354  }
355  }
356 
357  if ( isClosing )
358  {
359  const QPointF &p1 = p[n-1];
360  const QPointF &p2 = p[0];
361 
362  const double td = param( p1, p2 );
363 
364  if ( td != 0.0 )
365  {
366  const double t3 = td / 3.0;
367 
368  const double cx1 = p1.x() + mx[j] * t3;
369  const double cy1 = p1.y() + my[j] * t3;
370 
371  const double cx2 = p2.x() - mx[0] * t3;
372  const double cy2 = p2.y() - my[0] * t3;
373 
374  store.addCubic( cx1, cy1, cx2, cy2, p2.x(), p2.y() );
375  }
376  else
377  {
378  store.addCubic( p1.x(), p1.y(), p2.x(), p2.y(), p2.x(), p2.y() );
379  }
380 
381  store.end();
382  }
383 
384  return store;
385 }
386 
387 template< QwtSplinePolynomial toPolynomial( const QPointF &, double, const QPointF &, double ) >
388 static QPolygonF qwtPolygonParametric( double distance,
389  const QPolygonF &points, const QVector<double> &values, bool withNodes )
390 {
391  QPolygonF fittedPoints;
392 
393  const QPointF *p = points.constData();
394  const double *v = values.constData();
395 
396  fittedPoints += p[0];
397  double t = distance;
398 
399  const int n = points.size();
400 
401  for ( int i = 0; i < n - 1; i++ )
402  {
403  const QPointF &p1 = p[i];
404  const QPointF &p2 = p[i+1];
405 
406  const QwtSplinePolynomial polynomial = toPolynomial( p1, v[i], p2, v[i+1] );
407 
408  const double l = p2.x() - p1.x();
409 
410  while ( t < l )
411  {
412  fittedPoints += QPointF( p1.x() + t, p1.y() + polynomial.valueAt( t ) );
413  t += distance;
414  }
415 
416  if ( withNodes )
417  {
418  if ( qFuzzyCompare( fittedPoints.last().x(), p2.x() ) )
419  fittedPoints.last() = p2;
420  else
421  fittedPoints += p2;
422  }
423  else
424  {
425  t -= l;
426  }
427  }
428 
429  return fittedPoints;
430 }
431 
433 {
434 public:
436  boundaryType( QwtSpline::ConditionalBoundaries )
437  {
438  parametrization = new QwtSplineParametrization(
440 
441  // parabolic runout at both ends
442 
443  boundaryConditions[0].type = QwtSpline::Clamped3;
444  boundaryConditions[0].value = 0.0;
445 
446  boundaryConditions[1].type = QwtSpline::Clamped3;
447  boundaryConditions[1].value = 0.0;
448  }
449 
451  {
452  delete parametrization;
453  }
454 
457 
458  struct
459  {
460  int type;
461  double value;
462 
463  } boundaryConditions[2];
464 };
465 
494 QPolygonF QwtSpline::polygon( const QPolygonF &points, double tolerance ) const
495 {
496  if ( tolerance <= 0.0 )
497  return QPolygonF();
498 
499  const QPainterPath path = painterPath( points );
500  const int n = path.elementCount();
501  if ( n == 0 )
502  return QPolygonF();
503 
504  const QPainterPath::Element el = path.elementAt( 0 );
505  if ( el.type != QPainterPath::MoveToElement )
506  return QPolygonF();
507 
508  QPointF p1( el.x, el.y );
509 
510  QPolygonF polygon;
511  QwtBezier bezier( tolerance );
512 
513  for ( int i = 1; i < n; i += 3 )
514  {
515  const QPainterPath::Element el1 = path.elementAt( i );
516  const QPainterPath::Element el2 = path.elementAt( i + 1 );
517  const QPainterPath::Element el3 = path.elementAt( i + 2 );
518 
519  const QPointF cp1( el1.x, el1.y );
520  const QPointF cp2( el2.x, el2.y );
521  const QPointF p2( el3.x, el3.y );
522 
523  bezier.appendToPolygon( p1, cp1, cp2, p2, polygon );
524 
525  p1 = p2;
526  }
527 
528  return polygon;
529 }
530 
539 {
540  d_data = new PrivateData;
541 }
542 
545 {
546  delete d_data;
547 }
548 
563 {
564  return 0;
565 }
566 
575 {
576  if ( d_data->parametrization->type() != type )
577  {
578  delete d_data->parametrization;
579  d_data->parametrization = new QwtSplineParametrization( type );
580  }
581 }
582 
591 {
592  if ( ( parametrization != NULL ) && ( d_data->parametrization != parametrization ) )
593  {
594  delete d_data->parametrization;
595  d_data->parametrization = parametrization;
596  }
597 }
598 
604 {
605  return d_data->parametrization;
606 }
607 
616 {
617  d_data->boundaryType = boundaryType;
618 }
619 
625 {
626  return d_data->boundaryType;
627 }
628 
637 void QwtSpline::setBoundaryCondition( BoundaryPosition position, int condition )
638 {
639  if ( ( position == QwtSpline::AtBeginning ) || ( position == QwtSpline::AtEnd ) )
640  d_data->boundaryConditions[position].type = condition;
641 }
642 
650 {
651  if ( ( position == QwtSpline::AtBeginning ) || ( position == QwtSpline::AtEnd ) )
652  return d_data->boundaryConditions[position].type;
653 
654  return d_data->boundaryConditions[0].type; // should never happen
655 }
656 
668 void QwtSpline::setBoundaryValue( BoundaryPosition position, double value )
669 {
670  if ( ( position == QwtSpline::AtBeginning ) || ( position == QwtSpline::AtEnd ) )
671  d_data->boundaryConditions[position].value = value;
672 }
673 
681 {
682  if ( ( position == QwtSpline::AtBeginning ) || ( position == QwtSpline::AtEnd ) )
683  return d_data->boundaryConditions[position].value;
684 
685  return d_data->boundaryConditions[0].value; // should never happen
686 }
687 
699  int condition, double valueBegin, double valueEnd )
700 {
701  setBoundaryCondition( QwtSpline::AtBeginning, condition );
702  setBoundaryValue( QwtSpline::AtBeginning, valueBegin );
703 
704  setBoundaryCondition( QwtSpline::AtEnd, condition );
705  setBoundaryValue( QwtSpline::AtEnd, valueEnd );
706 }
707 
710 {
711 }
712 
715 {
716 }
717 
746 QPainterPath QwtSplineInterpolating::painterPath( const QPolygonF &points ) const
747 {
748  const int n = points.size();
749 
750  QPainterPath path;
751  if ( n == 0 )
752  return path;
753 
754  if ( n == 1 )
755  {
756  path.moveTo( points[0] );
757  return path;
758  }
759 
760  if ( n == 2 )
761  {
762  path.addPolygon( points );
763  return path;
764  }
765 
766  const QVector<QLineF> controlLines = bezierControlLines( points );
767  if ( controlLines.size() < n - 1 )
768  return path;
769 
770  const QPointF *p = points.constData();
771  const QLineF *l = controlLines.constData();
772 
773  path.moveTo( p[0] );
774  for ( int i = 0; i < n - 1; i++ )
775  path.cubicTo( l[i].p1(), l[i].p2(), p[i+1] );
776 
777  if ( ( boundaryType() == QwtSpline::ClosedPolygon )
778  && ( controlLines.size() >= n ) )
779  {
780  path.cubicTo( l[n-1].p1(), l[n-1].p2(), p[0] );
781  path.closeSubpath();
782  }
783 
784  return path;
785 }
786 
804  const QPolygonF &points, double tolerance ) const
805 {
806  if ( tolerance <= 0.0 )
807  return QPolygonF();
808 
809  const QVector<QLineF> controlLines = bezierControlLines( points );
810  if ( controlLines.isEmpty() )
811  return QPolygonF();
812 
813  const bool isClosed = boundaryType() == QwtSpline::ClosedPolygon;
814 
815  QwtBezier bezier( tolerance );
816 
817  const QPointF *p = points.constData();
818  const QLineF *cl = controlLines.constData();
819 
820  const int n = controlLines.size();
821 
822  QPolygonF polygon;
823 
824  for ( int i = 0; i < n - 1; i++ )
825  {
826  const QLineF &l = cl[i];
827  bezier.appendToPolygon( p[i], l.p1(), l.p2(), p[i+1], polygon );
828  }
829 
830  const QPointF &pn = isClosed ? p[0] : p[n];
831  const QLineF &l = cl[n-1];
832 
833  bezier.appendToPolygon( p[n-1], l.p1(), l.p2(), pn, polygon );
834 
835  return polygon;
836 }
837 
861 QPolygonF QwtSplineInterpolating::equidistantPolygon( const QPolygonF &points,
862  double distance, bool withNodes ) const
863 {
864  if ( distance <= 0.0 )
865  return QPolygonF();
866 
867  const int n = points.size();
868  if ( n <= 1 )
869  return points;
870 
871  if ( n == 2 )
872  {
873  // TODO
874  return points;
875  }
876 
877  QPolygonF path;
878 
879  const QVector<QLineF> controlLines = bezierControlLines( points );
880 
881  if ( controlLines.size() < n - 1 )
882  return path;
883 
884  path += points.first();
885  double t = distance;
886 
887  const QPointF *p = points.constData();
888  const QLineF *cl = controlLines.constData();
889 
890  const QwtSplineParametrization *param = parametrization();
891 
892  for ( int i = 0; i < n - 1; i++ )
893  {
894  const double l = param->valueIncrement( p[i], p[i+1] );
895 
896  while ( t < l )
897  {
898  path += QwtBezier::pointAt( p[i], cl[i].p1(),
899  cl[i].p2(), p[i+1], t / l );
900 
901  t += distance;
902  }
903 
904  if ( withNodes )
905  {
906  if ( qFuzzyCompare( path.last().x(), p[i+1].x() ) )
907  path.last() = p[i+1];
908  else
909  path += p[i+1];
910 
911  t = distance;
912  }
913  else
914  {
915  t -= l;
916  }
917  }
918 
919  if ( ( boundaryType() == QwtSpline::ClosedPolygon )
920  && ( controlLines.size() >= n ) )
921  {
922  const double l = param->valueIncrement( p[n-1], p[0] );
923 
924  while ( t < l )
925  {
926  path += QwtBezier::pointAt( p[n-1], cl[n-1].p1(),
927  cl[n-1].p2(), p[0], t / l );
928 
929  t += distance;
930  }
931 
932  if ( qFuzzyCompare( path.last().x(), p[0].x() ) )
933  path.last() = p[0];
934  else
935  path += p[0];
936  }
937 
938  return path;
939 }
940 
943 {
944 }
945 
948 {
949 }
950 
961 {
962  setParametrization( QwtSplineParametrization::ParameterX );
963 }
964 
967 {
968 }
969 
977 double QwtSplineC1::slopeAtBeginning( const QPolygonF &points, double slopeNext ) const
978 {
979  if ( points.size() < 2 )
980  return 0.0;
981 
983  boundaryCondition( QwtSpline::AtBeginning ),
984  boundaryValue( QwtSpline::AtBeginning ),
985  points[0], points[1], slopeNext );
986 }
987 
995 double QwtSplineC1::slopeAtEnd( const QPolygonF &points, double slopeBefore ) const
996 {
997  const int n = points.size();
998 
999  const QPointF p1( points[n-1].x(), -points[n-1].y() );
1000  const QPointF p2( points[n-2].x(), -points[n-2].y() );
1001 
1002  const int condition = boundaryCondition( QwtSpline::AtEnd );
1003 
1004  double value = boundaryValue( QwtSpline::AtEnd );
1005  if ( condition != QwtSpline::LinearRunout )
1006  {
1007  // beside LinearRunout the boundaryValue is a slope or curvature
1008  // and needs to be inverted too
1009  value = -value;
1010  }
1011 
1012  const double slope = QwtSplineC1P::slopeBoundary( condition, value, p1, p2, -slopeBefore );
1013  return -slope;
1014 }
1015 
1041 QPainterPath QwtSplineC1::painterPath( const QPolygonF &points ) const
1042 {
1043  const int n = points.size();
1044  if ( n <= 2 )
1045  return QwtSplineInterpolating::painterPath( points );
1046 
1047  using namespace QwtSplineC1P;
1048 
1049  PathStore store;
1050  switch( parametrization()->type() )
1051  {
1053  {
1054  store = qwtSplineC1PathParamX<PathStore>( this, points );
1055  break;
1056  }
1058  {
1059  store = qwtSplineC1PathParamY<PathStore>( this, points );
1060  break;
1061  }
1063  {
1064  store = qwtSplineC1PathParametric<PathStore>(
1065  this, points, paramUniform() );
1066  break;
1067  }
1069  {
1070  store = qwtSplineC1PathParametric<PathStore>(
1071  this, points, paramCentripetal() );
1072  break;
1073  }
1075  {
1076  store = qwtSplineC1PathParametric<PathStore>(
1077  this, points, paramChordal() );
1078  break;
1079  }
1080  default:
1081  {
1082  store = qwtSplineC1PathParametric<PathStore>(
1083  this, points, param( parametrization() ) );
1084  }
1085  }
1086 
1087  return store.path;
1088 }
1089 
1099 QVector<QLineF> QwtSplineC1::bezierControlLines( const QPolygonF &points ) const
1100 {
1101  using namespace QwtSplineC1P;
1102 
1103  const int n = points.size();
1104  if ( n <= 2 )
1105  return QVector<QLineF>();
1106 
1107  ControlPointsStore store;
1108  switch( parametrization()->type() )
1109  {
1111  {
1112  store = qwtSplineC1PathParamX<ControlPointsStore>( this, points );
1113  break;
1114  }
1116  {
1117  store = qwtSplineC1PathParamY<ControlPointsStore>( this, points );
1118  break;
1119  }
1121  {
1122  store = qwtSplineC1PathParametric<ControlPointsStore>(
1123  this, points, paramUniform() );
1124  break;
1125  }
1127  {
1128  store = qwtSplineC1PathParametric<ControlPointsStore>(
1129  this, points, paramCentripetal() );
1130  break;
1131  }
1133  {
1134  store = qwtSplineC1PathParametric<ControlPointsStore>(
1135  this, points, paramChordal() );
1136  break;
1137  }
1138  default:
1139  {
1140  store = qwtSplineC1PathParametric<ControlPointsStore>(
1141  this, points, param( parametrization() ) );
1142  }
1143  }
1144 
1145  return store.controlPoints;
1146 }
1147 
1165 QPolygonF QwtSplineC1::equidistantPolygon( const QPolygonF &points,
1166  double distance, bool withNodes ) const
1167 {
1168  if ( parametrization()->type() == QwtSplineParametrization::ParameterX )
1169  {
1170  if ( points.size() > 2 )
1171  {
1172  const QVector<double> m = slopes( points );
1173  if ( m.size() != points.size() )
1174  return QPolygonF();
1175 
1176  return qwtPolygonParametric<QwtSplinePolynomial::fromSlopes>(
1177  distance, points, m, withNodes );
1178  }
1179  }
1180 
1181  return QwtSplineInterpolating::equidistantPolygon( points, distance, withNodes );
1182 }
1183 
1199 QVector<QwtSplinePolynomial> QwtSplineC1::polynomials(
1200  const QPolygonF &points ) const
1201 {
1202  QVector<QwtSplinePolynomial> polynomials;
1203 
1204  const QVector<double> m = slopes( points );
1205  if ( m.size() < 2 )
1206  return polynomials;
1207 
1208  polynomials.reserve( m.size() - 1 );
1209  for ( int i = 1; i < m.size(); i++ )
1210  {
1211  polynomials += QwtSplinePolynomial::fromSlopes(
1212  points[i-1], m[i-1], points[i], m[i] );
1213  }
1214 
1215  return polynomials;
1216 }
1217 
1227 {
1228 }
1229 
1232 {
1233 }
1234 
1247 QPainterPath QwtSplineC2::painterPath( const QPolygonF &points ) const
1248 {
1249  // could be implemented from curvatures without the extra
1250  // loop for calculating the slopes vector. TODO ...
1251 
1252  return QwtSplineC1::painterPath( points );
1253 }
1254 
1268 QVector<QLineF> QwtSplineC2::bezierControlLines( const QPolygonF &points ) const
1269 {
1270  // could be implemented from curvatures without the extra
1271  // loop for calculating the slopes vector. TODO ...
1272 
1273  return QwtSplineC1::bezierControlLines( points );
1274 }
1275 
1293 QPolygonF QwtSplineC2::equidistantPolygon( const QPolygonF &points,
1294  double distance, bool withNodes ) const
1295 {
1296  if ( parametrization()->type() == QwtSplineParametrization::ParameterX )
1297  {
1298  if ( points.size() > 2 )
1299  {
1300  const QVector<double> cv = curvatures( points );
1301  if ( cv.size() != points.size() )
1302  return QPolygonF();
1303 
1304  return qwtPolygonParametric<QwtSplinePolynomial::fromCurvatures>(
1305  distance, points, cv, withNodes );
1306  }
1307  }
1308 
1309  return QwtSplineInterpolating::equidistantPolygon( points, distance, withNodes );
1310 }
1311 
1337 QVector<double> QwtSplineC2::slopes( const QPolygonF &points ) const
1338 {
1339  const QVector<double> curvatures = this->curvatures( points );
1340  if ( curvatures.size() < 2 )
1341  return QVector<double>();
1342 
1343  QVector<double> slopes( curvatures.size() );
1344 
1345  const double *cv = curvatures.constData();
1346  double *m = slopes.data();
1347 
1348  const int n = points.size();
1349  const QPointF *p = points.constData();
1350 
1351  QwtSplinePolynomial polynomial;
1352 
1353  for ( int i = 0; i < n - 1; i++ )
1354  {
1355  polynomial = QwtSplinePolynomial::fromCurvatures( p[i], cv[i], p[i+1], cv[i+1] );
1356  m[i] = polynomial.c1;
1357  }
1358 
1359  m[n-1] = polynomial.slopeAt( p[n-1].x() - p[n-2].x() );
1360 
1361  return slopes;
1362 }
1363 
1379 QVector<QwtSplinePolynomial> QwtSplineC2::polynomials( const QPolygonF &points ) const
1380 {
1381  QVector<QwtSplinePolynomial> polynomials;
1382 
1383  const QVector<double> curvatures = this->curvatures( points );
1384  if ( curvatures.size() < 2 )
1385  return polynomials;
1386 
1387  const QPointF *p = points.constData();
1388  const double *cv = curvatures.constData();
1389  const int n = curvatures.size();
1390  polynomials.reserve( n - 1 );
1391 
1392  for ( int i = 1; i < n; i++ )
1393  {
1394  polynomials += QwtSplinePolynomial::fromCurvatures(
1395  p[i-1], cv[i-1], p[i], cv[i] );
1396  }
1397 
1398  return polynomials;
1399 }
int v
Curve parametrization used for a spline interpolation.
static QPointF pointAt(const QPointF &p1, const QPointF &cp1, const QPointF &cp2, const QPointF &p2, double t)
Definition: qwt_bezier.h:70
virtual ~QwtSplineC1()
Destructor.
Definition: qwt_spline.cpp:966
virtual QPainterPath painterPath(const QPolygonF &) const
Interpolate a curve with Bezier curves.
Definition: qwt_spline.cpp:746
double operator()(const QPointF &p1, const QPointF &p2) const
Definition: qwt_spline.cpp:34
virtual uint locality() const
Definition: qwt_spline.cpp:562
static QPolygonF qwtPolygonParametric(double distance, const QPolygonF &points, const QVector< double > &values, bool withNodes)
Definition: qwt_spline.cpp:388
void appendToPolygon(const QPointF &p1, const QPointF &cp1, const QPointF &cp2, const QPointF &p2, QPolygonF &polygon) const
Interpolate a Bézier curve by a polygon.
Definition: qwt_bezier.cpp:183
double c1
coefficient of the linear summand
static double valueIncrementCentripetal(const QPointF &, const QPointF &)
Calculate the ParameterCentripetal value increment for 2 points.
double slopeAt(double x) const
virtual QPainterPath painterPath(const QPolygonF &) const
Calculate an interpolated painter path.
virtual QPolygonF equidistantPolygon(const QPolygonF &, double distance, bool withNodes) const
Find an interpolated polygon with "equidistant" points.
Definition: qwt_spline.cpp:861
QwtSplineParametrization * parametrization
Definition: qwt_spline.cpp:455
static double valueIncrementChordal(const QPointF &, const QPointF &)
Calculate the ParameterChordal value increment for 2 points.
param(const QwtSplineParametrization *p)
Definition: qwt_spline.cpp:19
static SplineStore qwtSplineC1PathParamX(const QwtSplineC1 *spline, const QPolygonF &points)
Definition: qwt_spline.cpp:187
double valueAt(double x) const
XmlRpcServer s
QwtSplineG1()
Constructor.
Definition: qwt_spline.cpp:942
virtual QVector< double > slopes(const QPolygonF &) const =0
Find the first derivative at the control points.
virtual ~QwtSplineG1()
Destructor.
Definition: qwt_spline.cpp:947
virtual QVector< QwtSplinePolynomial > polynomials(const QPolygonF &) const
Calculate the interpolating polynomials for a non parametric spline.
virtual QVector< QLineF > bezierControlLines(const QPolygonF &) const
Interpolate a curve with Bezier curves.
Base class for all splines.
Definition: qwt_spline.h:53
double operator()(const QPointF &p1, const QPointF &p2) const
Definition: qwt_spline.cpp:50
double slopeBoundary(int boundaryCondition, double boundaryValue, const QPointF &p1, const QPointF &p2, double slope1)
Definition: qwt_spline.cpp:139
TFSIMD_FORCE_INLINE const tfScalar & y() const
const QwtSplineParametrization * parametrization() const
Definition: qwt_spline.cpp:603
the condiation is at the end of the polynomial
Definition: qwt_spline.h:101
static SplineStore qwtSplineC1PathParametric(const QwtSplineC1 *spline, const QPolygonF &points, Param param)
Definition: qwt_spline.cpp:253
void setBoundaryConditions(int condition, double valueBegin=0.0, double valueEnd=0.0)
Define the condition at the endpoints of a spline.
Definition: qwt_spline.cpp:698
void setBoundaryCondition(BoundaryPosition, int condition)
Define the condition for an endpoint of the spline.
Definition: qwt_spline.cpp:637
virtual ~QwtSplineC2()
Destructor.
double operator()(const QPointF &p1, const QPointF &p2) const
Definition: qwt_spline.cpp:66
virtual double valueIncrement(const QPointF &, const QPointF &) const
Calculate the parameter value increment for 2 points.
QwtSplineC2()
Constructor.
virtual QPolygonF equidistantPolygon(const QPolygonF &, double distance, bool withNodes) const
Find an interpolated polygon with "equidistant" points.
QwtSpline::BoundaryType boundaryType
Definition: qwt_spline.cpp:456
A cubic polynomial without constant term.
Base class for spline interpolations providing a first order parametric continuity ( C1 ) between adj...
Definition: qwt_spline.h:230
const QwtSplineParametrization * parameter
Definition: qwt_spline.cpp:29
the condiation is at the beginning of the polynomial
Definition: qwt_spline.h:98
GraphId path[kMaxDeadlockPathLen]
An implementation of the de Casteljau’s Algorithm for interpolating Bézier curves.
Definition: qwt_bezier.h:27
virtual QPolygonF equidistantPolygon(const QPolygonF &, double distance, bool withNodes) const
Find an interpolated polygon with "equidistant" points.
virtual QPainterPath painterPath(const QPolygonF &) const
Interpolate a curve with Bezier curves.
T value
static double valueIncrementY(const QPointF &, const QPointF &)
Calculate the ParameterY value increment for 2 points.
void setBoundaryValue(BoundaryPosition, double value)
Define the boundary value.
Definition: qwt_spline.cpp:668
QwtSpline()
Constructor.
Definition: qwt_spline.cpp:538
virtual ~QwtSplineInterpolating()
Destructor.
Definition: qwt_spline.cpp:714
double operator()(const QPointF &p1, const QPointF &p2) const
Definition: qwt_spline.cpp:58
TFSIMD_FORCE_INLINE const tfScalar & x() const
void addCubic(double cx1, double cy1, double cx2, double cy2, double x2, double y2)
Definition: qwt_spline.cpp:119
virtual ~QwtSpline()
Destructor.
Definition: qwt_spline.cpp:544
void addCubic(double cx1, double cy1, double cx2, double cy2, double x2, double y2)
Definition: qwt_spline.cpp:85
int boundaryCondition(BoundaryPosition) const
Definition: qwt_spline.cpp:649
double operator()(const QPointF &p1, const QPointF &p2) const
Definition: qwt_spline.cpp:24
static double valueIncrementUniform(const QPointF &, const QPointF &)
Calculate the ParameterUniform value increment.
static QwtSplinePolynomial fromSlopes(const QPointF &p1, double m1, const QPointF &p2, double m2)
QwtSplineC1()
Constructor.
Definition: qwt_spline.cpp:960
double operator()(const QPointF &p1, const QPointF &p2) const
Definition: qwt_spline.cpp:42
QwtSplineInterpolating()
Constructor.
Definition: qwt_spline.cpp:709
void setParametrization(int type)
Definition: qwt_spline.cpp:574
virtual QPolygonF polygon(const QPolygonF &, double tolerance) const
Interpolate a curve by a polygon.
Definition: qwt_spline.cpp:494
virtual QPolygonF polygon(const QPolygonF &, double tolerance) const
Interpolate a curve by a polygon.
Definition: qwt_spline.cpp:803
static SplineStore qwtSplineC1PathParamY(const QwtSplineC1 *spline, const QPolygonF &points)
Definition: qwt_spline.cpp:216
void start(double x1, double y1)
Definition: qwt_spline.cpp:80
virtual double slopeAtBeginning(const QPolygonF &, double slopeNext) const
Definition: qwt_spline.cpp:977
virtual QVector< double > slopes(const QPolygonF &) const
Find the first derivative at the control points.
static QwtSplinePolynomial fromCurvatures(const QPointF &p1, double cv1, const QPointF &p2, double cv2)
virtual QVector< QwtSplinePolynomial > polynomials(const QPolygonF &) const
Calculate the interpolating polynomials for a non parametric spline.
virtual QVector< QLineF > bezierControlLines(const QPolygonF &) const
Interpolate a curve with Bezier curves.
virtual double slopeAtEnd(const QPolygonF &, double slopeBefore) const
Definition: qwt_spline.cpp:995
BoundaryType boundaryType() const
Definition: qwt_spline.cpp:624
int i
double boundaryValue(BoundaryPosition) const
Definition: qwt_spline.cpp:680
void init(int size)
Definition: qwt_spline.cpp:75
BoundaryPosition
Definition: qwt_spline.h:95
int n
void start(double x1, double y1)
Definition: qwt_spline.cpp:113
void setBoundaryType(BoundaryType)
Definition: qwt_spline.cpp:615
static double valueIncrementManhattan(const QPointF &, const QPointF &)
Calculate the ParameterManhattan value increment for 2 points.


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