16 if ( dy1 == 0.0 || dy2 == 0.0 )
19 return ( dy1 > 0.0 ) == ( dy2 > 0.0 );
22 static inline double qwtSlopeLine(
const QPointF &p1,
const QPointF &p2 )
25 const double dx = p2.x() - p1.x();
26 return dx ? ( p2.y() - p1.y() ) / dx : 0.0;
30 double dx1,
double dy1,
double s1,
double dx2,
double dy2,
double s2 )
35 return ( dy1 + dy2 ) / ( dx1 + dx2 );
39 double dx1,
double dy1,
double s1,
double dx2,
double dy2,
double s2 )
44 return ( dx2 * s1 + dx1 * s2 ) / ( dx1 + dx2 );
48 double dx1,
double dy1,
double s1,
double dx2,
double dy2,
double s2 )
54 const double w1 = ( 3 * dx1 + 3 * dx2 ) / ( 2 * dx1 + 4 * dx2 );
55 const double w2 = ( 3 * dx1 + 3 * dx2 ) / ( 4 * dx1 + 2 * dx2 );
61 return 2.0 / ( 1.0 / s1 + 1.0 / s2 );
65 const double s12 = ( dy1 + dy2 ) / ( dx1 + dx2 );
66 return 3.0 * ( s1 * s2 ) / ( s1 + s2 + s12 );
77 inline void init(
const QVector<QPointF> & )
81 inline void start(
const QPointF &p0,
double )
86 inline void addCubic(
const QPointF &p1,
double m1,
87 const QPointF &p2,
double m2 )
89 const double dx3 = ( p2.x() - p1.x() ) / 3.0;
91 path.cubicTo( p1.x() + dx3, p1.y() + m1 * dx3,
92 p2.x() - dx3, p2.y() - m2 * dx3,
102 inline void init(
const QVector<QPointF> &points )
104 if ( points.size() > 0 )
105 controlPoints.resize( points.size() - 1 );
106 d_cp = controlPoints.data();
109 inline void start(
const QPointF &,
double )
113 inline void addCubic(
const QPointF &p1,
double m1,
114 const QPointF &p2,
double m2 )
116 const double dx3 = ( p2.x() - p1.x() ) / 3.0;
119 l.setLine( p1.x() + dx3, p1.y() + m1 * dx3,
120 p2.x() - dx3, p2.y() - m2 * dx3 );
132 void init(
const QVector<QPointF> &points )
134 slopes.resize( points.size() );
138 inline void start(
const QPointF &,
double m0 )
144 const QPointF &,
double m2 )
157 static inline double value(
double dx1,
double dy1,
double s1,
158 double dx2,
double dy2,
double s2 )
166 static inline double value(
double dx1,
double dy1,
double s1,
167 double dx2,
double dy2,
double s2 )
175 static inline double value(
double dx1,
double dy1,
double s1,
176 double dx2,
double dy2,
double s2 )
183 template<
class Slope >
185 const QPointF &p1,
const QPointF &p2,
const QPointF &p3 )
187 const double dx1 = p2.x() - p1.x();
188 const double dy1 = p2.y() - p1.y();
189 const double dx2 = p3.x() - p2.x();
190 const double dy2 = p3.y() - p2.y();
192 return Slope::value( dx1, dy1, dy1 / dx1, dx2, dy2, dy2 / dx2 );
195 static inline double qwtSlopeAkima(
double s1,
double s2,
double s3,
double s4 )
197 if ( ( s1 == s2 ) && ( s3 == s4 ) )
199 return 0.5 * ( s2 + s3 );
202 const double ds12 = qAbs( s2 - s1 );
203 const double ds34 = qAbs( s4 - s3 );
205 return ( s2 * ds34 + s3 * ds12 ) / ( ds12 + ds34 );
209 const QPointF &p3,
const QPointF &p4,
const QPointF &p5 )
219 template<
class Slope >
222 double &slopeBegin,
double &slopeEnd )
224 const int n = points.size();
225 const QPointF *p = points.constData();
230 const QPointF pn = p[0] - ( p[n-1] - p[n-2] );
231 slopeBegin = slopeEnd = qwtSlopeP3<Slope>( pn, p[0], p[1] );
235 const double m2 = qwtSlopeP3<Slope>( p[0], p[1], p[2] );
238 const double mn2 = qwtSlopeP3<Slope>( p[n-3], p[n-2], p[n-1] );
243 template<
class SplineStore,
class Slope >
247 const int size = points.size();
248 const QPointF *p = points.constData();
250 double slopeBegin, slopeEnd;
251 qwtSplineBoundariesL1<Slope>( spline, points, slopeBegin, slopeEnd );
253 double m1 = slopeBegin;
256 store.init( points );
257 store.start( p[0], m1 );
259 double dx1 = p[1].x() - p[0].x();
260 double dy1 = p[1].y() - p[0].y();
261 double s1 = dy1 / dx1;
263 for (
int i = 1;
i < size - 1;
i++ )
265 const double dx2 = p[
i+1].x() - p[
i].x();
266 const double dy2 = p[
i+1].y() - p[
i].y() ;
270 const double s2 = dy2 / dx2;
272 const double m2 = Slope::value( dx1, dy1, s1, dx2, dy2, s2 );
274 store.addCubic( p[
i-1], m1, p[
i], m2 );
282 store.addCubic( p[size-2], m1, p[size-1], slopeEnd );
289 double &slopeBegin,
double &slopeEnd )
291 const int n = points.size();
292 const QPointF *p = points.constData();
297 const QPointF p2 = p[0] - ( p[n-1] - p[n-2] );
298 const QPointF p1 = p2 - ( p[n-2] - p[n-3] );
300 slopeBegin = slopeEnd =
qwtSlopeAkima( p1, p2, p[0], p[1], p[2] );
318 const double m =
qwtSlopeAkima( 0.5 * s1, s1, s2, 0.5 * s2 );
331 const double m2 =
qwtSlopeAkima( 0.5 * s[0], s[0], s[1], s[2] );
339 const double mn2 =
qwtSlopeAkima( s[0], s[1], s[2], 0.5 * s[2] );
345 template<
class SplineStore >
349 const int size = points.size();
350 const QPointF *p = points.constData();
352 double slopeBegin, slopeEnd;
355 double m1 = slopeBegin;
358 store.init( points );
359 store.start( p[0], m1 );
363 double s1 = 0.5 * s2;
365 for (
int i = 0;
i < size - 3;
i++ )
370 store.addCubic( p[
i], m1, p[i+1], m2 );
381 store.addCubic( p[size - 3], m1, p[size - 2], m2 );
382 store.addCubic( p[size - 2], m2, p[size - 1], slopeEnd );
387 template<
class SplineStore >
393 const int size = points.size();
401 const double m2 = spline->
slopeAtEnd( points, s0 );
403 store.init( points );
404 store.start( points[0], m1 );
405 store.addCubic( points[0], m1, points[1], m2 );
410 switch( spline->
type() )
415 store = qwtSplineL1<SplineStore, slopeCardinal>( spline, points );
421 store = qwtSplineL1<SplineStore, slopeParabolicBlending>( spline, points );
427 store = qwtSplineL1<SplineStore, slopePChip>( spline, points );
432 store = qwtSplineAkima<SplineStore>( spline, points );
485 return qwtSplineLocal<PathStore>(
this, points).
path;
505 return qwtSplineLocal<ControlPointsStore>(
this, points ).controlPoints;
522 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)
virtual uint locality() const
virtual uint locality() const
virtual QPainterPath painterPath(const QPolygonF &) const
Calculate an interpolated painter path.
QVector< QLineF > controlPoints
static double qwtSlopeP3(const QPointF &p1, const QPointF &p2, const QPointF &p3)
static SplineStore qwtSplineAkima(const QwtSplineLocal *spline, const QVector< QPointF > &points)
virtual QVector< QLineF > bezierControlLines(const QPolygonF &) const
Interpolate a curve with Bezier curves.
static void qwtSplineBoundariesL1(const QwtSplineLocal *spline, const QVector< QPointF > &points, double &slopeBegin, double &slopeEnd)
virtual ~QwtSplineLocal()
Destructor.
Type
Spline interpolation type.
virtual QPainterPath painterPath(const QPolygonF &) const
Interpolate a curve with Bezier curves.
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)
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)
static bool qwtIsStrictlyMonotonic(double dy1, double dy2)
the condiation is at the beginning of the polynomial
GraphId path[kMaxDeadlockPathLen]
void init(const QVector< QPointF > &points)
static double qwtSlopeCardinal(double dx1, double dy1, double s1, double dx2, double dy2, double s2)
virtual QVector< double > slopes(const QPolygonF &) const
Find the first derivative at the control points.
virtual QVector< QwtSplinePolynomial > polynomials(const QPolygonF &) const
Calculate the interpolating polynomials for a non parametric spline.
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 QVector< QLineF > bezierControlLines(const QPolygonF &) const
Interpolate a curve with Bezier curves.
virtual double slopeAtEnd(const QPolygonF &, double slopeBefore) const
BoundaryType boundaryType() const
double boundaryValue(BoundaryPosition) const
static double qwtSlopeParabolicBlending(double dx1, double dy1, double s1, double dx2, double dy2, double s2)
A spline with C1 continuity.
QwtSplineLocal(Type type)
Constructor.