qwt_spline_basis.cpp
Go to the documentation of this file.
00001 #include "qwt_spline_basis.h"
00002 #include "qwt_spline_parametrization.h"
00003 
00004 #if 0
00005 static QPolygonF qwtBasisUniformKnots( const QPolygonF& points ) 
00006 {
00007     const int n = points.size();
00008 
00009     if ( n < 3 )
00010         return points;
00011 
00012     QVector<double> u( n - 2 );
00013     QVector<double> kx( n - 2 );
00014     QVector<double> ky( n - 2 );
00015 
00016     u[n-3] = 4.0;
00017     kx[n-3] = 6.0 * points[n-2].x() - points[n-1].x();
00018     ky[n-3] = 6.0 * points[n-2].y() - points[n-1].y();
00019 
00020     for ( int i = n - 4; i >= 0; i-- )
00021     {
00022         u[i] = 4.0 - 1.0 / u[i+1];
00023         kx[i] = 6.0 * points[i+1].x() - kx[i+1] / u[i+1];
00024         ky[i] = 6.0 * points[i+1].y() - ky[i+1] / u[i+1];
00025     }
00026 
00027     QVector<QPointF> knots( n );
00028 
00029     knots[0] = points[0];
00030 
00031     for ( int i = 1; i < n - 1; i++ )
00032     {
00033         knots[i].rx() = ( kx[i-1] - knots[i-1].x() ) / u[i-1];
00034         knots[i].ry() = ( ky[i-1] - knots[i-1].y() ) / u[i-1];
00035     }
00036 
00037     knots[n-1] = points[n-1];
00038 
00039     return knots;
00040 }
00041 #endif
00042 
00043 static inline void qwtSplineBezierControlPoints( const QwtSplineParametrization *param,
00044     const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4, 
00045     QPointF &cp1, QPointF &cp2 )
00046 {
00047     const double t1 = param->valueIncrement( p1, p2 );
00048     const double t2 = param->valueIncrement( p2, p3 );
00049     const double t3 = param->valueIncrement( p3, p4 );
00050 
00051     const double t123 = t1 + t2 + t3;
00052 
00053     cp1 = ( t2 + t3 ) / t123 * p2 + t1 / t123 * p3;
00054     cp2 = ( t3 * p2 + ( t1 + t2 ) * p3 ) / t123;
00055 }
00056 
00057 static QPainterPath qwtSplineBasisPathUniform( const QPolygonF& points, 
00058     QwtSpline::BoundaryType boundaryType ) 
00059 {
00060     const int n = points.size();
00061     const QPointF *pd = points.constData();
00062 
00063     QPainterPath path;
00064 
00065     QPointF cp1 = ( 2.0 * pd[0] + pd[1] ) / 3.0;;
00066 
00067     if ( boundaryType == QwtSpline::ConditionalBoundaries )
00068     {
00069         path.moveTo( pd[0] );
00070     }
00071     else
00072     {
00073         const QPointF cpN = ( pd[n-1] + 2.0 * pd[0] ) / 3.0;
00074         path.moveTo( 0.5 * ( cpN + cp1 ) );
00075     }
00076 
00077     for ( int i = 1; i < n - 1; i++ )
00078     {
00079         const QPointF cp2 = ( pd[i-1] + 2.0 * pd[i] ) / 3.0;
00080         const QPointF cp3 = ( 2.0 * pd[i] + pd[i+1] ) / 3.0;
00081 
00082         path.cubicTo( cp1, cp2, 0.5 * ( cp2 + cp3 ) );
00083 
00084         cp1 = cp3;
00085     }
00086 
00087     if ( boundaryType == QwtSpline::ConditionalBoundaries )
00088     {
00089         const QPointF cp2 = ( pd[n-2] + 2.0 * pd[n-1] ) / 3.0;
00090         path.cubicTo( cp1, cp2, pd[n-1] );
00091     }
00092     else
00093     {
00094         const QPointF cp2 = ( pd[n-2] + 2.0 * pd[n-1] ) / 3.0;
00095         const QPointF cp3 = ( 2.0 * pd[n-1] + pd[0] ) / 3.0;
00096 
00097         path.cubicTo( cp1, cp2, 0.5 * ( cp2 + cp3 ) );
00098 
00099         if ( boundaryType == QwtSpline::ClosedPolygon )
00100         {
00101             const QPointF cp4 = ( pd[n-1] + 2.0 * pd[0] ) / 3.0;
00102             const QPointF cp5 = ( 2.0 * pd[0] + pd[1] ) / 3.0;
00103 
00104             path.cubicTo( cp3, cp4, 0.5 * ( cp4 + cp5 ) );
00105         }
00106     }
00107 
00108     return path;
00109 }
00110 
00111 static QPainterPath qwtSplineBasisPath( const QPolygonF &points, 
00112     const QwtSplineParametrization *param,
00113     QwtSpline::BoundaryType boundaryType )
00114 {
00115     const int n = points.size();
00116     const QPointF *pd = points.constData();
00117 
00118     QPointF p0;
00119 
00120     double t1 = param->valueIncrement( pd[0], pd[1] );
00121     double t2 = param->valueIncrement( pd[1], pd[2] );
00122     
00123     double t0;
00124     if ( boundaryType == QwtSpline::ConditionalBoundaries )
00125         t0 = t1;
00126     else
00127         t0 = param->valueIncrement( pd[n-1], pd[0] );
00128 
00129     double t012 = t0 + t1 + t2;
00130     QPointF cp1 = ( ( t1 + t2 ) * pd[0] + t0 * pd[1] ) / t012;
00131 
00132     if ( boundaryType == QwtSpline::ConditionalBoundaries )
00133     {
00134         p0 = pd[0];
00135     }
00136     else
00137     {
00138         const double tN = param->valueIncrement( pd[n-2], pd[n-1] );
00139         const QPointF cpN = ( t1 * pd[n-1] + ( tN + t0 ) * pd[0] ) / ( tN + t0 + t1 );
00140 
00141         p0 = ( t1 * cpN + t0 * cp1 ) / ( t0 + t1 );
00142     }
00143 
00144     QPainterPath path;
00145     path.moveTo( p0 );
00146 
00147     for ( int i = 1; i < n - 2; i++ )
00148     {
00149         const double t3 = param->valueIncrement( pd[i+1], pd[i+2] );
00150         const double t123 = t1 + t2 + t3;
00151 
00152         const QPointF cp2 = ( t2 * pd[i-1] + ( t0 + t1 ) * pd[i] ) / t012;
00153         const QPointF cp3 = ( ( t2 + t3 ) * pd[i] + t1 * pd[i+1] ) / t123;
00154 
00155         const QPointF p2 = ( t2 * cp2 + t1 * cp3 ) / ( t1 + t2 );
00156 
00157         path.cubicTo( cp1, cp2, p2 );
00158 
00159         cp1 = cp3;
00160 
00161         t0 = t1;
00162         t1 = t2;
00163         t2 = t3;
00164         t012 = t123;
00165     }
00166 
00167     {   
00168         double t3;
00169         if ( boundaryType == QwtSpline::ConditionalBoundaries )
00170             t3 = t2;
00171         else
00172             t3 = param->valueIncrement( pd[n-1], pd[0] );
00173 
00174         const double t123 = t1 + t2 + t3;
00175         
00176         const QPointF cp2 = ( t2 * pd[n-3] + ( t0 + t1 ) * pd[n-2] ) / t012;
00177         const QPointF cp3 = ( ( t2 + t3 ) * pd[n-2] + t1 * pd[n-1] ) / t123;
00178         
00179         const QPointF p2 = ( t2 * cp2 + t1 * cp3 ) / ( t1 + t2 );
00180         
00181         path.cubicTo( cp1, cp2, p2 );
00182         
00183         cp1 = cp3;
00184         
00185         t0 = t1;
00186         t1 = t2;
00187         t2 = t3;
00188         t012 = t123;
00189     }
00190 
00191     const QPointF cp2 = ( t2 * pd[n-2] + ( t0 + t1 ) * pd[n-1] ) / t012;
00192 
00193     if ( boundaryType == QwtSpline::ConditionalBoundaries )
00194     {
00195         path.cubicTo( cp1, cp2, pd[n-1] );
00196     }
00197     else
00198     {   
00199         const double t3 = param->valueIncrement( pd[0], pd[1] );
00200         const double t123 = t1 + t2 + t3;
00201 
00202         const QPointF cp3 = ( t2 + t3 ) / t123 * pd[n-1] + t1 / t123 * pd[0];
00203         const QPointF cp4 = ( t3 * pd[n-1] + ( t1 + t2 ) * pd[0] ) / t123;
00204 
00205         const QPointF pN = ( t2 * cp2 + t1 * cp3 ) / ( t1 + t2 );
00206 
00207         path.cubicTo( cp1, cp2, pN );
00208         path.cubicTo( cp3, cp4, p0 );
00209     }
00210 
00211     return path;
00212 }
00213 
00215 QwtSplineBasis::QwtSplineBasis()
00216 {
00217 }
00218 
00220 QwtSplineBasis::~QwtSplineBasis()
00221 {
00222 }
00223 
00225 uint QwtSplineBasis::locality() const
00226 {
00227     return 2;
00228 }
00229 
00237 QPainterPath QwtSplineBasis::painterPath( const QPolygonF &points ) const
00238 {
00239     if ( points.size() < 4 )
00240         return QPainterPath();
00241 
00242     QPainterPath path;
00243 
00244     switch( parametrization()->type() )
00245     {
00246         case QwtSplineParametrization::ParameterUniform:
00247         {
00248             path = qwtSplineBasisPathUniform( points, boundaryType() );
00249             break;
00250         }
00251         default:
00252         {
00253             path = qwtSplineBasisPath( points, parametrization(), boundaryType() );
00254         }
00255     }
00256 
00257     return path;
00258 }


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56