qwt_spline.cpp
/******************************************************************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#include "qwt_spline.h"
#include "qwt_spline_parametrization.h"
#include "qwt_spline_polynomial.h"
#include "qwt_bezier.h"
#include <qpainterpath.h>
namespace QwtSplineC1P
{
struct param
{
param( const QwtSplineParametrization* p ):
parameter( p )
{
}
inline double operator()( const QPointF& p1, const QPointF& p2 ) const
{
return parameter->valueIncrement( p1, p2 );
}
const QwtSplineParametrization* parameter;
};
struct paramY
{
inline double operator()( const QPointF& p1, const QPointF& p2 ) const
{
return QwtSplineParametrization::valueIncrementY( p1, p2 );
}
};
struct paramUniform
{
inline double operator()( const QPointF& p1, const QPointF& p2 ) const
{
return QwtSplineParametrization::valueIncrementUniform( p1, p2 );
}
};
struct paramCentripetal
{
inline double operator()( const QPointF& p1, const QPointF& p2 ) const
{
return QwtSplineParametrization::valueIncrementCentripetal( p1, p2 );
}
};
struct paramChordal
{
inline double operator()( const QPointF& p1, const QPointF& p2 ) const
{
return QwtSplineParametrization::valueIncrementChordal( p1, p2 );
}
};
struct paramManhattan
{
inline double operator()( const QPointF& p1, const QPointF& p2 ) const
{
return QwtSplineParametrization::valueIncrementManhattan( p1, p2 );
}
};
class PathStore
{
public:
inline void init( int size )
{
Q_UNUSED(size);
}
inline void start( double x1, double y1 )
{
path.moveTo( x1, y1 );
}
inline void addCubic( double cx1, double cy1,
double cx2, double cy2, double x2, double y2 )
{
path.cubicTo( cx1, cy1, cx2, cy2, x2, y2 );
}
inline void end()
{
path.closeSubpath();
}
QPainterPath path;
};
class ControlPointsStore
{
public:
inline ControlPointsStore():
m_cp( NULL )
{
}
inline void init( int size )
{
controlPoints.resize( size );
m_cp = controlPoints.data();
}
inline void start( double x1, double y1 )
{
Q_UNUSED( x1 );
Q_UNUSED( y1 );
}
inline void addCubic( double cx1, double cy1,
double cx2, double cy2, double x2, double y2 )
{
Q_UNUSED( x2 );
Q_UNUSED( y2 );
QLineF& l = *m_cp++;
l.setLine( cx1, cy1, cx2, cy2 );
}
inline void end()
{
}
QVector< QLineF > controlPoints;
private:
QLineF* m_cp;
};
double slopeBoundary( int boundaryCondition, double boundaryValue,
const QPointF& p1, const QPointF& p2, double slope1 )
{
const double dx = p2.x() - p1.x();
const double dy = p2.y() - p1.y();
double m = 0.0;
switch( boundaryCondition )
{
case QwtSpline::Clamped1:
{
m = boundaryValue;
break;
}
case QwtSpline::Clamped2:
{
const double c2 = 0.5 * boundaryValue;
const double c1 = slope1;
m = 0.5 * ( 3.0 * dy / dx - c1 - c2 * dx );
break;
}
case QwtSpline::Clamped3:
{
const double c3 = boundaryValue / 6.0;
m = c3 * dx * dx + 2 * dy / dx - slope1;
break;
}
case QwtSpline::LinearRunout:
{
const double s = dy / dx;
const double r = qBound( 0.0, boundaryValue, 1.0 );
m = s - r * ( s - slope1 );
break;
}
default:
{
m = dy / dx; // something
}
}
return m;
}
}
template< class SplineStore >
static inline SplineStore qwtSplineC1PathParamX(
const QwtSplineC1* spline, const QPolygonF& points )
{
const int n = points.size();
const QVector< double > m = spline->slopes( points );
if ( m.size() != n )
return SplineStore();
const QPointF* pd = points.constData();
const double* md = m.constData();
SplineStore store;
store.init( m.size() - 1 );
store.start( pd[0].x(), pd[0].y() );
for ( int i = 0; i < n - 1; i++ )
{
const double dx3 = ( pd[i + 1].x() - pd[i].x() ) / 3.0;
store.addCubic( pd[i].x() + dx3, pd[i].y() + md[i] * dx3,
pd[i + 1].x() - dx3, pd[i + 1].y() - md[i + 1] * dx3,
pd[i + 1].x(), pd[i + 1].y() );
}
return store;
}
template< class SplineStore >
static inline SplineStore qwtSplineC1PathParamY(
const QwtSplineC1* spline, const QPolygonF& points )
{
const int n = points.size();
QPolygonF pointsFlipped( n );
for ( int i = 0; i < n; i++ )
{
pointsFlipped[i].setX( points[i].y() );
pointsFlipped[i].setY( points[i].x() );
}
const QVector< double > m = spline->slopes( pointsFlipped );
if ( m.size() != n )
return SplineStore();
const QPointF* pd = pointsFlipped.constData();
const double* md = m.constData();
SplineStore store;
store.init( m.size() - 1 );
store.start( pd[0].y(), pd[0].x() );
QVector< QLineF > lines( n );
for ( int i = 0; i < n - 1; i++ )
{
const double dx3 = ( pd[i + 1].x() - pd[i].x() ) / 3.0;
store.addCubic( pd[i].y() + md[i] * dx3, pd[i].x() + dx3,
pd[i + 1].y() - md[i + 1] * dx3, pd[i + 1].x() - dx3,
pd[i + 1].y(), pd[i + 1].x() );
}
return store;
}
template< class SplineStore, class Param >
static inline SplineStore qwtSplineC1PathParametric(
const QwtSplineC1* spline, const QPolygonF& points, Param param )
{
const bool isClosing = ( spline->boundaryType() == QwtSpline::ClosedPolygon );
const int n = points.size();
QPolygonF pointsX, pointsY;
pointsX.resize( isClosing ? n + 1 : n );
pointsY.resize( isClosing ? n + 1 : n );
QPointF* px = pointsX.data();
QPointF* py = pointsY.data();
const QPointF* p = points.constData();
double t = 0.0;
px[0].rx() = py[0].rx() = t;
px[0].ry() = p[0].x();
py[0].ry() = p[0].y();
int numParamPoints = 1;
for ( int i = 1; i < n; i++ )
{
const double td = param( points[i - 1], points[i] );
if ( td > 0.0 )
{
t += td;
px[numParamPoints].rx() = py[numParamPoints].rx() = t;
px[numParamPoints].ry() = p[i].x();
py[numParamPoints].ry() = p[i].y();
numParamPoints++;
}
}
if ( isClosing )
{
const double td = param( points[n - 1], points[0] );
if ( td > 0.0 )
{
t += td;
px[numParamPoints].rx() = py[numParamPoints].rx() = t;
px[numParamPoints].ry() = p[0].x();
py[numParamPoints].ry() = p[0].y();
numParamPoints++;
}
}
if ( pointsX.size() != numParamPoints )
{
pointsX.resize( numParamPoints );
pointsY.resize( numParamPoints );
}
const QVector< double > slopesX = spline->slopes( pointsX );
const QVector< double > slopesY = spline->slopes( pointsY );
const double* mx = slopesX.constData();
const double* my = slopesY.constData();
// we don't need it anymore
pointsX.clear();
pointsY.clear();
SplineStore store;
store.init( isClosing ? n : n - 1 );
store.start( points[0].x(), points[0].y() );
int j = 0;
for ( int i = 0; i < n - 1; i++ )
{
const QPointF& p1 = p[i];
const QPointF& p2 = p[i + 1];
const double td = param( p1, p2 );
if ( td != 0.0 )
{
const double t3 = td / 3.0;
const double cx1 = p1.x() + mx[j] * t3;
const double cy1 = p1.y() + my[j] * t3;
const double cx2 = p2.x() - mx[j + 1] * t3;
const double cy2 = p2.y() - my[j + 1] * t3;
store.addCubic( cx1, cy1, cx2, cy2, p2.x(), p2.y() );
j++;
}
else
{
// setting control points to the ends
store.addCubic( p1.x(), p1.y(), p2.x(), p2.y(), p2.x(), p2.y() );
}
}
if ( isClosing )
{
const QPointF& p1 = p[n - 1];
const QPointF& p2 = p[0];
const double td = param( p1, p2 );
if ( td != 0.0 )
{
const double t3 = td / 3.0;
const double cx1 = p1.x() + mx[j] * t3;
const double cy1 = p1.y() + my[j] * t3;
const double cx2 = p2.x() - mx[0] * t3;
const double cy2 = p2.y() - my[0] * t3;
store.addCubic( cx1, cy1, cx2, cy2, p2.x(), p2.y() );
}
else
{
store.addCubic( p1.x(), p1.y(), p2.x(), p2.y(), p2.x(), p2.y() );
}
store.end();
}
return store;
}
template< QwtSplinePolynomial toPolynomial( const QPointF&, double, const QPointF&, double ) >
static QPolygonF qwtPolygonParametric( double distance,
const QPolygonF& points, const QVector< double >& values, bool withNodes )
{
QPolygonF fittedPoints;
const QPointF* p = points.constData();
const double* v = values.constData();
fittedPoints += p[0];
double t = distance;
const int n = points.size();
for ( int i = 0; i < n - 1; i++ )
{
const QPointF& p1 = p[i];
const QPointF& p2 = p[i + 1];
const QwtSplinePolynomial polynomial = toPolynomial( p1, v[i], p2, v[i + 1] );
const double l = p2.x() - p1.x();
while ( t < l )
{
fittedPoints += QPointF( p1.x() + t, p1.y() + polynomial.valueAt( t ) );
t += distance;
}
if ( withNodes )
{
if ( qFuzzyCompare( fittedPoints.last().x(), p2.x() ) )
fittedPoints.last() = p2;
else
fittedPoints += p2;
}
else
{
t -= l;
}
}
return fittedPoints;
}
class QwtSpline::PrivateData
{
public:
PrivateData()
: boundaryType( QwtSpline::ConditionalBoundaries )
{
parametrization = new QwtSplineParametrization(
QwtSplineParametrization::ParameterChordal );
// parabolic runout at both ends
boundaryConditions[0].type = QwtSpline::Clamped3;
boundaryConditions[0].value = 0.0;
boundaryConditions[1].type = QwtSpline::Clamped3;
boundaryConditions[1].value = 0.0;
}
~PrivateData()
{
delete parametrization;
}
QwtSplineParametrization* parametrization;
QwtSpline::BoundaryType boundaryType;
struct
{
int type;
double value;
} boundaryConditions[2];
};
QPolygonF QwtSpline::polygon( const QPolygonF& points, double tolerance ) const
{
if ( tolerance <= 0.0 )
return QPolygonF();
const QPainterPath path = painterPath( points );
const int n = path.elementCount();
if ( n == 0 )
return QPolygonF();
const QPainterPath::Element el = path.elementAt( 0 );
if ( el.type != QPainterPath::MoveToElement )
return QPolygonF();
QPointF p1( el.x, el.y );
QPolygonF polygon;
QwtBezier bezier( tolerance );
for ( int i = 1; i < n; i += 3 )
{
const QPainterPath::Element el1 = path.elementAt( i );
const QPainterPath::Element el2 = path.elementAt( i + 1 );
const QPainterPath::Element el3 = path.elementAt( i + 2 );
const QPointF cp1( el1.x, el1.y );
const QPointF cp2( el2.x, el2.y );
const QPointF p2( el3.x, el3.y );
bezier.appendToPolygon( p1, cp1, cp2, p2, polygon );
p1 = p2;
}
return polygon;
}
QwtSpline::QwtSpline()
{
m_data = new PrivateData;
}
QwtSpline::~QwtSpline()
{
delete m_data;
}
uint QwtSpline::locality() const
{
return 0;
}
void QwtSpline::setParametrization( int type )
{
if ( m_data->parametrization->type() != type )
{
delete m_data->parametrization;
m_data->parametrization = new QwtSplineParametrization( type );
}
}
void QwtSpline::setParametrization( QwtSplineParametrization* parametrization )
{
if ( ( parametrization != NULL ) && ( m_data->parametrization != parametrization ) )
{
delete m_data->parametrization;
m_data->parametrization = parametrization;
}
}
const QwtSplineParametrization* QwtSpline::parametrization() const
{
return m_data->parametrization;
}
void QwtSpline::setBoundaryType( BoundaryType boundaryType )
{
m_data->boundaryType = boundaryType;
}
QwtSpline::BoundaryType QwtSpline::boundaryType() const
{
return m_data->boundaryType;
}
void QwtSpline::setBoundaryCondition( BoundaryPosition position, int condition )
{
if ( ( position == QwtSpline::AtBeginning ) || ( position == QwtSpline::AtEnd ) )
m_data->boundaryConditions[position].type = condition;
}
int QwtSpline::boundaryCondition( BoundaryPosition position ) const
{
if ( ( position == QwtSpline::AtBeginning ) || ( position == QwtSpline::AtEnd ) )
return m_data->boundaryConditions[position].type;
return m_data->boundaryConditions[0].type; // should never happen
}
void QwtSpline::setBoundaryValue( BoundaryPosition position, double value )
{
if ( ( position == QwtSpline::AtBeginning ) || ( position == QwtSpline::AtEnd ) )
m_data->boundaryConditions[position].value = value;
}
double QwtSpline::boundaryValue( BoundaryPosition position ) const
{
if ( ( position == QwtSpline::AtBeginning ) || ( position == QwtSpline::AtEnd ) )
return m_data->boundaryConditions[position].value;
return m_data->boundaryConditions[0].value; // should never happen
}
void QwtSpline::setBoundaryConditions(
int condition, double valueBegin, double valueEnd )
{
setBoundaryCondition( QwtSpline::AtBeginning, condition );
setBoundaryValue( QwtSpline::AtBeginning, valueBegin );
setBoundaryCondition( QwtSpline::AtEnd, condition );
setBoundaryValue( QwtSpline::AtEnd, valueEnd );
}
QwtSplineInterpolating::QwtSplineInterpolating()
{
}
QwtSplineInterpolating::~QwtSplineInterpolating()
{
}
QPainterPath QwtSplineInterpolating::painterPath( const QPolygonF& points ) const
{
const int n = points.size();
QPainterPath path;
if ( n == 0 )
return path;
if ( n == 1 )
{
path.moveTo( points[0] );
return path;
}
if ( n == 2 )
{
path.addPolygon( points );
return path;
}
const QVector< QLineF > controlLines = bezierControlLines( points );
if ( controlLines.size() < n - 1 )
return path;
const QPointF* p = points.constData();
const QLineF* l = controlLines.constData();
path.moveTo( p[0] );
for ( int i = 0; i < n - 1; i++ )
path.cubicTo( l[i].p1(), l[i].p2(), p[i + 1] );
if ( ( boundaryType() == QwtSpline::ClosedPolygon )
&& ( controlLines.size() >= n ) )
{
path.cubicTo( l[n - 1].p1(), l[n - 1].p2(), p[0] );
path.closeSubpath();
}
return path;
}
QPolygonF QwtSplineInterpolating::polygon(
const QPolygonF& points, double tolerance ) const
{
if ( tolerance <= 0.0 )
return QPolygonF();
const QVector< QLineF > controlLines = bezierControlLines( points );
if ( controlLines.isEmpty() )
return QPolygonF();
const bool isClosed = boundaryType() == QwtSpline::ClosedPolygon;
QwtBezier bezier( tolerance );
const QPointF* p = points.constData();
const QLineF* cl = controlLines.constData();
const int n = controlLines.size();
QPolygonF polygon;
for ( int i = 0; i < n - 1; i++ )
{
const QLineF& l = cl[i];
bezier.appendToPolygon( p[i], l.p1(), l.p2(), p[i + 1], polygon );
}
const QPointF& pn = isClosed ? p[0] : p[n];
const QLineF& l = cl[n - 1];
bezier.appendToPolygon( p[n - 1], l.p1(), l.p2(), pn, polygon );
return polygon;
}
QPolygonF QwtSplineInterpolating::equidistantPolygon( const QPolygonF& points,
double distance, bool withNodes ) const
{
if ( distance <= 0.0 )
return QPolygonF();
const int n = points.size();
if ( n <= 1 )
return points;
if ( n == 2 )
{
// TODO
return points;
}
QPolygonF path;
const QVector< QLineF > controlLines = bezierControlLines( points );
if ( controlLines.size() < n - 1 )
return path;
path += points.first();
double t = distance;
const QPointF* p = points.constData();
const QLineF* cl = controlLines.constData();
const QwtSplineParametrization* param = parametrization();
for ( int i = 0; i < n - 1; i++ )
{
const double l = param->valueIncrement( p[i], p[i + 1] );
while ( t < l )
{
path += QwtBezier::pointAt( p[i], cl[i].p1(),
cl[i].p2(), p[i + 1], t / l );
t += distance;
}
if ( withNodes )
{
if ( qFuzzyCompare( path.last().x(), p[i + 1].x() ) )
path.last() = p[i + 1];
else
path += p[i + 1];
t = distance;
}
else
{
t -= l;
}
}
if ( ( boundaryType() == QwtSpline::ClosedPolygon )
&& ( controlLines.size() >= n ) )
{
const double l = param->valueIncrement( p[n - 1], p[0] );
while ( t < l )
{
path += QwtBezier::pointAt( p[n - 1], cl[n - 1].p1(),
cl[n - 1].p2(), p[0], t / l );
t += distance;
}
if ( qFuzzyCompare( path.last().x(), p[0].x() ) )
path.last() = p[0];
else
path += p[0];
}
return path;
}
QwtSplineG1::QwtSplineG1()
{
}
QwtSplineG1::~QwtSplineG1()
{
}
QwtSplineC1::QwtSplineC1()
{
setParametrization( QwtSplineParametrization::ParameterX );
}
QwtSplineC1::~QwtSplineC1()
{
}
double QwtSplineC1::slopeAtBeginning( const QPolygonF& points, double slopeNext ) const
{
if ( points.size() < 2 )
return 0.0;
return QwtSplineC1P::slopeBoundary(
boundaryCondition( QwtSpline::AtBeginning ),
boundaryValue( QwtSpline::AtBeginning ),
points[0], points[1], slopeNext );
}
double QwtSplineC1::slopeAtEnd( const QPolygonF& points, double slopeBefore ) const
{
const int n = points.size();
const QPointF p1( points[n - 1].x(), -points[n - 1].y() );
const QPointF p2( points[n - 2].x(), -points[n - 2].y() );
const int condition = boundaryCondition( QwtSpline::AtEnd );
double value = boundaryValue( QwtSpline::AtEnd );
if ( condition != QwtSpline::LinearRunout )
{
// beside LinearRunout the boundaryValue is a slope or curvature
// and needs to be inverted too
value = -value;
}
const double slope = QwtSplineC1P::slopeBoundary( condition, value, p1, p2, -slopeBefore );
return -slope;
}
QPainterPath QwtSplineC1::painterPath( const QPolygonF& points ) const
{
const int n = points.size();
if ( n <= 2 )
return QwtSplineInterpolating::painterPath( points );
using namespace QwtSplineC1P;
PathStore store;
switch( parametrization()->type() )
{
case QwtSplineParametrization::ParameterX:
{
store = qwtSplineC1PathParamX< PathStore >( this, points );
break;
}
case QwtSplineParametrization::ParameterY:
{
store = qwtSplineC1PathParamY< PathStore >( this, points );
break;
}
case QwtSplineParametrization::ParameterUniform:
{
store = qwtSplineC1PathParametric< PathStore >(
this, points, paramUniform() );
break;
}
case QwtSplineParametrization::ParameterCentripetal:
{
store = qwtSplineC1PathParametric< PathStore >(
this, points, paramCentripetal() );
break;
}
case QwtSplineParametrization::ParameterChordal:
{
store = qwtSplineC1PathParametric< PathStore >(
this, points, paramChordal() );
break;
}
default:
{
store = qwtSplineC1PathParametric< PathStore >(
this, points, param( parametrization() ) );
}
}
return store.path;
}
QVector< QLineF > QwtSplineC1::bezierControlLines( const QPolygonF& points ) const
{
using namespace QwtSplineC1P;
const int n = points.size();
if ( n <= 2 )
return QVector< QLineF >();
ControlPointsStore store;
switch( parametrization()->type() )
{
case QwtSplineParametrization::ParameterX:
{
store = qwtSplineC1PathParamX< ControlPointsStore >( this, points );
break;
}
case QwtSplineParametrization::ParameterY:
{
store = qwtSplineC1PathParamY< ControlPointsStore >( this, points );
break;
}
case QwtSplineParametrization::ParameterUniform:
{
store = qwtSplineC1PathParametric< ControlPointsStore >(
this, points, paramUniform() );
break;
}
case QwtSplineParametrization::ParameterCentripetal:
{
store = qwtSplineC1PathParametric< ControlPointsStore >(
this, points, paramCentripetal() );
break;
}
case QwtSplineParametrization::ParameterChordal:
{
store = qwtSplineC1PathParametric< ControlPointsStore >(
this, points, paramChordal() );
break;
}
default:
{
store = qwtSplineC1PathParametric< ControlPointsStore >(
this, points, param( parametrization() ) );
}
}
return store.controlPoints;
}
QPolygonF QwtSplineC1::equidistantPolygon( const QPolygonF& points,
double distance, bool withNodes ) const
{
if ( parametrization()->type() == QwtSplineParametrization::ParameterX )
{
if ( points.size() > 2 )
{
const QVector< double > m = slopes( points );
if ( m.size() != points.size() )
return QPolygonF();
return qwtPolygonParametric< QwtSplinePolynomial::fromSlopes >(
distance, points, m, withNodes );
}
}
return QwtSplineInterpolating::equidistantPolygon( points, distance, withNodes );
}
QVector< QwtSplinePolynomial > QwtSplineC1::polynomials(
const QPolygonF& points ) const
{
QVector< QwtSplinePolynomial > polynomials;
const QVector< double > m = slopes( points );
if ( m.size() < 2 )
return polynomials;
polynomials.reserve( m.size() - 1 );
for ( int i = 1; i < m.size(); i++ )
{
polynomials += QwtSplinePolynomial::fromSlopes(
points[i - 1], m[i - 1], points[i], m[i] );
}
return polynomials;
}
QwtSplineC2::QwtSplineC2()
{
}
QwtSplineC2::~QwtSplineC2()
{
}
QPainterPath QwtSplineC2::painterPath( const QPolygonF& points ) const
{
// could be implemented from curvatures without the extra
// loop for calculating the slopes vector. TODO ...
return QwtSplineC1::painterPath( points );
}
QVector< QLineF > QwtSplineC2::bezierControlLines( const QPolygonF& points ) const
{
// could be implemented from curvatures without the extra
// loop for calculating the slopes vector. TODO ...
return QwtSplineC1::bezierControlLines( points );
}
QPolygonF QwtSplineC2::equidistantPolygon( const QPolygonF& points,
double distance, bool withNodes ) const
{
if ( parametrization()->type() == QwtSplineParametrization::ParameterX )
{
if ( points.size() > 2 )
{
const QVector< double > cv = curvatures( points );
if ( cv.size() != points.size() )
return QPolygonF();
return qwtPolygonParametric< QwtSplinePolynomial::fromCurvatures >(
distance, points, cv, withNodes );
}
}
return QwtSplineInterpolating::equidistantPolygon( points, distance, withNodes );
}
QVector< double > QwtSplineC2::slopes( const QPolygonF& points ) const
{
const QVector< double > curvatures = this->curvatures( points );
if ( curvatures.size() < 2 )
return QVector< double >();
QVector< double > slopes( curvatures.size() );
const double* cv = curvatures.constData();
double* m = slopes.data();
const int n = points.size();
const QPointF* p = points.constData();
QwtSplinePolynomial polynomial;
for ( int i = 0; i < n - 1; i++ )
{
polynomial = QwtSplinePolynomial::fromCurvatures( p[i], cv[i], p[i + 1], cv[i + 1] );
m[i] = polynomial.c1;
}
m[n - 1] = polynomial.slopeAt( p[n - 1].x() - p[n - 2].x() );
return slopes;
}
QVector< QwtSplinePolynomial > QwtSplineC2::polynomials( const QPolygonF& points ) const
{
QVector< QwtSplinePolynomial > polynomials;
const QVector< double > curvatures = this->curvatures( points );
if ( curvatures.size() < 2 )
return polynomials;
const QPointF* p = points.constData();
const double* cv = curvatures.constData();
const int n = curvatures.size();
polynomials.reserve( n - 1 );
for ( int i = 1; i < n; i++ )
{
polynomials += QwtSplinePolynomial::fromCurvatures(
p[i - 1], cv[i - 1], p[i], cv[i] );
}
return polynomials;
}
QVector< QLineF >
QwtBezier
An implementation of the de Casteljau’s Algorithm for interpolating Bézier curves.
Definition: qwt_bezier.h:30
QwtBezier::appendToPolygon
void appendToPolygon(const QPointF &p1, const QPointF &cp1, const QPointF &cp2, const QPointF &p2, QPolygonF &polygon) const
Interpolate a Bézier curve by a polygon.
Definition: qwt_bezier.cpp:186
QwtBezier::pointAt
static QPointF pointAt(const QPointF &p1, const QPointF &cp1, const QPointF &cp2, const QPointF &p2, double t)
Definition: qwt_bezier.cpp:239
QwtSplineC1
Base class for spline interpolations providing a first order parametric continuity ( C1 ) between adj...
Definition: qwt_spline.h:236
QwtSplineC1::slopes
virtual QVector< double > slopes(const QPolygonF &) const =0
Find the first derivative at the control points.
QwtSplineC1::~QwtSplineC1
virtual ~QwtSplineC1()
Destructor.
Definition: qwt_spline.cpp:968
QwtSplineC1::QwtSplineC1
QwtSplineC1()
Constructor.
Definition: qwt_spline.cpp:962
QwtSplineC1::slopeAtBeginning
virtual double slopeAtBeginning(const QPolygonF &, double slopeNext) const
Definition: qwt_spline.cpp:979
QwtSplineC1::painterPath
virtual QPainterPath painterPath(const QPolygonF &) const override
Calculate an interpolated painter path.
Definition: qwt_spline.cpp:1043
QwtSplineC1::equidistantPolygon
virtual QPolygonF equidistantPolygon(const QPolygonF &, double distance, bool withNodes) const override
Find an interpolated polygon with "equidistant" points.
Definition: qwt_spline.cpp:1167
QwtSplineC1::bezierControlLines
virtual QVector< QLineF > bezierControlLines(const QPolygonF &) const override
Interpolate a curve with Bezier curves.
Definition: qwt_spline.cpp:1101
QwtSplineC1::slopeAtEnd
virtual double slopeAtEnd(const QPolygonF &, double slopeBefore) const
Definition: qwt_spline.cpp:997
QwtSplineC1::polynomials
virtual QVector< QwtSplinePolynomial > polynomials(const QPolygonF &) const
Calculate the interpolating polynomials for a non parametric spline.
Definition: qwt_spline.cpp:1201
QwtSplineC2::equidistantPolygon
virtual QPolygonF equidistantPolygon(const QPolygonF &, double distance, bool withNodes) const override
Find an interpolated polygon with "equidistant" points.
Definition: qwt_spline.cpp:1295
QwtSplineC2::slopes
virtual QVector< double > slopes(const QPolygonF &) const override
Find the first derivative at the control points.
Definition: qwt_spline.cpp:1339
QwtSplineC2::QwtSplineC2
QwtSplineC2()
Constructor.
Definition: qwt_spline.cpp:1228
QwtSplineC2::bezierControlLines
virtual QVector< QLineF > bezierControlLines(const QPolygonF &) const override
Interpolate a curve with Bezier curves.
Definition: qwt_spline.cpp:1270
QwtSplineC2::polynomials
virtual QVector< QwtSplinePolynomial > polynomials(const QPolygonF &) const override
Calculate the interpolating polynomials for a non parametric spline.
Definition: qwt_spline.cpp:1381
QwtSplineC2::~QwtSplineC2
virtual ~QwtSplineC2()
Destructor.
Definition: qwt_spline.cpp:1233
QwtSplineC2::painterPath
virtual QPainterPath painterPath(const QPolygonF &) const override
Interpolate a curve with Bezier curves.
Definition: qwt_spline.cpp:1249
QwtSplineG1::~QwtSplineG1
virtual ~QwtSplineG1()
Destructor.
Definition: qwt_spline.cpp:949
QwtSplineG1::QwtSplineG1
QwtSplineG1()
Constructor.
Definition: qwt_spline.cpp:944
QwtSpline
Base class for all splines.
Definition: qwt_spline.h:58
QwtSpline::BoundaryPosition
BoundaryPosition
Definition: qwt_spline.h:100
QwtSpline::AtBeginning
@ AtBeginning
the condition is at the beginning of the polynomial
Definition: qwt_spline.h:102
QwtSpline::AtEnd
@ AtEnd
the condition is at the end of the polynomial
Definition: qwt_spline.h:105
QwtSpline::painterPath
virtual QPainterPath painterPath(const QPolygonF &) const =0
QwtSpline::boundaryValue
double boundaryValue(BoundaryPosition) const
Definition: qwt_spline.cpp:682
QwtSpline::setBoundaryType
void setBoundaryType(BoundaryType)
Definition: qwt_spline.cpp:617
QwtSpline::QwtSpline
QwtSpline()
Constructor.
Definition: qwt_spline.cpp:540
QwtSpline::setBoundaryCondition
void setBoundaryCondition(BoundaryPosition, int condition)
Define the condition for an endpoint of the spline.
Definition: qwt_spline.cpp:639
QwtSpline::parametrization
const QwtSplineParametrization * parametrization() const
Definition: qwt_spline.cpp:605
QwtSpline::boundaryCondition
int boundaryCondition(BoundaryPosition) const
Definition: qwt_spline.cpp:651
QwtSpline::boundaryType
BoundaryType boundaryType() const
Definition: qwt_spline.cpp:626
QwtSpline::locality
virtual uint locality() const
Definition: qwt_spline.cpp:564
QwtSpline::~QwtSpline
virtual ~QwtSpline()
Destructor.
Definition: qwt_spline.cpp:546
QwtSpline::polygon
virtual QPolygonF polygon(const QPolygonF &, double tolerance) const
Interpolate a curve by a polygon.
Definition: qwt_spline.cpp:496
QwtSpline::setBoundaryConditions
void setBoundaryConditions(int condition, double valueBegin=0.0, double valueEnd=0.0)
Define the condition at the endpoints of a spline.
Definition: qwt_spline.cpp:700
QwtSpline::setBoundaryValue
void setBoundaryValue(BoundaryPosition, double value)
Define the boundary value.
Definition: qwt_spline.cpp:670
QwtSpline::BoundaryType
BoundaryType
Definition: qwt_spline.h:66
QwtSpline::ClosedPolygon
@ ClosedPolygon
Definition: qwt_spline.h:92
QwtSpline::ConditionalBoundaries
@ ConditionalBoundaries
Definition: qwt_spline.h:72
QwtSpline::Clamped2
@ Clamped2
Definition: qwt_spline.h:134
QwtSpline::LinearRunout
@ LinearRunout
Definition: qwt_spline.h:153
QwtSpline::Clamped3
@ Clamped3
Definition: qwt_spline.h:143
QwtSpline::Clamped1
@ Clamped1
Definition: qwt_spline.h:125
QwtSpline::setParametrization
void setParametrization(int type)
Definition: qwt_spline.cpp:576
QwtSplineInterpolating::~QwtSplineInterpolating
virtual ~QwtSplineInterpolating()
Destructor.
Definition: qwt_spline.cpp:716
QwtSplineInterpolating::equidistantPolygon
virtual QPolygonF equidistantPolygon(const QPolygonF &, double distance, bool withNodes) const
Find an interpolated polygon with "equidistant" points.
Definition: qwt_spline.cpp:863
QwtSplineInterpolating::bezierControlLines
virtual QVector< QLineF > bezierControlLines(const QPolygonF &) const =0
Interpolate a curve with Bezier curves.
QwtSplineInterpolating::QwtSplineInterpolating
QwtSplineInterpolating()
Constructor.
Definition: qwt_spline.cpp:711
QwtSplineInterpolating::polygon
virtual QPolygonF polygon(const QPolygonF &, double tolerance) const override
Interpolate a curve by a polygon.
Definition: qwt_spline.cpp:805
QwtSplineInterpolating::painterPath
virtual QPainterPath painterPath(const QPolygonF &) const override
Interpolate a curve with Bezier curves.
Definition: qwt_spline.cpp:748
QwtSplineParametrization
Curve parametrization used for a spline interpolation.
Definition: qwt_spline_parametrization.h:45
QwtSplineParametrization::valueIncrementChordal
static double valueIncrementChordal(const QPointF &, const QPointF &)
Calculate the ParameterChordal value increment for 2 points.
Definition: qwt_spline_parametrization.h:179
QwtSplineParametrization::valueIncrementCentripetal
static double valueIncrementCentripetal(const QPointF &, const QPointF &)
Calculate the ParameterCentripetal value increment for 2 points.
Definition: qwt_spline_parametrization.h:196
QwtSplineParametrization::valueIncrementUniform
static double valueIncrementUniform(const QPointF &, const QPointF &)
Calculate the ParameterUniform value increment.
Definition: qwt_spline_parametrization.h:162
QwtSplineParametrization::valueIncrement
virtual double valueIncrement(const QPointF &, const QPointF &) const
Calculate the parameter value increment for 2 points.
Definition: qwt_spline_parametrization.cpp:35
QwtSplineParametrization::ParameterY
@ ParameterY
Definition: qwt_spline_parametrization.h:60
QwtSplineParametrization::ParameterCentripetal
@ ParameterCentripetal
Definition: qwt_spline_parametrization.h:94
QwtSplineParametrization::ParameterX
@ ParameterX
Definition: qwt_spline_parametrization.h:54
QwtSplineParametrization::ParameterUniform
@ ParameterUniform
Definition: qwt_spline_parametrization.h:72
QwtSplineParametrization::ParameterChordal
@ ParameterChordal
Definition: qwt_spline_parametrization.h:82
QwtSplineParametrization::valueIncrementManhattan
static double valueIncrementManhattan(const QPointF &, const QPointF &)
Calculate the ParameterManhattan value increment for 2 points.
Definition: qwt_spline_parametrization.h:210
QwtSplineParametrization::valueIncrementY
static double valueIncrementY(const QPointF &, const QPointF &)
Calculate the ParameterY value increment for 2 points.
Definition: qwt_spline_parametrization.h:148
QwtSplinePolynomial
A cubic polynomial without constant term.
Definition: qwt_spline_polynomial.h:31
QwtSplinePolynomial::slopeAt
double slopeAt(double x) const
Definition: qwt_spline_polynomial.h:119
QwtSplinePolynomial::fromSlopes
static QwtSplinePolynomial fromSlopes(const QPointF &p1, double m1, const QPointF &p2, double m2)
Definition: qwt_spline_polynomial.h:147
QwtSplinePolynomial::valueAt
double valueAt(double x) const
Definition: qwt_spline_polynomial.h:108
QwtSplinePolynomial::fromCurvatures
static QwtSplinePolynomial fromCurvatures(const QPointF &p1, double cv1, const QPointF &p2, double cv2)
Definition: qwt_spline_polynomial.h:185
QwtSplinePolynomial::c1
double c1
coefficient of the linear summand
Definition: qwt_spline_polynomial.h:64