14 #include <qpainterpath.h>
16 #define SLOPES_INCREMENTAL 0
43 const double t =
m_sum +
y;
49 static inline double sum3(
double d1,
double d2,
double d3 )
58 static inline double sum4(
double d1,
double d2,
double d3,
double d4 )
84 const QPointF&,
const QPointF&,
double b1,
double )
90 const QPointF&,
const QPointF&,
double,
double b2 )
92 m_cv[index] = 2.0 * b2;
96 const QPointF&,
const QPointF&,
double,
double b2 )
102 const QPointF&,
const QPointF&,
double b1,
double )
104 m_cv[index] = 2.0 * b1;
129 const QPointF& p1,
const QPointF& p2,
double b1,
double b2 )
131 const double s = ( p2.y() - p1.y() ) / h;
132 m_m[0] =
s - h * ( 2.0 * b1 + b2 ) / 3.0;
139 const QPointF& p1,
const QPointF& p2,
double b1,
double b2 )
141 #if SLOPES_INCREMENTAL
145 m_sum.add( ( b1 + b2 ) * h );
146 m_m[index] = m_sum.value();
148 m_m[index] =
m_m[index - 1] + ( b1 + b2 ) * h;
151 const double s = ( p2.y() - p1.y() ) / h;
152 m_m[index] =
s + h * ( b1 + 2.0 * b2 ) / 3.0;
157 const QPointF& p1,
const QPointF& p2,
double b1,
double b2 )
159 const double s = ( p2.y() - p1.y() ) / h;
160 m_m[
m_slopes.size() - 1] =
s + h * ( b1 + 2.0 * b2 ) / 3.0;
167 const QPointF& p1,
const QPointF& p2,
double b1,
double b2 )
169 #if SLOPES_INCREMENTAL
173 m_sum.add( -( b1 + b2 ) * h );
174 m_m[index] = m_sum.value();
176 m_m[index] =
m_m[index + 1] - ( b1 + b2 ) * h;
180 const double s = ( p2.y() - p1.y() ) / h;
181 m_m[index] =
s - h * ( 2.0 * b1 + b2 ) / 3.0;
195 #if SLOPES_INCREMENTAL
217 inline void setup(
double p0,
double q0,
double r0 )
236 return (
r -
q * x2 ) /
p;
241 return (
r -
p * x1 ) /
q;
248 return (
r - k * eq.
r ) / (
p - k * eq.
p );
254 const double k =
p / eq.
p;
255 return (
r - k * eq.
r ) / (
q - k * eq.
q );
269 inline Equation3(
const QPointF& p1,
const QPointF& p2,
const QPointF& p3 )
271 const double h1 = p2.x() - p1.x();
272 const double s1 = ( p2.y() - p1.y() ) / h1;
274 const double h2 = p3.x() - p2.x();
275 const double s2 = ( p3.y() - p2.y() ) / h2;
283 inline Equation3(
double cp,
double cq,
double du,
double dr ):
293 return (
p == c.
p ) && (
q == c.
q ) &&
294 (
u == c.
u ) && (
r == c.
r );
297 inline void setup(
double cp,
double cq,
double du,
double dr )
319 const double k =
p / eq.
p;
327 const double k =
q / eq.
q;
335 const double k =
u / eq.
u;
342 const double k =
p / eq.
p;
350 const double k =
u / eq.
q;
357 return (
r -
q * x2 -
u * x3 ) /
p;
362 return (
r -
u * x3 -
p * x1 ) /
q;
367 return (
r -
p * x1 -
q * x2 ) /
u;
378 debug.nospace() <<
"EQ2(" << eq.
p <<
", " << eq.
q <<
", " << eq.
r <<
")";
379 return debug.space();
384 debug.nospace() <<
"EQ3(" << eq.
p <<
", "
385 << eq.
q <<
", " << eq.
u <<
", " << eq.
r <<
")";
386 return debug.space();
413 const int n = p.size();
429 const double h0 = p[1].x() - p[0].x();
430 const double h1 = p[2].x() - p[1].x();
431 const double hn = p[n - 1].x() - p[n - 2].x();
443 const Equation3 eqSpline0( p[0], p[1], p[2] );
467 const double b0 = eqSpline0.
resolved1( b1, b2 );
469 m_store.storeFirst( h0, p[0], p[1], b0, b1 );
470 m_store.storeNext( 1, h0, p[0], p[1], b0, b1 );
471 m_store.storeNext( 2, h1, p[1], p[2], b1, b2 );
476 const Equation3 eqSplineN( p[n - 3], p[n - 2], p[n - 1] );
482 const Equation3 eqSplineR( p[n - 4], p[n - 3], p[n - 2] );
487 const Equation3 eqSpline0( p[0], p[1], p[2] );
507 m_store.storeFirst( h0, p[0], p[1], b0, b1 );
508 m_store.storeNext( 1, h0, p[0], p[1], b0, b1 );
515 const double hx = p[n - 2].x() - p[n - 3].x();
516 m_store.storeNext( n - 2, hx, p[n - 3], p[n - 2], bn2, bn1 );
517 m_store.storeNext( n - 1, hn, p[n - 2], p[n - 1], bn1, bn0 );
523 const int n = points.size();
525 m_eq.resize( n - 2 );
530 double slope2 = ( points[n - 3].y() - points[n - 4].y() ) / eq.
p;
532 for (
int i = n - 4; i > 1; i-- )
537 eq1.
p = points[i].x() - points[i - 1].x();
538 const double slope1 = ( points[i].y() - points[i - 1].y() ) / eq1.
p;
540 const double v = eq2.
p / eq2.
q;
542 eq1.
q = 2.0 * ( eq1.
p + eq2.
p ) - v * eq2.
p;
543 eq1.
r = 3.0 * ( slope2 - slope1 ) - v * eq2.
r;
553 const int n = points.size();
554 const QPointF* p = points.constData();
556 for (
int i = 2; i < n - 2; i++ )
559 const double b2 =
m_eq[i].resolved2( b1 );
560 m_store.storeNext( i,
m_eq[i].p, p[i - 1], p[i], b1, b2 );
585 const int n = p.size();
587 if ( p[n - 1].
y() != p[0].
y() )
592 const double h0 = p[1].x() - p[0].x();
593 const double s0 = ( p[1].y() - p[0].y() ) / h0;
597 const double h1 = p[2].x() - p[1].x();
598 const double s1 = ( p[2].y() - p[1].y() ) / h1;
600 const double b = 3.0 * ( s0 - s1 ) / ( h0 + h1 );
603 m_store.storeLast( h1, p[1], p[2], -b, b );
604 m_store.storePrevious( 1, h1, p[1], p[2], -b, b );
610 const double hn = p[n - 1].x() - p[n - 2].x();
619 m_store.storeLast( hn, p[n - 2], p[n - 1], bn, b0 );
620 m_store.storePrevious( n - 2, hn, p[n - 2], p[n - 1], bn, b0 );
631 const int n = points.size();
633 const double hn = points[n - 1].x() - points[n - 2].x();
635 const Equation3 eqSpline0( points[0], points[1], points[2] );
637 QPointF( points[0].
x() - hn, points[n - 2].
y() ), points[0], points[1] );
639 m_eq.resize( n - 1 );
646 double slope1 = ( points[2].y() - points[1].y() ) /
m_eq[1].u;
660 for (
int i = 2; i < n - 1; i++ )
665 dq += eq1.
p * eq1.
p / eq1.
q;
666 dr += eq1.
p * eq1.
r / eq1.
q;
668 eq2.
u = points[i + 1].x() - points[i].x();
669 const double slope2 = ( points[i + 1].y() - points[i].y() ) / eq2.
u;
671 const double k = eq1.
u / eq1.
q;
674 eq2.
q = 2.0 * ( eq1.
u + eq2.
u ) - eq1.
u * k;
675 eq2.
r = 3.0 * ( slope2 - slope1 ) - eq1.
r * k;
685 eqX.
setup(
m_eq[n - 2].p + eqSplineN.
p, eqSplineN.
q - dq, eqSplineN.
r - dr );
690 const int n = points.size();
692 for (
int i = n - 3; i >= 1; i-- )
697 m_store.storePrevious( i, eq.
u, points[i], points[i + 1], b, bi );
706 const int n = points.size();
708 bi =
m_eq[0].resolved3( b0, bi );
710 for (
int i = 1; i < n - 2; i++ )
715 m[i + 1] = m[i] + ( b + bi ) *
m_eq[i].u;
724 const int n = points.size();
726 double h0 = ( points[1].x() - points[0].x() );
727 double s0 = ( points[1].y() - points[0].y() ) / h0;
729 m[1] = m[0] + ( b0 + b1 ) * h0;
731 for (
int i = 1; i < n - 1; i++ )
733 const double h1 = ( points[i + 1].x() - points[i].x() );
734 const double s1 = ( points[i + 1].y() - points[i].y() ) / h1;
736 const double r = 3.0 * ( s1 - s0 );
738 const double b2 = ( r - h0 * b0 - 2.0 * ( h0 + h1 ) * b1 ) / h1;
739 m[i + 1] = m[i] + ( b1 + b2 ) * h1;
751 const int n = points.size();
753 double h2 = ( points[n - 1].x() - points[n - 2].x() );
754 double s2 = ( points[n - 1].y() - points[n - 2].y() ) / h2;
756 for (
int i = n - 2; i > 1; i-- )
758 const double h1 = ( points[i].x() - points[i - 1].x() );
759 const double s1 = ( points[i].y() - points[i - 1].y() ) / h1;
761 const double r = 3.0 * ( s2 - s1 );
762 const double k = 2.0 * ( h1 + h2 );
764 const double b0 = ( r - h2 * b2 - k * b1 ) / h1;
766 m[i - 1] = m[i] - ( b0 + b1 ) * h1;
782 int conditionBegin,
double valueBegin,
int conditionEnd,
double valueEnd,
785 const int n = points.size();
787 const double h0 = points[1].x() - points[0].x();
788 const double s0 = ( points[1].y() - points[0].y() ) / h0;
790 const double hn = ( points[n - 1].x() - points[n - 2].x() );
791 const double sn = ( points[n - 1].y() - points[n - 2].y() ) / hn;
793 switch( conditionBegin )
808 eq[0].
setup( 2 * h0 / 3.0, h0 / 3.0, 0.0, s0 - valueBegin );
821 eq[0].
setup( 1.0, 0.0, 0.0, 0.5 * valueBegin );
836 eq[0].
setup( 1.0, -1.0, 0.0, -0.5 * valueBegin * h0 );
842 const double r0 = qBound( 0.0, valueBegin, 1.0 );
846 eq[0].
setup( 2 * h0 / 3.0, h0 / 3.0, 0.0, 0.0 );
850 eq[0].
setup( 1.0 + 2.0 / r0, 2.0 + 1.0 / r0, 0.0, 0.0 );
875 v0 = h0 / ( points[2].x() - points[1].x() );
878 eq[0].
setup( 1.0, -( 1.0 + v0 ), v0, 0.0 );
885 eq[0].
setup( 1.0, 0.0, 0.0, 0.0 );
890 switch( conditionEnd )
895 eq[1].
setup( 0.0, 1.0 / 3.0 * hn, 2.0 / 3.0 * hn, valueEnd - sn );
901 eq[1].
setup( 0.0, 0.0, 1.0, 0.5 * valueEnd );
907 eq[1].
setup( 0.0, 1.0, -1.0, -0.5 * valueEnd * hn );
912 const double rn = qBound( 0.0, valueEnd, 1.0 );
916 eq[1].
setup( 0.0, 1.0 / 3.0 * hn, 2.0 / 3.0 * hn, 0.0 );
920 eq[1].
setup( 0.0, 2.0 + 1.0 / rn, 1.0 + 2.0 / rn, 0.0 );
942 vn = hn / ( points[n - 2].x() - points[n - 3].x() );
945 eq[1].
setup( vn, -( 1.0 + vn ), 1.0, 0.0 );
952 eq[1].
setup( 0.0, 0.0, 1.0, 0.0 );
1010 if ( points.size() <= 2 )
1022 if ( points.size() == 3 )
1028 const double h0 = points[1].x() - points[0].x();
1029 const double h1 = points[2].x() - points[1].x();
1031 const double s0 = ( points[1].y() - points[0].y() ) / h0;
1032 const double s1 = ( points[2].y() - points[1].y() ) / h1;
1039 const double b = ( s1 - s0 ) / ( h0 + h1 );
1082 if ( points.size() <= 2 )
1094 if ( points.size() == 3 )