10 #include "qwt_spline_pleasing.h" 
   11 #include "qwt_spline_parametrization.h" 
   13 #include <qpainterpath.h> 
   15 static 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 );
 
   23 template< 
class Param >
 
   24 static QPointF qwtVector( Param param,
 
   25     const QPointF& p1, 
const QPointF& p2 )
 
   27     return ( p2 - p1 ) / param( p1, p2 );
 
   30 template< 
class Param >
 
   31 static 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 );
 
   40 namespace QwtSplinePleasingP
 
   55         inline double operator()( 
const QPointF& p1, 
const QPointF& p2 )
 const 
   57             return parameter->valueIncrement( p1, p2 );
 
   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 );
 
  124 static 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;
 
  162 template< 
class SplineStore, 
class Param >
 
  163 static 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;
 
const QwtSplineParametrization * parametrization() const
BoundaryType boundaryType() const
void setParametrization(int type)
virtual QPainterPath painterPath(const QPolygonF &) const override
Interpolate a curve with Bezier curves.
Curve parametrization used for a spline interpolation.
static double valueIncrementUniform(const QPointF &, const QPointF &)
Calculate the ParameterUniform value increment.
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.