13 #define SLOPES_INCREMENTAL 0 40 const double t =
d_sum + y;
42 d_carry = ( t -
d_sum ) - y;
46 static inline double sum3(
double d1,
double d2,
double d3 )
55 static inline double sum4(
double d1,
double d2,
double d3,
double d4 )
76 d_curvatures.resize( size );
77 d_cv = d_curvatures.data();
81 const QPointF &,
const QPointF &,
double b1,
double )
87 const QPointF &,
const QPointF &,
double,
double b2 )
89 d_cv[index] = 2.0 * b2;
93 const QPointF &,
const QPointF &,
double,
double b2 )
95 d_cv[d_curvatures.size() - 1] = 2.0 * b2;
99 const QPointF &,
const QPointF &,
double b1,
double )
101 d_cv[index] = 2.0 * b1;
106 d_cv[0] = d_cv[d_curvatures.size() - 1];
121 d_slopes.resize( size );
122 d_m = d_slopes.data();
126 const QPointF &p1,
const QPointF &p2,
double b1,
double b2 )
128 const double s = ( p2.y() - p1.y() ) / h;
129 d_m[0] = s - h * ( 2.0 * b1 + b2 ) / 3.0;
136 const QPointF &p1,
const QPointF &p2,
double b1,
double b2 )
138 #if SLOPES_INCREMENTAL 142 d_sum.add( ( b1 + b2 ) * h );
143 d_m[index] =
d_sum.value();
145 d_m[index] = d_m[index-1] + ( b1 + b2 ) * h;
148 const double s = ( p2.y() - p1.y() ) / h;
149 d_m[index] = s + h * ( b1 + 2.0 * b2 ) / 3.0;
154 const QPointF &p1,
const QPointF &p2,
double b1,
double b2 )
156 const double s = ( p2.y() - p1.y() ) / h;
157 d_m[d_slopes.size() - 1] = s + h * ( b1 + 2.0 * b2 ) / 3.0;
159 d_sum.add( d_m[d_slopes.size() - 1] );
164 const QPointF &p1,
const QPointF &p2,
double b1,
double b2 )
166 #if SLOPES_INCREMENTAL 170 d_sum.add( -( b1 + b2 ) * h );
171 d_m[index] =
d_sum.value();
173 d_m[index] = d_m[index+1] - ( b1 + b2 ) * h;
177 const double s = ( p2.y() - p1.y() ) / h;
178 d_m[index] = s - h * ( 2.0 * b1 + b2 ) / 3.0;
184 d_m[0] = d_m[d_slopes.size() - 1];
187 QVector<double>
slopes()
const {
return d_slopes; }
192 #if SLOPES_INCREMENTAL 214 inline void setup(
double p0 ,
double q0,
double r0 )
233 return ( r - q * x2 ) / p;
238 return ( r - p * x1 ) / q;
245 return ( r - k * eq.
r ) / ( p - k * eq.
p );
251 const double k = p / eq.
p;
252 return ( r - k * eq.
r ) / ( q - k * eq.
q );
266 inline Equation3(
const QPointF &p1,
const QPointF &p2,
const QPointF &p3 )
268 const double h1 = p2.x() - p1.x();
269 const double s1 = ( p2.y() - p1.y() ) / h1;
271 const double h2 = p3.x() - p2.x();
272 const double s2 = ( p3.y() - p2.y() ) / h2;
280 inline Equation3(
double cp,
double cq,
double du,
double dr ):
290 return ( p == c.
p ) && ( q == c.
q ) &&
291 ( u == c.
u ) && ( r == c.
r );
294 inline void setup(
double cp,
double cq,
double du,
double dr )
316 const double k = p / eq.
p;
317 return Equation2( q - k * eq.
q, u - k * eq.
u, r - k * eq.
r );
324 const double k = q / eq.
q;
325 return Equation2( p - k * eq.
p, u - k * eq.
u, r - k * eq.
r );
332 const double k = u / eq.
u;
333 return Equation2( p - k * eq.
p, q - k * eq.
q, r - k * eq.
r );
339 const double k = p / eq.
p;
347 const double k = u / eq.
q;
354 return ( r - q * x2 - u * x3 ) / p;
359 return ( r - u * x3 - p * x1 ) / q;
364 return ( r - p * x1 - q * x2 ) / u;
374 debug.nospace() <<
"EQ2(" << eq.
p <<
", " << eq.
q <<
", " << eq.
r <<
")";
375 return debug.space();
380 debug.nospace() <<
"EQ3(" << eq.
p <<
", " 381 << eq.
q <<
", " << eq.
u <<
", " << eq.
r <<
")";
382 return debug.space();
393 d_conditionsEQ[0].setup( p, q, u, r );
398 d_conditionsEQ[1].setup( p, q, u, r );
408 const int n = p.size();
412 if ( d_conditionsEQ[0].p == 0.0 ||
413 ( d_conditionsEQ[0].q == 0.0 && d_conditionsEQ[0].u != 0.0 ) )
418 if ( d_conditionsEQ[1].u == 0.0 ||
419 ( d_conditionsEQ[1].q == 0.0 && d_conditionsEQ[1].p != 0.0 ) )
424 const double h0 = p[1].x() - p[0].x();
425 const double h1 = p[2].x() - p[1].x();
426 const double hn = p[n-1].x() - p[n-2].x();
438 const Equation3 eqSpline0( p[0], p[1], p[2] );
439 const Equation2 eq0 = d_conditionsEQ[0].substituted1( eqSpline0 );
457 const Equation2 eq = d_conditionsEQ[1].substituted1( eqSpline0 );
462 const double b0 = eqSpline0.
resolved1( b1, b2 );
464 d_store.storeFirst( h0, p[0], p[1], b0, b1 );
465 d_store.storeNext( 1, h0, p[0], p[1], b0, b1 );
466 d_store.storeNext( 2, h1, p[1], p[2], b1, b2 );
471 const Equation3 eqSplineN( p[n-3], p[n-2], p[n-1] );
472 const Equation2 eqN = d_conditionsEQ[1].substituted3( eqSplineN );
477 const Equation3 eqSplineR( p[n-4], p[n-3], p[n-2] );
479 eq = substituteSpline( p, eq );
482 const Equation3 eqSpline0( p[0], p[1], p[2] );
485 if ( d_conditionsEQ[0].u == 0.0 )
489 const Equation3 &eq0 = d_conditionsEQ[0];
495 const Equation2 eqX = d_conditionsEQ[0].substituted3( eq );
502 d_store.storeFirst( h0, p[0], p[1], b0, b1 );
503 d_store.storeNext( 1, h0, p[0], p[1], b0, b1 );
505 const double bn2 = resolveSpline( p, b1 );
508 const double bn0 = d_conditionsEQ[1].resolved3( bn2, bn1 );
510 const double hx = p[n-2].x() - p[n-3].x();
511 d_store.storeNext( n - 2, hx, p[n-3], p[n-2], bn2, bn1 );
512 d_store.storeNext( n - 1, hn, p[n-2], p[n-1], bn1, bn0 );
518 const int n = points.size();
520 d_eq.resize( n - 2 );
525 double slope2 = ( points[n-3].y() - points[n-4].y() ) / eq.
p;
527 for (
int i = n - 4;
i > 1;
i-- )
532 eq1.
p = points[
i].x() - points[
i-1].x();
533 const double slope1 = ( points[
i].y() - points[
i-1].y() ) / eq1.
p;
535 const double v = eq2.
p / eq2.
q;
537 eq1.
q = 2.0 * ( eq1.
p + eq2.
p ) -
v * eq2.
p;
538 eq1.
r = 3.0 * ( slope2 - slope1 ) -
v * eq2.
r;
548 const int n = points.size();
549 const QPointF *p = points.constData();
551 for (
int i = 2;
i < n - 2;
i++ )
554 const double b2 = d_eq[
i].resolved2( b1 );
555 d_store.storeNext(
i, d_eq[
i].p, p[
i-1], p[
i], b1, b2 );
580 const int n = p.size();
582 if ( p[n-1].
y() != p[0].
y() )
587 const double h0 = p[1].x() - p[0].x();
588 const double s0 = ( p[1].y() - p[0].y() ) / h0;
592 const double h1 = p[2].x() - p[1].x();
593 const double s1 = ( p[2].y() - p[1].y() ) / h1;
595 const double b = 3.0 * ( s0 - s1 ) / ( h0 + h1 );
598 d_store.storeLast( h1, p[1], p[2], -b, b );
599 d_store.storePrevious( 1, h1, p[1], p[2], -b, b );
605 const double hn = p[n-1].x() - p[n-2].x();
608 substitute( p, eqn, eqX );
614 d_store.storeLast( hn, p[n-2], p[n-1], bn, b0 );
615 d_store.storePrevious( n - 2, hn, p[n-2], p[n-1], bn, b0 );
617 resolveSpline( p, b0, bn );
626 const int n = points.size();
628 const double hn = points[n-1].x() - points[n-2].x();
630 const Equation3 eqSpline0( points[0], points[1], points[2] );
632 QPointF( points[0].
x() - hn, points[n-2].
y() ), points[0], points[1] );
634 d_eq.resize( n - 1 );
641 double slope1 = ( points[2].y() - points[1].y() ) / d_eq[1].u;
655 for (
int i = 2;
i < n - 1;
i++ )
660 dq += eq1.
p * eq1.
p / eq1.
q;
661 dr += eq1.
p * eq1.
r / eq1.
q;
663 eq2.
u = points[
i+1].x() - points[
i].x();
664 const double slope2 = ( points[
i+1].y() - points[
i].y() ) / eq2.
u;
666 const double k = eq1.
u / eq1.
q;
669 eq2.
q = 2.0 * ( eq1.
u + eq2.
u ) - eq1.
u * k;
670 eq2.
r = 3.0 * ( slope2 - slope1 ) - eq1.
r * k;
677 eqn.
setup( d_eq[n-2].q, d_eq[n-2].p + eqSplineN.
p , d_eq[n-2].r );
680 eqX.
setup( d_eq[n-2].p + eqSplineN.
p, eqSplineN.
q - dq, eqSplineN.
r - dr );
685 const int n = points.size();
687 for (
int i = n - 3;
i >= 1;
i-- )
692 d_store.storePrevious(
i, eq.
u, points[
i], points[i+1], b, bi );
699 double b0,
double bi, QVector<double> &m )
701 const int n = points.size();
703 bi = d_eq[0].resolved3( b0, bi );
705 for (
int i = 1;
i < n - 2;
i++ )
710 m[
i+1] = m[
i] + ( b + bi ) * d_eq[
i].u;
717 double b0,
double b1, QVector<double> &m )
719 const int n = points.size();
721 double h0 = ( points[1].x() - points[0].x() );
722 double s0 = ( points[1].y() - points[0].y() ) / h0;
724 m[1] = m[0] + ( b0 + b1 ) * h0;
726 for (
int i = 1;
i < n - 1;
i++ )
728 const double h1 = ( points[
i+1].x() - points[
i].x() );
729 const double s1 = ( points[
i+1].y() - points[
i].y() ) / h1;
731 const double r = 3.0 * ( s1 - s0 );
733 const double b2 = ( r - h0 * b0 - 2.0 * ( h0 + h1 ) * b1 ) / h1;
734 m[
i+1] = m[
i] + ( b1 + b2 ) * h1;
744 double b2,
double b1, QVector<double> &m )
746 const int n = points.size();
748 double h2 = ( points[n-1].x() - points[n-2].x() );
749 double s2 = ( points[n-1].y() - points[n-2].y() ) / h2;
751 for (
int i = n - 2;
i > 1;
i-- )
753 const double h1 = ( points[
i].x() - points[
i-1].x() );
754 const double s1 = ( points[
i].y() - points[
i-1].y() ) / h1;
756 const double r = 3.0 * ( s2 - s1 );
757 const double k = 2.0 * ( h1 + h2 );
759 const double b0 = ( r - h2 * b2 - k * b1 ) / h1;
761 m[
i-1] = m[
i] - ( b0 + b1 ) * h1;
777 int conditionBegin,
double valueBegin,
int conditionEnd,
double valueEnd,
780 const int n = points.size();
782 const double h0 = points[1].x() - points[0].x();
783 const double s0 = ( points[1].y() - points[0].y() ) / h0;
785 const double hn = ( points[n-1].x() - points[n-2].x() );
786 const double sn = ( points[n-1].y() - points[n-2].y() ) / hn;
788 switch( conditionBegin )
803 eq[0].
setup( 2 * h0 / 3.0, h0 / 3.0, 0.0, s0 - valueBegin );
816 eq[0].
setup( 1.0, 0.0, 0.0, 0.5 * valueBegin );
831 eq[0].
setup( 1.0, -1.0, 0.0, -0.5 * valueBegin * h0 );
837 const double r0 = qBound( 0.0, valueBegin, 1.0 );
841 eq[0].
setup( 2 * h0 / 3.0, h0 / 3.0, 0.0, 0.0 );
845 eq[0].
setup( 1.0 + 2.0 / r0, 2.0 + 1.0 / r0, 0.0, 0.0 );
870 v0 = h0 / ( points[2].x() - points[1].x() );
873 eq[0].
setup( 1.0, -( 1.0 + v0 ), v0, 0.0 );
880 eq[0].
setup( 1.0, 0.0, 0.0, 0.0 );
885 switch( conditionEnd )
890 eq[1].
setup( 0.0, 1.0 / 3.0 * hn, 2.0 / 3.0 * hn, valueEnd - sn );
896 eq[1].
setup( 0.0, 0.0, 1.0, 0.5 * valueEnd );
902 eq[1].
setup( 0.0, 1.0, -1.0, -0.5 * valueEnd * hn );
907 const double rn = qBound( 0.0, valueEnd, 1.0 );
911 eq[1].
setup( 0.0, 1.0 / 3.0 * hn, 2.0 / 3.0 * hn, 0.0 );
915 eq[1].
setup( 0.0, 2.0 + 1.0 / rn, 1.0 + 2.0 / rn, 0.0 );
937 vn = hn / ( points[n-2].x() - points[n-3].x() );
940 eq[1].
setup( vn, -( 1.0 + vn ), 1.0, 0.0 );
947 eq[1].
setup( 0.0, 0.0, 1.0, 0.0 );
1011 if ( points.size() <= 2 )
1012 return QVector<double>();
1023 if ( points.size() == 3 )
1029 const double h0 = points[1].x() - points[0].x();
1030 const double h1 = points[2].x() - points[1].x();
1032 const double s0 = ( points[1].y() - points[0].y() ) / h0;
1033 const double s1 = ( points[2].y() - points[1].y() ) / h1;
1040 const double b = ( s1 - s0 ) / ( h0 + h1 );
1042 QVector<double> m( 3 );
1049 return QVector<double>();
1083 if ( points.size() <= 2 )
1084 return QVector<double>();
1095 if ( points.size() == 3 )
1100 return QVector<double>();
virtual ~QwtSplineCubic()
Destructor.
Equation2 substituted2(const Equation3 &eq) const
Equation2 normalized() const
void storeLast(double h, const QPointF &p1, const QPointF &p2, double b1, double b2)
static double sum3(double d1, double d2, double d3)
static double sum4(double d1, double d2, double d3, double d4)
Equation2 substituteSpline(const QPolygonF &points, const Equation2 &eq)
Equation2 substituted3(const Equation2 &eq) const
virtual QPainterPath painterPath(const QPolygonF &) const
Calculate an interpolated painter path.
static void qwtSetupEndEquations(int conditionBegin, double valueBegin, int conditionEnd, double valueEnd, const QPolygonF &points, QwtSplineCubicP::Equation3 eq[2])
void storeLast(double, const QPointF &, const QPointF &, double, double b2)
Equation3(double cp, double cq, double du, double dr)
void resolveSpline2(const QPolygonF &points, double b0, double bi, QVector< double > &m)
void storeFirst(double h, const QPointF &p1, const QPointF &p2, double b1, double b2)
virtual QVector< QwtSplinePolynomial > polynomials(const QPolygonF &) const
Calculate the interpolating polynomials for a non parametric spline.
void setup(double p0, double q0, double r0)
void setup(double cp, double cq, double du, double dr)
void resolve(const QPolygonF &p)
void storeNext(int index, double, const QPointF &, const QPointF &, double, double b2)
virtual QPainterPath painterPath(const QPolygonF &) const
Interpolate a curve with Bezier curves.
TFSIMD_FORCE_INLINE const tfScalar & y() const
QVector< double > slopes() const
the condiation is at the end of the polynomial
void storeNext(int index, double h, const QPointF &p1, const QPointF &p2, double b1, double b2)
KahanSum(double value=0.0)
QVector< double > curvatures() const
TFSIMD_FORCE_INLINE Vector3 normalized() const
Equation2 substituted3(const Equation3 &eq) const
the condiation is at the beginning of the polynomial
void resolve(const QPolygonF &p)
Equation2 substituted1(const Equation2 &eq) const
double resolved1(double x2) const
QVector< double > d_curvatures
Equation2 substituted1(const Equation3 &eq) const
void storePrevious(int index, double h, const QPointF &p1, const QPointF &p2, double b1, double b2)
QDebug operator<<(QDebug debug, const QwtSplineCubicP::Equation2 &eq)
bool operator==(const Equation3 &c) const
TFSIMD_FORCE_INLINE const tfScalar & x() const
void setStartCondition(double p, double q, double u, double r)
void setEndCondition(double p, double q, double u, double r)
virtual uint locality() const
void resolveSpline3(const QPolygonF &points, double b0, double b1, QVector< double > &m)
virtual QVector< QLineF > bezierControlLines(const QPolygonF &points) const
Interpolate a curve with Bezier curves.
Equation2(double p0, double q0, double r0)
QVector< double > d_slopes
virtual QVector< double > curvatures(const QPolygonF &) const
Find the second derivative at the control points.
double resolved1(double x2, double x3) const
void storeFirst(double, const QPointF &, const QPointF &, double b1, double)
double resolveSpline(const QPolygonF &points, double b1)
double resolved2(double x1, double x3) const
double resolved3(double x1, double x2) const
virtual QVector< double > slopes(const QPolygonF &) const
Find the first derivative at the control points.
Equation3 normalized() const
double resolved2(double x1) const
virtual QVector< QLineF > bezierControlLines(const QPolygonF &) const
Interpolate a curve with Bezier curves.
QVector< Equation2 > d_eq
virtual QVector< QwtSplinePolynomial > polynomials(const QPolygonF &) const
Calculate the interpolating polynomials for a non parametric spline.
double resolved1(const Equation2 &eq) const
QwtSplineCubic()
Constructor The default setting is a non closing natural spline with no parametrization.
Equation3(const QPointF &p1, const QPointF &p2, const QPointF &p3)
QVector< Equation3 > d_eq
void resolveSpline4(const QPolygonF &points, double b2, double b1, QVector< double > &m)
void resolveSpline(const QPolygonF &points, double b0, double bi)
void substitute(const QPolygonF &points, Equation2 &eqn, Equation2 &eqX)
double resolved2(const Equation2 &eq) const
void storePrevious(int index, double, const QPointF &, const QPointF &, double b1, double)