10#include "qwt_spline_pleasing.h" 
   11#include "qwt_spline_parametrization.h" 
   13#include <qpainterpath.h> 
   15static inline double qwtChordalLength( 
const QPointF& point1, 
const QPointF& point2 )
 
   17    const double dx = point2.x() - point1.x();
 
   18    const double dy = point2.y() - point1.y();
 
   20    return std::sqrt( dx * dx + dy * dy );
 
   23template< 
class Param >
 
   24static QPointF qwtVector( Param param,
 
   25    const QPointF& p1, 
const QPointF& p2 )
 
   27    return ( p2 - p1 ) / param( p1, p2 );
 
   30template< 
class Param >
 
   31static QPointF qwtVectorCardinal( Param param,
 
   32    const QPointF& p1, 
const QPointF& p2, 
const QPointF& p3 )
 
   34    const double t1 = param( p1, p2 );
 
   35    const double t2 = param( p2, p3 );
 
   37    return t2 * ( p3 - p1 ) / ( t1 + t2 );
 
   40namespace QwtSplinePleasingP
 
   55        inline double operator()( 
const QPointF& p1, 
const QPointF& p2 )
 const 
   65        inline double operator()( 
const QPointF& p1, 
const QPointF& p2 )
 const 
   74        inline void init( 
int )
 
   78        inline void start( 
const QPointF& p0 )
 
   83        inline void addCubic( 
const QPointF& cp1,
 
   84            const QPointF& cp2, 
const QPointF& p2 )
 
   86            path.cubicTo( cp1, cp2, p2 );
 
   92    class ControlPointsStore
 
   95        inline ControlPointsStore():
 
  100        inline void init( 
int size )
 
  102            controlPoints.resize( size );
 
  103            m_cp = controlPoints.data();
 
  106        inline void start( 
const QPointF& )
 
  110        inline void addCubic( 
const QPointF& cp1,
 
  111            const QPointF& cp2, 
const QPointF& )
 
  114            l.setPoints( cp1, cp2 );
 
  124static inline QwtSplinePleasingP::Tension qwtTensionPleasing(
 
  125    double d13, 
double d23, 
double d24,
 
  126    const QPointF& p1, 
const QPointF& p2,
 
  127    const QPointF& p3, 
const QPointF& p4 )
 
  129    QwtSplinePleasingP::Tension tension;
 
  131    const bool b1 = ( d13 / 3.0 ) < d23;
 
  132    const bool b2 = ( d24 / 3.0 ) < d23;
 
  138            tension.t1 = ( p1 != p2 ) ? ( 1.0 / 3.0 ) : ( 2.0 / 3.0 );
 
  139            tension.t2 = ( p3 != p4 ) ? ( 1.0 / 3.0 ) : ( 2.0 / 3.0 );
 
  143            tension.t1 = tension.t2 = d23 / d24;
 
  150            tension.t1 = tension.t2 = d23 / d13;
 
  154            tension.t1 = d23 / d13;
 
  155            tension.t2 = d23 / d24;
 
  162template< 
class SplineStore, 
class Param >
 
  163static SplineStore qwtSplinePathPleasing( 
const QPolygonF& points,
 
  164    bool isClosed, Param param )
 
  166    using namespace QwtSplinePleasingP;
 
  168    const int size = points.size();
 
  170    const QPointF* p = points.constData();
 
  173    store.init( isClosed ? size : size - 1 );
 
  181        d13 = qwtChordalLength(p[0], p[2]);
 
  183        const Tension t0 = qwtTensionPleasing(
 
  184            qwtChordalLength( p[size - 1], p[1]), qwtChordalLength(p[0], p[1]),
 
  185            d13, p[size - 1], p[0], p[1], p[2] );
 
  187        const QPointF vec0 = qwtVectorCardinal< Param >( param, p[size - 1], p[0], p[1] );
 
  188        vec1 = qwtVectorCardinal< Param >( param, p[0], p[1], p[2] );
 
  190        store.addCubic( p[0] + vec0 * t0.t1, p[1] - vec1 * t0.t2, p[1] );
 
  194        d13 = qwtChordalLength(p[0], p[2]);
 
  196        const Tension t0 = qwtTensionPleasing(
 
  197            qwtChordalLength( p[0], p[1]), qwtChordalLength(p[0], p[1]),
 
  198            d13,  p[0], p[0], p[1], p[2] );
 
  200        const QPointF vec0 = 0.5 * qwtVector< Param >( param, p[0], p[1] );
 
  201        vec1 = qwtVectorCardinal< Param >( param, p[0], p[1], p[2] );
 
  203        store.addCubic( p[0] + vec0 * t0.t1, p[1] - vec1 * t0.t2, p[1] );
 
  206    for ( 
int i = 1; i < size - 2; i++ )
 
  208        const double d23 = qwtChordalLength( p[i], p[i + 1] );
 
  209        const double d24 = qwtChordalLength( p[i], p[i + 2] );
 
  211        const QPointF vec2 = qwtVectorCardinal< Param >( param, p[i], p[i + 1], p[i + 2] );
 
  213        const Tension t = qwtTensionPleasing(
 
  214            d13, d23, d24, p[i - 1], p[i], p[i + 1], p[i + 2] );
 
  216        store.addCubic( p[i] + vec1 * t.t1, p[i + 1] - vec2 * t.t2, p[i + 1] );
 
  224        const double d24 = qwtChordalLength( p[size - 2], p[0] );
 
  226        const Tension tn = qwtTensionPleasing(
 
  227            d13, qwtChordalLength( p[size - 2], p[size - 1] ), d24,
 
  228            p[size - 3], p[size - 2], p[size - 1], p[0] );
 
  230        const QPointF vec2 = qwtVectorCardinal< Param >( param, p[size - 2], p[size - 1], p[0] );
 
  231        store.addCubic( p[size - 2] + vec1 * tn.t1, p[size - 1] - vec2 * tn.t2, p[size - 1] );
 
  233        const double d34 = qwtChordalLength( p[size - 1], p[0] );
 
  234        const double d35 = qwtChordalLength( p[size - 1], p[1] );
 
  236        const Tension tc = qwtTensionPleasing( d24, d34, d35, p[size - 2], p[size - 1], p[0], p[1] );
 
  238        const QPointF vec3 = qwtVectorCardinal< Param >( param, p[size - 1], p[0], p[1] );
 
  240        store.addCubic( p[size - 1] + vec2 * tc.t1, p[0] - vec3 * tc.t2, p[0] );
 
  244        const double d24 = qwtChordalLength( p[size - 2], p[size - 1] );
 
  246        const Tension tn = qwtTensionPleasing(
 
  247            d13, qwtChordalLength( p[size - 2], p[size - 1] ), d24,
 
  248            p[size - 3], p[size - 2], p[size - 1], p[size - 1] );
 
  250        const QPointF vec2 = 0.5 * qwtVector< Param >( param, p[size - 2], p[size - 1] );
 
  251        store.addCubic( p[size - 2] + vec1 * tn.t1, p[size - 1] - vec2 * tn.t2, p[size - 1] );
 
  292    const int size = points.size();
 
  298    using namespace QwtSplinePleasingP;
 
  303        store = qwtSplinePathPleasing< PathStore >( points,
 
  304            isClosing, paramUniform() );
 
  308        store = qwtSplinePathPleasing< PathStore >( points,
 
  313        store.path.closeSubpath();
 
 
  328    const QPolygonF& points )
 const 
  330    const int size = points.size();
 
  336    using namespace QwtSplinePleasingP;
 
  338    ControlPointsStore store;
 
  341        store = qwtSplinePathPleasing< ControlPointsStore >( points,
 
  342            isClosing, paramUniform() );
 
  346        store = qwtSplinePathPleasing< ControlPointsStore >( points,
 
  350    return store.controlPoints;
 
 
virtual QPainterPath painterPath(const QPolygonF &) const =0
const QwtSplineParametrization * parametrization() const
BoundaryType boundaryType() const
void setParametrization(int type)
Curve parametrization used for a spline interpolation.
static double valueIncrementUniform(const QPointF &, const QPointF &)
Calculate the ParameterUniform value increment.
virtual double valueIncrement(const QPointF &, const QPointF &) const
Calculate the parameter value increment for 2 points.
virtual uint locality() const override
virtual QVector< QLineF > bezierControlLines(const QPolygonF &) const override
Interpolate a curve with Bezier curves.
virtual ~QwtSplinePleasing()
Destructor.
virtual QPainterPath painterPath(const QPolygonF &) const override
Interpolate a curve with Bezier curves.
QwtSplinePleasing()
Constructor.