qwt_spline_pleasing.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_pleasing.h"
12 
13 #include <qpainterpath.h>
14 
15 static inline double qwtChordalLength( const QPointF& point1, const QPointF& point2 )
16 {
17  const double dx = point2.x() - point1.x();
18  const double dy = point2.y() - point1.y();
19 
20  return std::sqrt( dx * dx + dy * dy );
21 }
22 
23 template< class Param >
24 static QPointF qwtVector( Param param,
25  const QPointF& p1, const QPointF& p2 )
26 {
27  return ( p2 - p1 ) / param( p1, p2 );
28 }
29 
30 template< class Param >
31 static QPointF qwtVectorCardinal( Param param,
32  const QPointF& p1, const QPointF& p2, const QPointF& p3 )
33 {
34  const double t1 = param( p1, p2 );
35  const double t2 = param( p2, p3 );
36 
37  return t2 * ( p3 - p1 ) / ( t1 + t2 );
38 }
39 
41 {
42  struct Tension
43  {
44  double t1;
45  double t2;
46  };
47 
48  struct param
49  {
51  parameter( p )
52  {
53  }
54 
55  inline double operator()( const QPointF& p1, const QPointF& p2 ) const
56  {
57  return parameter->valueIncrement( p1, p2 );
58  }
59 
61  };
62 
63  struct paramUniform
64  {
65  inline double operator()( const QPointF& p1, const QPointF& p2 ) const
66  {
68  }
69  };
70 
71  class PathStore
72  {
73  public:
74  inline void init( int )
75  {
76  }
77 
78  inline void start( const QPointF& p0 )
79  {
80  path.moveTo( p0 );
81  }
82 
83  inline void addCubic( const QPointF& cp1,
84  const QPointF& cp2, const QPointF& p2 )
85  {
86  path.cubicTo( cp1, cp2, p2 );
87  }
88 
89  QPainterPath path;
90  };
91 
93  {
94  public:
96  m_cp( NULL )
97  {
98  }
99 
100  inline void init( int size )
101  {
102  controlPoints.resize( size );
103  m_cp = controlPoints.data();
104  }
105 
106  inline void start( const QPointF& )
107  {
108  }
109 
110  inline void addCubic( const QPointF& cp1,
111  const QPointF& cp2, const QPointF& )
112  {
113  QLineF& l = *m_cp++;
114  l.setPoints( cp1, cp2 );
115  }
116 
118 
119  private:
120  QLineF* m_cp;
121  };
122 }
123 
125  double d13, double d23, double d24,
126  const QPointF& p1, const QPointF& p2,
127  const QPointF& p3, const QPointF& p4 )
128 {
130 
131  const bool b1 = ( d13 / 3.0 ) < d23;
132  const bool b2 = ( d24 / 3.0 ) < d23;
133 
134  if ( b1 )
135  {
136  if ( b2 )
137  {
138  tension.t1 = ( p1 != p2 ) ? ( 1.0 / 3.0 ) : ( 2.0 / 3.0 );
139  tension.t2 = ( p3 != p4 ) ? ( 1.0 / 3.0 ) : ( 2.0 / 3.0 );
140  }
141  else
142  {
143  tension.t1 = tension.t2 = d23 / d24;
144  }
145  }
146  else
147  {
148  if ( b2 )
149  {
150  tension.t1 = tension.t2 = d23 / d13;
151  }
152  else
153  {
154  tension.t1 = d23 / d13;
155  tension.t2 = d23 / d24;
156  }
157  }
158 
159  return tension;
160 }
161 
162 template< class SplineStore, class Param >
163 static SplineStore qwtSplinePathPleasing( const QPolygonF& points,
164  bool isClosed, Param param )
165 {
166  using namespace QwtSplinePleasingP;
167 
168  const int size = points.size();
169 
170  const QPointF* p = points.constData();
171 
172  SplineStore store;
173  store.init( isClosed ? size : size - 1 );
174  store.start( p[0] );
175 
176  double d13;
177  QPointF vec1;
178 
179  if ( isClosed )
180  {
181  d13 = qwtChordalLength(p[0], p[2]);
182 
183  const Tension t0 = qwtTensionPleasing(
184  qwtChordalLength( p[size - 1], p[1]), qwtChordalLength(p[0], p[1]),
185  d13, p[size - 1], p[0], p[1], p[2] );
186 
187  const QPointF vec0 = qwtVectorCardinal< Param >( param, p[size - 1], p[0], p[1] );
188  vec1 = qwtVectorCardinal< Param >( param, p[0], p[1], p[2] );
189 
190  store.addCubic( p[0] + vec0 * t0.t1, p[1] - vec1 * t0.t2, p[1] );
191  }
192  else
193  {
194  d13 = qwtChordalLength(p[0], p[2]);
195 
196  const Tension t0 = qwtTensionPleasing(
197  qwtChordalLength( p[0], p[1]), qwtChordalLength(p[0], p[1]),
198  d13, p[0], p[0], p[1], p[2] );
199 
200  const QPointF vec0 = 0.5 * qwtVector< Param >( param, p[0], p[1] );
201  vec1 = qwtVectorCardinal< Param >( param, p[0], p[1], p[2] );
202 
203  store.addCubic( p[0] + vec0 * t0.t1, p[1] - vec1 * t0.t2, p[1] );
204  }
205 
206  for ( int i = 1; i < size - 2; i++ )
207  {
208  const double d23 = qwtChordalLength( p[i], p[i + 1] );
209  const double d24 = qwtChordalLength( p[i], p[i + 2] );
210 
211  const QPointF vec2 = qwtVectorCardinal< Param >( param, p[i], p[i + 1], p[i + 2] );
212 
213  const Tension t = qwtTensionPleasing(
214  d13, d23, d24, p[i - 1], p[i], p[i + 1], p[i + 2] );
215 
216  store.addCubic( p[i] + vec1 * t.t1, p[i + 1] - vec2 * t.t2, p[i + 1] );
217 
218  d13 = d24;
219  vec1 = vec2;
220  }
221 
222  if ( isClosed )
223  {
224  const double d24 = qwtChordalLength( p[size - 2], p[0] );
225 
226  const Tension tn = qwtTensionPleasing(
227  d13, qwtChordalLength( p[size - 2], p[size - 1] ), d24,
228  p[size - 3], p[size - 2], p[size - 1], p[0] );
229 
230  const QPointF vec2 = qwtVectorCardinal< Param >( param, p[size - 2], p[size - 1], p[0] );
231  store.addCubic( p[size - 2] + vec1 * tn.t1, p[size - 1] - vec2 * tn.t2, p[size - 1] );
232 
233  const double d34 = qwtChordalLength( p[size - 1], p[0] );
234  const double d35 = qwtChordalLength( p[size - 1], p[1] );
235 
236  const Tension tc = qwtTensionPleasing( d24, d34, d35, p[size - 2], p[size - 1], p[0], p[1] );
237 
238  const QPointF vec3 = qwtVectorCardinal< Param >( param, p[size - 1], p[0], p[1] );
239 
240  store.addCubic( p[size - 1] + vec2 * tc.t1, p[0] - vec3 * tc.t2, p[0] );
241  }
242  else
243  {
244  const double d24 = qwtChordalLength( p[size - 2], p[size - 1] );
245 
246  const Tension tn = qwtTensionPleasing(
247  d13, qwtChordalLength( p[size - 2], p[size - 1] ), d24,
248  p[size - 3], p[size - 2], p[size - 1], p[size - 1] );
249 
250  const QPointF vec2 = 0.5 * qwtVector< Param >( param, p[size - 2], p[size - 1] );
251  store.addCubic( p[size - 2] + vec1 * tn.t1, p[size - 1] - vec2 * tn.t2, p[size - 1] );
252  }
253 
254  return store;
255 }
256 
266 {
268 }
269 
272 {
273 }
274 
277 {
278  return 2;
279 }
280 
290 QPainterPath QwtSplinePleasing::painterPath( const QPolygonF& points ) const
291 {
292  const int size = points.size();
293  if ( size <= 2 )
294  return QwtSplineG1::painterPath( points );
295 
296  const bool isClosing = ( boundaryType() == QwtSpline::ClosedPolygon );
297 
298  using namespace QwtSplinePleasingP;
299 
300  PathStore store;
302  {
303  store = qwtSplinePathPleasing< PathStore >( points,
304  isClosing, paramUniform() );
305  }
306  else
307  {
308  store = qwtSplinePathPleasing< PathStore >( points,
309  isClosing, param( parametrization() ) );
310  }
311 
312  if ( isClosing )
313  store.path.closeSubpath();
314 
315  return store.path;
316 }
317 
328  const QPolygonF& points ) const
329 {
330  const int size = points.size();
331  if ( size <= 2 )
332  return QVector< QLineF >();
333 
334  const bool isClosing = ( boundaryType() == QwtSpline::ClosedPolygon );
335 
336  using namespace QwtSplinePleasingP;
337 
338  ControlPointsStore store;
340  {
341  store = qwtSplinePathPleasing< ControlPointsStore >( points,
342  isClosing, paramUniform() );
343  }
344  else
345  {
346  store = qwtSplinePathPleasing< ControlPointsStore >( points,
347  isClosing, param( parametrization() ) );
348  }
349 
350  return store.controlPoints;
351 }
QwtSpline::boundaryType
BoundaryType boundaryType() const
Definition: qwt_spline.cpp:626
QwtSplinePleasing::~QwtSplinePleasing
virtual ~QwtSplinePleasing()
Destructor.
Definition: qwt_spline_pleasing.cpp:271
QwtSplineParametrization::valueIncrementUniform
static double valueIncrementUniform(const QPointF &, const QPointF &)
Calculate the ParameterUniform value increment.
Definition: qwt_spline_parametrization.h:162
QwtSplinePleasingP::ControlPointsStore::addCubic
void addCubic(const QPointF &cp1, const QPointF &cp2, const QPointF &)
Definition: qwt_spline_pleasing.cpp:110
QwtSplinePleasingP::param::parameter
const QwtSplineParametrization * parameter
Definition: qwt_spline_pleasing.cpp:60
QwtSplinePleasingP::paramUniform
Definition: qwt_spline_pleasing.cpp:63
QwtSplinePleasingP::ControlPointsStore::ControlPointsStore
ControlPointsStore()
Definition: qwt_spline_pleasing.cpp:95
QwtSplineParametrization
Curve parametrization used for a spline interpolation.
Definition: qwt_spline_parametrization.h:44
QwtSplinePleasingP::ControlPointsStore::controlPoints
QVector< QLineF > controlPoints
Definition: qwt_spline_pleasing.cpp:117
QwtSplinePleasingP::param::param
param(const QwtSplineParametrization *p)
Definition: qwt_spline_pleasing.cpp:50
QVector< QLineF >
QwtSplineParametrization::type
int type() const
Definition: qwt_spline_parametrization.cpp:72
QwtSplinePleasingP::ControlPointsStore
Definition: qwt_spline_pleasing.cpp:92
QwtSplinePleasingP::PathStore::start
void start(const QPointF &p0)
Definition: qwt_spline_pleasing.cpp:78
QwtSplinePleasingP::param
Definition: qwt_spline_pleasing.cpp:48
qwtVectorCardinal
static QPointF qwtVectorCardinal(Param param, const QPointF &p1, const QPointF &p2, const QPointF &p3)
Definition: qwt_spline_pleasing.cpp:31
qwtVector
static QPointF qwtVector(Param param, const QPointF &p1, const QPointF &p2)
Definition: qwt_spline_pleasing.cpp:24
QwtSplinePleasingP::paramUniform::operator()
double operator()(const QPointF &p1, const QPointF &p2) const
Definition: qwt_spline_pleasing.cpp:65
QwtSpline::ClosedPolygon
@ ClosedPolygon
Definition: qwt_spline.h:92
QwtSpline::setParametrization
void setParametrization(int type)
Definition: qwt_spline.cpp:576
QwtSplinePleasingP::ControlPointsStore::start
void start(const QPointF &)
Definition: qwt_spline_pleasing.cpp:106
nonstd::span_lite::size
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1554
QwtSplinePleasing::bezierControlLines
virtual QVector< QLineF > bezierControlLines(const QPolygonF &) const QWT_OVERRIDE
Interpolate a curve with Bezier curves.
Definition: qwt_spline_pleasing.cpp:327
QwtSplinePleasingP::ControlPointsStore::init
void init(int size)
Definition: qwt_spline_pleasing.cpp:100
QwtSplinePleasing::painterPath
virtual QPainterPath painterPath(const QPolygonF &) const QWT_OVERRIDE
Interpolate a curve with Bezier curves.
Definition: qwt_spline_pleasing.cpp:290
QwtSplinePleasingP::PathStore::path
QPainterPath path
Definition: qwt_spline_pleasing.cpp:89
qwt_spline_pleasing.h
QwtSplinePleasingP::Tension::t1
double t1
Definition: qwt_spline_pleasing.cpp:44
qwtSplinePathPleasing
static SplineStore qwtSplinePathPleasing(const QPolygonF &points, bool isClosed, Param param)
Definition: qwt_spline_pleasing.cpp:163
QwtSplineInterpolating::painterPath
virtual QPainterPath painterPath(const QPolygonF &) const QWT_OVERRIDE
Interpolate a curve with Bezier curves.
Definition: qwt_spline.cpp:748
QwtSplinePleasingP::param::operator()
double operator()(const QPointF &p1, const QPointF &p2) const
Definition: qwt_spline_pleasing.cpp:55
QwtSplinePleasingP::PathStore
Definition: qwt_spline_pleasing.cpp:71
QwtSplinePleasingP::Tension::t2
double t2
Definition: qwt_spline_pleasing.cpp:45
QwtSpline::parametrization
const QwtSplineParametrization * parametrization() const
Definition: qwt_spline.cpp:605
QwtSplineParametrization::valueIncrement
virtual double valueIncrement(const QPointF &, const QPointF &) const
Calculate the parameter value increment for 2 points.
Definition: qwt_spline_parametrization.cpp:35
qwtTensionPleasing
static QwtSplinePleasingP::Tension qwtTensionPleasing(double d13, double d23, double d24, const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4)
Definition: qwt_spline_pleasing.cpp:124
QwtSplinePleasingP::PathStore::addCubic
void addCubic(const QPointF &cp1, const QPointF &cp2, const QPointF &p2)
Definition: qwt_spline_pleasing.cpp:83
QwtSplinePleasingP
Definition: qwt_spline_pleasing.cpp:40
qwtChordalLength
static double qwtChordalLength(const QPointF &point1, const QPointF &point2)
Definition: qwt_spline_pleasing.cpp:15
QwtSplinePleasingP::PathStore::init
void init(int)
Definition: qwt_spline_pleasing.cpp:74
param
T param(const std::string &param_name, const T &default_val)
QwtSplinePleasingP::ControlPointsStore::m_cp
QLineF * m_cp
Definition: qwt_spline_pleasing.cpp:120
qwt_spline_parametrization.h
QwtSplinePleasingP::Tension
Definition: qwt_spline_pleasing.cpp:42
QwtSplineParametrization::ParameterUniform
@ ParameterUniform
Definition: qwt_spline_parametrization.h:86
QwtSplinePleasing::QwtSplinePleasing
QwtSplinePleasing()
Constructor.
Definition: qwt_spline_pleasing.cpp:265
QwtSplinePleasing::locality
virtual uint locality() const QWT_OVERRIDE
Definition: qwt_spline_pleasing.cpp:276


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