Add files from zip
This commit is contained in:
101
tests/splineprof/main.cpp
Normal file
101
tests/splineprof/main.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
/*****************************************************************************
|
||||
* Qwt Examples - Copyright (C) 2002 Uwe Rathmann
|
||||
* This file may be used under the terms of the 3-clause BSD License
|
||||
*****************************************************************************/
|
||||
|
||||
#include <QwtSplinePleasing>
|
||||
#include <QwtSplineLocal>
|
||||
#include <QwtSplineCubic>
|
||||
#include <QwtSplineParametrization>
|
||||
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include <QPolygon>
|
||||
#include <QLine>
|
||||
#include <QDebug>
|
||||
|
||||
static void testSpline( const char* name, QwtSplineInterpolating* spline,
|
||||
int type, const QPolygonF& points )
|
||||
{
|
||||
spline->setParametrization( type );
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
const QVector< QLineF > lines = spline->bezierControlLines( points );
|
||||
|
||||
qDebug() << name << ":" << timer.elapsed();
|
||||
}
|
||||
|
||||
static void testSplines( int paramType, const QPolygonF& points )
|
||||
{
|
||||
#if 0
|
||||
QwtSplinePleasing splinePleasing;
|
||||
testSpline( "Pleasing", &splinePleasing, paramType, points );
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
QwtSplineLocal splineCardinal( QwtSplineLocal::Cardinal );
|
||||
testSpline( "Cardinal", &splineCardinal, paramType, points );
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
QwtSplineLocal splinePC( QwtSplineLocal::PChip );
|
||||
testSpline( "PChip", &splinePC, paramType, points );
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
QwtSplineLocal splineAkima( QwtSplineLocal::Akima );
|
||||
testSpline( "Akima", &splineAkima, paramType, points );
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
QwtSplineLocal splinePB( QwtSplineLocal::ParabolicBlending );
|
||||
testSpline( "Parabolic Blending", &splinePB, paramType, points );
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
QwtSplineCubic splineC2;
|
||||
testSpline( "Cubic", &splineC2, paramType, points );
|
||||
#endif
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
QPolygonF points;
|
||||
|
||||
for ( int i = 0; i < 10e6; i++ )
|
||||
points += QPointF( i, std::sin( i ) );
|
||||
|
||||
#if 1
|
||||
qDebug() << "=== X";
|
||||
testSplines( QwtSplineParametrization::ParameterX, points );
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
qDebug() << "=== Y";
|
||||
testSplines( QwtSplineParametrization::ParameterY, points );
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
qDebug() << "=== Uniform";
|
||||
testSplines( QwtSplineParametrization::ParameterUniform, points );
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
qDebug() << "=== Manhattan";
|
||||
testSplines( QwtSplineParametrization::ParameterManhattan, points );
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
qDebug() << "=== Chordal";
|
||||
testSplines( QwtSplineParametrization::ParameterChordal, points );
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
qDebug() << "=== Centripetral";
|
||||
testSplines( QwtSplineParametrization::ParameterCentripetal, points );
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
18
tests/splineprof/splineprof.pro
Normal file
18
tests/splineprof/splineprof.pro
Normal file
@@ -0,0 +1,18 @@
|
||||
################################################################
|
||||
# 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( $${PWD}/../tests.pri )
|
||||
|
||||
CONFIG -= gui
|
||||
|
||||
TARGET = splineprof
|
||||
|
||||
SOURCES = \
|
||||
main.cpp
|
||||
|
||||
589
tests/splinetest/main.cpp
Normal file
589
tests/splinetest/main.cpp
Normal file
@@ -0,0 +1,589 @@
|
||||
/*****************************************************************************
|
||||
* Qwt Examples - Copyright (C) 2002 Uwe Rathmann
|
||||
* This file may be used under the terms of the 3-clause BSD License
|
||||
*****************************************************************************/
|
||||
|
||||
#include <QwtSplineCubic>
|
||||
#include <QwtSplineLocal>
|
||||
#include <QwtSplineParametrization>
|
||||
#include <QwtSplinePolynomial>
|
||||
#include <QwtMath>
|
||||
|
||||
#include <QPolygon>
|
||||
#include <QPainterPath>
|
||||
#include <QDebug>
|
||||
|
||||
#define DEBUG_ERRORS 1
|
||||
|
||||
static inline bool fuzzyCompare( double a, double b )
|
||||
{
|
||||
return ( qFuzzyIsNull(a) && qFuzzyIsNull(b) ) || qFuzzyCompare(a, b);
|
||||
}
|
||||
|
||||
static QwtSplinePolynomial polynomialAt( int index,
|
||||
const QPolygonF& points, const QVector< double >& m )
|
||||
{
|
||||
return QwtSplinePolynomial::fromSlopes(
|
||||
points[index], m[index], points[index + 1], m[index + 1] );
|
||||
}
|
||||
|
||||
class CubicSpline : public QwtSplineCubic
|
||||
{
|
||||
public:
|
||||
CubicSpline( const QString& name )
|
||||
: d_name( name )
|
||||
{
|
||||
}
|
||||
|
||||
void setBoundaryConditions( int condition, double valueBegin, double valueEnd )
|
||||
{
|
||||
const QwtSpline::BoundaryCondition c =
|
||||
static_cast< QwtSpline::BoundaryCondition >( condition );
|
||||
|
||||
setBoundaryCondition( QwtSpline::AtBeginning, c );
|
||||
setBoundaryValue( QwtSpline::AtEnd, valueBegin );
|
||||
|
||||
setBoundaryCondition( QwtSpline::AtEnd, c );
|
||||
setBoundaryValue( QwtSpline::AtEnd, valueEnd );
|
||||
}
|
||||
|
||||
QString name() const
|
||||
{
|
||||
return d_name;
|
||||
}
|
||||
|
||||
private:
|
||||
const QString d_name;
|
||||
};
|
||||
|
||||
class LocalSpline : public QwtSplineLocal
|
||||
{
|
||||
public:
|
||||
LocalSpline( QwtSplineLocal::Type type, const QString& name )
|
||||
: QwtSplineLocal( type ),
|
||||
d_name( name )
|
||||
{
|
||||
}
|
||||
|
||||
void setBoundaryConditions( int condition, double valueBegin, double valueEnd )
|
||||
{
|
||||
const QwtSpline::BoundaryCondition c =
|
||||
static_cast< QwtSpline::BoundaryCondition >( condition );
|
||||
|
||||
setBoundaryCondition( QwtSpline::AtBeginning, c );
|
||||
setBoundaryValue( QwtSpline::AtEnd, valueBegin );
|
||||
|
||||
setBoundaryCondition( QwtSpline::AtEnd, c );
|
||||
setBoundaryValue( QwtSpline::AtEnd, valueEnd );
|
||||
}
|
||||
|
||||
QString name() const
|
||||
{
|
||||
return d_name;
|
||||
}
|
||||
|
||||
private:
|
||||
const QString d_name;
|
||||
};
|
||||
|
||||
class SplineTester
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
Cardinal,
|
||||
Akima,
|
||||
Cubic
|
||||
};
|
||||
|
||||
void testSplineC1( const LocalSpline* spline, const QPolygonF& points ) const;
|
||||
void testSplineC2( const CubicSpline* spline, const QPolygonF& points ) const;
|
||||
|
||||
private:
|
||||
bool verifyBoundary( const QwtSpline*, QwtSpline::BoundaryPosition,
|
||||
const QPolygonF& points, const QVector< double >& m ) const;
|
||||
|
||||
int verifyNodesCV( const QPolygonF& p, const QVector< double >& cv ) const;
|
||||
int verifyNodesM( const QPolygonF& p, const QVector< double >& m ) const;
|
||||
};
|
||||
|
||||
void SplineTester::testSplineC1( const LocalSpline* spline, const QPolygonF& points ) const
|
||||
{
|
||||
const QVector< double > m = spline->slopes( points );
|
||||
|
||||
if ( m.size() != points.size() )
|
||||
{
|
||||
qDebug() << qPrintable( spline->name() ) << "("
|
||||
<< points.size() << "):" << "not implemented";
|
||||
return;
|
||||
}
|
||||
|
||||
const bool okStart = verifyBoundary( spline, QwtSpline::AtBeginning, points, m );
|
||||
const bool okEnd = verifyBoundary( spline, QwtSpline::AtEnd, points, m );
|
||||
|
||||
if ( !okStart || !okEnd )
|
||||
{
|
||||
qDebug() << qPrintable( spline->name() ) << "("
|
||||
<< points.size() << "):" << false;
|
||||
|
||||
#if DEBUG_ERRORS > 0
|
||||
if ( !okStart )
|
||||
qDebug() << " invalid start condition";
|
||||
|
||||
if ( !okEnd )
|
||||
qDebug() << " invalid end condition";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void SplineTester::testSplineC2( const CubicSpline* spline, const QPolygonF& points ) const
|
||||
{
|
||||
const QVector< double > m = spline->slopes( points );
|
||||
const QVector< double > cv = spline->curvatures( points );
|
||||
|
||||
if ( m.size() != points.size() )
|
||||
{
|
||||
qDebug() << qPrintable( spline->name() ) << "("
|
||||
<< points.size() << "):" << "not implemented";
|
||||
return;
|
||||
}
|
||||
|
||||
const bool okStart = verifyBoundary( spline, QwtSpline::AtBeginning, points, m );
|
||||
const int numErrorsM = verifyNodesM( points, m );
|
||||
const int numErrorsCV = verifyNodesCV( points, cv );
|
||||
const bool okEnd = verifyBoundary( spline, QwtSpline::AtEnd, points, m );
|
||||
|
||||
if ( !okStart || numErrorsM > 0 || numErrorsCV > 0 || !okEnd )
|
||||
{
|
||||
qDebug() << qPrintable( spline->name() ) << "("
|
||||
<< points.size() << "):" << false;
|
||||
|
||||
#if DEBUG_ERRORS > 0
|
||||
if ( !okStart )
|
||||
qDebug() << " invalid start condition";
|
||||
|
||||
if ( numErrorsM > 0 )
|
||||
qDebug() << " invalid node conditions ( slope )" << numErrorsM;
|
||||
|
||||
if ( numErrorsCV > 0 )
|
||||
qDebug() << " invalid node conditions ( curvature )" << numErrorsCV;
|
||||
|
||||
if ( !okEnd )
|
||||
qDebug() << " invalid end condition";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool SplineTester::verifyBoundary( const QwtSpline* spline, QwtSpline::BoundaryPosition pos,
|
||||
const QPolygonF& points, const QVector< double >& m ) const
|
||||
{
|
||||
const bool isC2 = dynamic_cast< const QwtSplineC2* >( spline );
|
||||
|
||||
const int n = points.size();
|
||||
|
||||
const QwtSplinePolynomial polynomBegin = polynomialAt( 0, points, m );
|
||||
const QwtSplinePolynomial polynomEnd = polynomialAt( n - 2, points, m );
|
||||
|
||||
bool ok = false;
|
||||
|
||||
if ( spline->boundaryType() != QwtSpline::ConditionalBoundaries )
|
||||
{
|
||||
// periodic or closed
|
||||
|
||||
const double dx = points[n - 1].x() - points[n - 2].x();
|
||||
|
||||
ok = fuzzyCompare( polynomEnd.slopeAt( dx ),
|
||||
polynomBegin.slopeAt( 0.0 ) );
|
||||
|
||||
if ( ok && isC2 )
|
||||
{
|
||||
ok = fuzzyCompare( polynomEnd.curvatureAt( dx ),
|
||||
polynomBegin.curvatureAt( 0.0 ) );
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
switch( spline->boundaryCondition( pos ) )
|
||||
{
|
||||
case QwtSpline::Clamped1:
|
||||
{
|
||||
const double mt = ( pos == QwtSpline::AtBeginning ) ? m.first() : m.last();
|
||||
ok = fuzzyCompare( mt, spline->boundaryValue( pos ) );
|
||||
|
||||
break;
|
||||
}
|
||||
case QwtSpline::Clamped2:
|
||||
{
|
||||
double cv;
|
||||
if ( pos == QwtSpline::AtBeginning )
|
||||
{
|
||||
cv = polynomBegin.curvatureAt( 0.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
const double dx = points[n - 1].x() - points[n - 2].x();
|
||||
cv = polynomEnd.curvatureAt( dx );
|
||||
}
|
||||
|
||||
ok = fuzzyCompare( cv, spline->boundaryValue( pos ) );
|
||||
|
||||
break;
|
||||
}
|
||||
case QwtSpline::Clamped3:
|
||||
{
|
||||
double c3;
|
||||
if ( pos == QwtSpline::AtBeginning )
|
||||
c3 = polynomBegin.c3;
|
||||
else
|
||||
c3 = polynomEnd.c3;
|
||||
|
||||
ok = fuzzyCompare( 6.0 * c3, spline->boundaryValue( pos ) );
|
||||
break;
|
||||
}
|
||||
case QwtSpline::LinearRunout:
|
||||
{
|
||||
const double ratio = spline->boundaryValue( pos );
|
||||
if ( pos == QwtSpline::AtBeginning )
|
||||
{
|
||||
const double s = ( points[1].y() - points[0].y() ) /
|
||||
( points[1].x() - points[0].x() );
|
||||
|
||||
ok = fuzzyCompare( m[0], s - ratio * ( s - m[1] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
const double s = ( points[n - 1].y() - points[n - 2].y() ) /
|
||||
( points[n - 1].x() - points[n - 2].x() );
|
||||
|
||||
ok = fuzzyCompare( m[n - 1], s - ratio * ( s - m[n - 2] ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QwtSplineC2::CubicRunout:
|
||||
{
|
||||
if ( pos == QwtSpline::AtBeginning )
|
||||
{
|
||||
const QwtSplinePolynomial polynomBegin2 = polynomialAt( 1, points, m );
|
||||
|
||||
const double cv0 = polynomBegin.curvatureAt( 0.0 );
|
||||
const double cv1 = polynomBegin2.curvatureAt( 0.0 );
|
||||
const double cv2 = polynomBegin2.curvatureAt( points[2].x() - points[1].x() );
|
||||
|
||||
ok = fuzzyCompare( cv0, 2 * cv1 - cv2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
const QwtSplinePolynomial polynomEnd2 = polynomialAt( n - 3, points, m );
|
||||
|
||||
const double cv0 = polynomEnd.curvatureAt( points[n - 1].x() - points[n - 2].x() );
|
||||
const double cv1 = polynomEnd.curvatureAt( 0.0 );
|
||||
const double cv2 = polynomEnd2.curvatureAt( 0.0 );
|
||||
|
||||
ok = fuzzyCompare( cv0, 2 * cv1 - cv2 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QwtSplineC2::NotAKnot:
|
||||
{
|
||||
if ( pos == QwtSpline::AtBeginning )
|
||||
{
|
||||
const QwtSplinePolynomial polynomBegin2 = polynomialAt( 1, points, m );
|
||||
ok = fuzzyCompare( polynomBegin.c3, polynomBegin2.c3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
const QwtSplinePolynomial polynomEnd2 = polynomialAt( n - 3, points, m );
|
||||
ok = fuzzyCompare( polynomEnd.c3, polynomEnd2.c3 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
int SplineTester::verifyNodesCV( const QPolygonF& points, const QVector< double >& cv ) const
|
||||
{
|
||||
const int n = points.size();
|
||||
|
||||
int numErrors = 0;
|
||||
|
||||
double h1 = points[1].x() - points[0].x();
|
||||
double s1 = ( points[1].y() - points[0].y() ) / h1;
|
||||
|
||||
for ( int i = 1; i < n - 2; i++ )
|
||||
{
|
||||
const double h2 = points[i + 1].x() - points[i].x();
|
||||
const double s2 = ( points[i + 1].y() - points[i].y() ) / h2;
|
||||
|
||||
const double v = ( h1 + h2 ) * cv[i] + 0.5 * ( h1 * cv[i - 1] + h2 * cv[i + 1] );
|
||||
if ( !fuzzyCompare( v, 3 * ( s2 - s1 ) ) )
|
||||
{
|
||||
#if DEBUG_ERRORS > 1
|
||||
qDebug() << "invalid node condition (cv)" << i
|
||||
<< cv[i - 1] << cv[i] << cv[i + 1]
|
||||
<< v - 3 * ( s2 - s1 );
|
||||
#endif
|
||||
|
||||
numErrors++;
|
||||
}
|
||||
|
||||
h1 = h2;
|
||||
s1 = s2;
|
||||
}
|
||||
|
||||
return numErrors;
|
||||
}
|
||||
|
||||
int SplineTester::verifyNodesM( const QPolygonF& points, const QVector< double >& m ) const
|
||||
{
|
||||
const int n = points.size();
|
||||
|
||||
int numErrors = 0;
|
||||
|
||||
double dx1 = points[1].x() - points[0].x();
|
||||
QwtSplinePolynomial polynomial1 = QwtSplinePolynomial::fromSlopes(
|
||||
dx1, points[1].y() - points[0].y(), m[0], m[1] );
|
||||
|
||||
for ( int i = 1; i < n - 1; i++ )
|
||||
{
|
||||
const double dx2 = points[i + 1].x() - points[i].x();
|
||||
const double dy2 = points[i + 1].y() - points[i].y();
|
||||
|
||||
const QwtSplinePolynomial polynomial2 =
|
||||
QwtSplinePolynomial::fromSlopes( dx2, dy2, m[i], m[i + 1] );
|
||||
|
||||
const double cv1 = polynomial1.curvatureAt( dx1 );
|
||||
const double cv2 = polynomial2.curvatureAt( 0.0 );
|
||||
if ( !fuzzyCompare( cv1, cv2 ) )
|
||||
{
|
||||
#if DEBUG_ERRORS > 1
|
||||
qDebug() << "invalid node condition (m)" << i <<
|
||||
cv1 << cv1 << cv2 - cv1;
|
||||
#endif
|
||||
|
||||
numErrors++;
|
||||
}
|
||||
|
||||
dx1 = dx2;
|
||||
polynomial1 = polynomial2;
|
||||
}
|
||||
|
||||
return numErrors;
|
||||
}
|
||||
|
||||
static void testSplines( SplineTester::Type splineType, const QPolygonF& points )
|
||||
{
|
||||
struct Condition
|
||||
{
|
||||
const char* name;
|
||||
int condition;
|
||||
double valueBegin;
|
||||
double valueEnd;
|
||||
} conditions[] =
|
||||
{
|
||||
{ "Periodic", -1, 0.0, 0.0 },
|
||||
{ "Clamped1", QwtSpline::Clamped1, 0.5, 1.0 },
|
||||
{ "Clamped2", QwtSpline::Clamped2, 0.4, -0.8 },
|
||||
{ "Clamped3", QwtSpline::Clamped3, 0.03, 0.01 },
|
||||
{ "Linear Runout", QwtSpline::LinearRunout, 0.3, 0.7 },
|
||||
{ "Cubic Runout", QwtSplineC2::CubicRunout, 0.0, 0.0 },
|
||||
{ "Not A Knot", QwtSplineC2::NotAKnot, 0.0, 0.0 }
|
||||
};
|
||||
|
||||
for ( uint i = 0; i < sizeof( conditions ) / sizeof( conditions[0] ); i++ )
|
||||
{
|
||||
const Condition& c = conditions[i];
|
||||
|
||||
if ( conditions[i].condition == QwtSplineC2::NotAKnot && points.size() < 4 )
|
||||
continue;
|
||||
|
||||
if ( splineType != SplineTester::Cubic )
|
||||
{
|
||||
LocalSpline* spline;
|
||||
if ( splineType == SplineTester::Cardinal )
|
||||
{
|
||||
const QString name = QString( c.name ) + " Spline Cardinal";
|
||||
spline = new LocalSpline( QwtSplineLocal::Cardinal, name );
|
||||
}
|
||||
else
|
||||
{
|
||||
const QString name = QString( c.name ) + " Spline Akima";
|
||||
spline = new LocalSpline( QwtSplineLocal::Akima, name );
|
||||
}
|
||||
|
||||
if ( c.condition < 0 )
|
||||
{
|
||||
spline->setBoundaryType( QwtSpline::PeriodicPolygon );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( c.condition == QwtSplineC2::NotAKnot
|
||||
|| c.condition == QwtSplineC2::CubicRunout )
|
||||
{
|
||||
// requires C2 continuity
|
||||
continue;
|
||||
}
|
||||
|
||||
spline->setBoundaryType( QwtSpline::ConditionalBoundaries );
|
||||
spline->setBoundaryConditions( c.condition,
|
||||
conditions[i].valueBegin, c.valueEnd );
|
||||
}
|
||||
|
||||
SplineTester tester;
|
||||
tester.testSplineC1( spline, points );
|
||||
|
||||
delete spline;
|
||||
}
|
||||
else
|
||||
{
|
||||
const QString name = QString( c.name ) + " Spline Cubic";
|
||||
|
||||
CubicSpline spline( name );
|
||||
if ( conditions[i].condition < 0 )
|
||||
{
|
||||
spline.setBoundaryType( QwtSpline::PeriodicPolygon );
|
||||
}
|
||||
else
|
||||
{
|
||||
spline.setBoundaryType( QwtSpline::ConditionalBoundaries );
|
||||
spline.setBoundaryConditions( conditions[i].condition,
|
||||
conditions[i].valueBegin, conditions[i].valueEnd );
|
||||
}
|
||||
|
||||
SplineTester tester;
|
||||
tester.testSplineC2( &spline, points );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void testSplines( const QPolygonF& points )
|
||||
{
|
||||
testSplines( SplineTester::Cardinal, points );
|
||||
testSplines( SplineTester::Akima, points );
|
||||
testSplines( SplineTester::Cubic, points );
|
||||
}
|
||||
|
||||
static void testSplines()
|
||||
{
|
||||
QPolygonF points;
|
||||
|
||||
// 3 points
|
||||
|
||||
points << QPointF( 10, 50 ) << QPointF( 60, 30 ) << QPointF( 82, 50 );
|
||||
|
||||
testSplines( points );
|
||||
|
||||
// 4 points
|
||||
|
||||
points.clear();
|
||||
points << QPointF( 10, 50 ) << QPointF( 60, 30 )
|
||||
<< QPointF( 70, 5 ) << QPointF( 82, 50 );
|
||||
|
||||
testSplines( points );
|
||||
|
||||
// 5 points
|
||||
points.clear();
|
||||
points << QPointF( 10, 50 ) << QPointF( 20, 20 ) << QPointF( 60, 30 )
|
||||
<< QPointF( 70, 5 ) << QPointF( 82, 50 );
|
||||
|
||||
testSplines( points );
|
||||
|
||||
// 12 points
|
||||
|
||||
points.clear();
|
||||
points << QPointF( 10, 50 ) << QPointF( 20, 90 ) << QPointF( 25, 60 )
|
||||
<< QPointF( 35, 38 ) << QPointF( 42, 40 ) << QPointF( 55, 60 )
|
||||
<< QPointF( 60, 50 ) << QPointF( 65, 80 ) << QPointF( 73, 30 )
|
||||
<< QPointF( 82, 30 ) << QPointF( 87, 40 ) << QPointF( 95, 50 );
|
||||
|
||||
testSplines( points );
|
||||
|
||||
// many points
|
||||
points.clear();
|
||||
|
||||
const double x1 = 10.0;
|
||||
const double x2 = 1000.0;
|
||||
const double y1 = -10000.0;
|
||||
const double y2 = 10000.0;
|
||||
|
||||
points += QPointF( x1, y1 );
|
||||
|
||||
const int n = 100;
|
||||
const double dx = ( x2 - x1 ) / n;
|
||||
const int mod = y2 - y1;
|
||||
for ( int i = 1; i < n - 1; i++ )
|
||||
{
|
||||
const double r = qwtRand() % mod;
|
||||
points += QPointF( x1 + i * dx, y1 + r );
|
||||
}
|
||||
points += QPointF( x2, y1 );
|
||||
|
||||
testSplines( points );
|
||||
}
|
||||
|
||||
static void testPaths( const char* prompt, const QwtSpline& spline,
|
||||
const QPolygonF& points1, const QPolygonF& points2 )
|
||||
{
|
||||
const QPainterPath path1 = spline.painterPath( points1 );
|
||||
const QPainterPath path2 = spline.painterPath( points2 );
|
||||
|
||||
if ( path1 != path2 )
|
||||
{
|
||||
QString txt( "Parametric Spline" );
|
||||
if ( spline.boundaryType() != QwtSpline::ConditionalBoundaries )
|
||||
txt += "(closed)";
|
||||
txt += ": ";
|
||||
txt += prompt;
|
||||
txt += " => failed.";
|
||||
|
||||
qDebug() << qPrintable( txt );
|
||||
}
|
||||
}
|
||||
|
||||
static void testDuplicates()
|
||||
{
|
||||
QwtSplineLocal spline( QwtSplineLocal::Cardinal );
|
||||
spline.setParametrization( QwtSplineParametrization::ParameterChordal );
|
||||
|
||||
QPolygonF points;
|
||||
points += QPointF( 1, 6 );
|
||||
points += QPointF( 2, 7 );
|
||||
points += QPointF( 3, 5);
|
||||
points += QPointF( 2, 4 );
|
||||
points += QPointF( 0, 3 );
|
||||
|
||||
// inserting duplicates
|
||||
|
||||
QPolygonF points1;
|
||||
for ( int i = 0; i < points.size(); i++ )
|
||||
{
|
||||
points1 += points[i];
|
||||
points1 += points[i];
|
||||
}
|
||||
|
||||
testPaths( "Duplicates", spline, points, points1 );
|
||||
|
||||
spline.setBoundaryType( QwtSpline::ClosedPolygon );
|
||||
|
||||
testPaths( "Duplicates", spline, points, points1 );
|
||||
|
||||
QPolygonF points2 = points;
|
||||
points2.append( points[0] );
|
||||
testPaths( "First point also at End", spline, points, points2 );
|
||||
|
||||
QPolygonF points3 = points;
|
||||
points3.prepend( points.first() );
|
||||
testPaths( "First point twice", spline, points, points3 );
|
||||
|
||||
QPolygonF points4 = points;
|
||||
points4.append( points.last() );
|
||||
testPaths( "Last point twice", spline, points, points4 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
testSplines();
|
||||
testDuplicates();
|
||||
}
|
||||
18
tests/splinetest/splinetest.pro
Normal file
18
tests/splinetest/splinetest.pro
Normal file
@@ -0,0 +1,18 @@
|
||||
################################################################
|
||||
# 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( $${PWD}/../tests.pri )
|
||||
|
||||
CONFIG -= gui
|
||||
|
||||
TARGET = splinetest
|
||||
|
||||
SOURCES = \
|
||||
main.cpp
|
||||
|
||||
71
tests/tests.pri
Normal file
71
tests/tests.pri
Normal file
@@ -0,0 +1,71 @@
|
||||
################################################################
|
||||
# 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
|
||||
###################################################################
|
||||
|
||||
QWT_ROOT = $${PWD}/..
|
||||
include( $${QWT_ROOT}/qwtconfig.pri )
|
||||
include( $${QWT_ROOT}/qwtbuild.pri )
|
||||
include( $${QWT_ROOT}/qwtfunctions.pri )
|
||||
|
||||
QWT_OUT_ROOT = $${OUT_PWD}/../..
|
||||
|
||||
TEMPLATE = app
|
||||
|
||||
INCLUDEPATH += $${QWT_ROOT}/src
|
||||
DEPENDPATH += $${QWT_ROOT}/src
|
||||
|
||||
INCLUDEPATH += $${QWT_ROOT}/classincludes
|
||||
DEPENDPATH += $${QWT_ROOT}/classincludes
|
||||
|
||||
!debug_and_release {
|
||||
|
||||
DESTDIR = $${QWT_OUT_ROOT}/tests/bin
|
||||
}
|
||||
else {
|
||||
CONFIG(debug, debug|release) {
|
||||
|
||||
DESTDIR = $${QWT_OUT_ROOT}/tests/bin_debug
|
||||
}
|
||||
else {
|
||||
|
||||
DESTDIR = $${QWT_OUT_ROOT}/tests/bin
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QMAKE_RPATHDIR *= $${QWT_ROOT}/lib
|
||||
qwtAddLibrary($${QWT_OUT_ROOT}/lib, qwt)
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||
|
||||
QT += printsupport
|
||||
QT += concurrent
|
||||
}
|
||||
|
||||
contains(QWT_CONFIG, QwtOpenGL ) {
|
||||
|
||||
QT += opengl
|
||||
}
|
||||
else {
|
||||
|
||||
DEFINES += QWT_NO_OPENGL
|
||||
}
|
||||
|
||||
contains(QWT_CONFIG, QwtSvg) {
|
||||
|
||||
QT += svg
|
||||
}
|
||||
else {
|
||||
|
||||
DEFINES += QWT_NO_SVG
|
||||
}
|
||||
|
||||
|
||||
contains(QWT_CONFIG, QwtDll) {
|
||||
DEFINES += QT_DLL QWT_DLL
|
||||
}
|
||||
16
tests/tests.pro
Normal file
16
tests/tests.pro
Normal file
@@ -0,0 +1,16 @@
|
||||
################################################################
|
||||
# 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( $${PWD}/../qwtconfig.pri )
|
||||
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += \
|
||||
splinetest \
|
||||
splineprof
|
||||
Reference in New Issue
Block a user