14 #include <qpainterpath.h> 18 if ( dy1 == 0.0 || dy2 == 0.0 )
21 return ( dy1 > 0.0 ) == ( dy2 > 0.0 );
24 static inline double qwtSlopeLine(
const QPointF &p1,
const QPointF &p2 )
27 const double dx = p2.x() - p1.x();
28 return dx ? ( p2.y() - p1.y() ) / dx : 0.0;
32 double dx1,
double dy1,
double s1,
double dx2,
double dy2,
double s2 )
37 return ( dy1 + dy2 ) / ( dx1 + dx2 );
41 double dx1,
double dy1,
double s1,
double dx2,
double dy2,
double s2 )
46 return ( dx2 * s1 + dx1 * s2 ) / ( dx1 + dx2 );
50 double dx1,
double dy1,
double s1,
double dx2,
double dy2,
double s2 )
56 const double w1 = ( 3 * dx1 + 3 * dx2 ) / ( 2 * dx1 + 4 * dx2 );
57 const double w2 = ( 3 * dx1 + 3 * dx2 ) / ( 4 * dx1 + 2 * dx2 );
63 return 2.0 / ( 1.0 / s1 + 1.0 / s2 );
67 const double s12 = ( dy1 + dy2 ) / ( dx1 + dx2 );
68 return 3.0 * ( s1 * s2 ) / ( s1 + s2 + s12 );
83 inline void start(
const QPointF &p0,
double )
88 inline void addCubic(
const QPointF &p1,
double m1,
89 const QPointF &p2,
double m2 )
91 const double dx3 = ( p2.x() - p1.x() ) / 3.0;
93 path.cubicTo( p1.x() + dx3, p1.y() + m1 * dx3,
94 p2.x() - dx3, p2.y() - m2 * dx3,
106 if ( points.size() > 0 )
107 controlPoints.resize( points.size() - 1 );
108 d_cp = controlPoints.data();
111 inline void start(
const QPointF &,
double )
115 inline void addCubic(
const QPointF &p1,
double m1,
116 const QPointF &p2,
double m2 )
118 const double dx3 = ( p2.x() - p1.x() ) / 3.0;
121 l.setLine( p1.x() + dx3, p1.y() + m1 * dx3,
122 p2.x() - dx3, p2.y() - m2 * dx3 );
136 slopes.resize( points.size() );
140 inline void start(
const QPointF &,
double m0 )
146 const QPointF &,
double m2 )
159 static inline double value(
double dx1,
double dy1,
double s1,
160 double dx2,
double dy2,
double s2 )
168 static inline double value(
double dx1,
double dy1,
double s1,
169 double dx2,
double dy2,
double s2 )
177 static inline double value(
double dx1,
double dy1,
double s1,
178 double dx2,
double dy2,
double s2 )
185 template<
class Slope >
187 const QPointF &p1,
const QPointF &p2,
const QPointF &p3 )
189 const double dx1 = p2.x() - p1.x();
190 const double dy1 = p2.y() - p1.y();
191 const double dx2 = p3.x() - p2.x();
192 const double dy2 = p3.y() - p2.y();
194 return Slope::value( dx1, dy1, dy1 / dx1, dx2, dy2, dy2 / dx2 );
197 static inline double qwtSlopeAkima(
double s1,
double s2,
double s3,
double s4 )
199 if ( ( s1 == s2 ) && ( s3 == s4 ) )
201 return 0.5 * ( s2 + s3 );
204 const double ds12 = qAbs( s2 - s1 );
205 const double ds34 = qAbs( s4 - s3 );
207 return ( s2 * ds34 + s3 * ds12 ) / ( ds12 + ds34 );
211 const QPointF &p3,
const QPointF &p4,
const QPointF &p5 )
221 template<
class Slope >
224 double &slopeBegin,
double &slopeEnd )
226 const int n = points.size();
227 const QPointF *p = points.constData();
232 const QPointF pn = p[0] - ( p[n-1] - p[n-2] );
233 slopeBegin = slopeEnd = qwtSlopeP3<Slope>( pn, p[0], p[1] );
237 const double m2 = qwtSlopeP3<Slope>( p[0], p[1], p[2] );
240 const double mn2 = qwtSlopeP3<Slope>( p[n-3], p[n-2], p[n-1] );
245 template<
class SplineStore,
class Slope >
249 const int size = points.size();
250 const QPointF *p = points.constData();
252 double slopeBegin, slopeEnd;
253 qwtSplineBoundariesL1<Slope>( spline, points, slopeBegin, slopeEnd );
255 double m1 = slopeBegin;
258 store.init( points );
259 store.start( p[0], m1 );
261 double dx1 = p[1].x() - p[0].x();
262 double dy1 = p[1].y() - p[0].y();
263 double s1 = dy1 / dx1;
265 for (
int i = 1; i < size - 1; i++ )
267 const double dx2 = p[i+1].x() - p[i].x();
268 const double dy2 = p[i+1].y() - p[i].y() ;
272 const double s2 = dy2 / dx2;
274 const double m2 =
Slope::value( dx1, dy1, s1, dx2, dy2, s2 );
276 store.addCubic( p[i-1], m1, p[i], m2 );
284 store.addCubic( p[size-2], m1, p[size-1], slopeEnd );
291 double &slopeBegin,
double &slopeEnd )
293 const int n = points.size();
294 const QPointF *p = points.constData();
299 const QPointF p2 = p[0] - ( p[n-1] - p[n-2] );
300 const QPointF p1 = p2 - ( p[n-2] - p[n-3] );
302 slopeBegin = slopeEnd =
qwtSlopeAkima( p1, p2, p[0], p[1], p[2] );
320 const double m =
qwtSlopeAkima( 0.5 * s1, s1, s2, 0.5 * s2 );
333 const double m2 =
qwtSlopeAkima( 0.5 * s[0], s[0], s[1], s[2] );
341 const double mn2 =
qwtSlopeAkima( s[0], s[1], s[2], 0.5 * s[2] );
347 template<
class SplineStore >
351 const int size = points.size();
352 const QPointF *p = points.constData();
354 double slopeBegin, slopeEnd;
357 double m1 = slopeBegin;
360 store.init( points );
361 store.start( p[0], m1 );
365 double s1 = 0.5 * s2;
367 for (
int i = 0; i < size - 3; i++ )
372 store.addCubic( p[i], m1, p[i+1], m2 );
383 store.addCubic( p[size - 3], m1, p[size - 2], m2 );
384 store.addCubic( p[size - 2], m2, p[size - 1], slopeEnd );
389 template<
class SplineStore >
395 const int size = points.size();
403 const double m2 = spline->
slopeAtEnd( points, s0 );
405 store.init( points );
406 store.start( points[0], m1 );
407 store.addCubic( points[0], m1, points[1], m2 );
412 switch( spline->
type() )
417 store = qwtSplineL1<SplineStore, slopeCardinal>( spline, points );
423 store = qwtSplineL1<SplineStore, slopeParabolicBlending>( spline, points );
429 store = qwtSplineL1<SplineStore, slopePChip>( spline, points );
434 store = qwtSplineAkima<SplineStore>( spline, points );
487 return qwtSplineLocal<PathStore>(
this, points).path;
507 return qwtSplineLocal<ControlPointsStore>(
this, points ).controlPoints;
524 return qwtSplineLocal<SlopeStore>(
this, points ).
slopes;
static double qwtSlopeLine(const QPointF &p1, const QPointF &p2)
static SplineStore qwtSplineL1(const QwtSplineLocal *spline, const QVector< QPointF > &points)
void addCubic(const QPointF &p1, double m1, const QPointF &p2, double m2)
enum MQTTPropertyCodes value
virtual uint locality() const
virtual QVector< double > slopes(const QPolygonF &) const QWT_OVERRIDE
Find the first derivative at the control points.
QVector< QLineF > controlPoints
virtual QPainterPath painterPath(const QPolygonF &) const QWT_OVERRIDE
Interpolate a curve with Bezier curves.
static double qwtSlopeP3(const QPointF &p1, const QPointF &p2, const QPointF &p3)
static SplineStore qwtSplineAkima(const QwtSplineLocal *spline, const QVector< QPointF > &points)
static void qwtSplineBoundariesL1(const QwtSplineLocal *spline, const QVector< QPointF > &points, double &slopeBegin, double &slopeEnd)
virtual ~QwtSplineLocal()
Destructor.
Type
Spline interpolation type.
void addCubic(const QPointF &, double, const QPointF &, double m2)
static double qwtSlopeAkima(double s1, double s2, double s3, double s4)
const QwtSplineParametrization * parametrization() const
the condiation is at the end of the polynomial
static double qwtSlopePChip(double dx1, double dy1, double s1, double dx2, double dy2, double s2)
virtual QVector< QLineF > bezierControlLines(const QPolygonF &) const QWT_OVERRIDE
Interpolate a curve with Bezier curves.
void setBoundaryCondition(BoundaryPosition, int condition)
Define the condition for an endpoint of the spline.
void init(const QVector< QPointF > &points)
static double value(double dx1, double dy1, double s1, double dx2, double dy2, double s2)
virtual QPainterPath painterPath(const QPolygonF &) const QWT_OVERRIDE
Calculate an interpolated painter path.
static bool qwtIsStrictlyMonotonic(double dy1, double dy2)
the condiation is at the beginning of the polynomial
void init(const QVector< QPointF > &points)
static double qwtSlopeCardinal(double dx1, double dy1, double s1, double dx2, double dy2, double s2)
void setBoundaryValue(BoundaryPosition, double value)
Define the boundary value.
void addCubic(const QPointF &p1, double m1, const QPointF &p2, double m2)
int boundaryCondition(BoundaryPosition) const
void start(const QPointF &, double m0)
void start(const QPointF &p0, double)
static void qwtSplineAkimaBoundaries(const QwtSplineLocal *spline, const QVector< QPointF > &points, double &slopeBegin, double &slopeEnd)
void init(const QVector< QPointF > &)
static double value(double dx1, double dy1, double s1, double dx2, double dy2, double s2)
static double value(double dx1, double dy1, double s1, double dx2, double dy2, double s2)
virtual double slopeAtBeginning(const QPolygonF &, double slopeNext) const
static SplineStore qwtSplineLocal(const QwtSplineLocal *spline, const QVector< QPointF > &points)
virtual QVector< QwtSplinePolynomial > polynomials(const QPolygonF &) const
Calculate the interpolating polynomials for a non parametric spline.
void start(const QPointF &, double)
virtual double slopeAtEnd(const QPolygonF &, double slopeBefore) const
BoundaryType boundaryType() const
double boundaryValue(BoundaryPosition) const
virtual uint locality() const QWT_OVERRIDE
virtual QVector< QwtSplinePolynomial > polynomials(const QPolygonF &) const QWT_OVERRIDE
Calculate the interpolating polynomials for a non parametric spline.
static double qwtSlopeParabolicBlending(double dx1, double dy1, double s1, double dx2, double dy2, double s2)
A spline with C1 continuity.
virtual QVector< QLineF > bezierControlLines(const QPolygonF &) const QWT_OVERRIDE
Interpolate a curve with Bezier curves.
QwtSplineLocal(Type type)
Constructor.