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


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Nov 11 2024 03:23:46