Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "qwt_math.h"
00011 #include "qwt_spline.h"
00012 #include "qwt_curve_fitter.h"
00013
00015 QwtCurveFitter::QwtCurveFitter()
00016 {
00017 }
00018
00020 QwtCurveFitter::~QwtCurveFitter()
00021 {
00022 }
00023
00024 class QwtSplineCurveFitter::PrivateData
00025 {
00026 public:
00027 PrivateData():
00028 fitMode(QwtSplineCurveFitter::Auto),
00029 splineSize(250)
00030 {
00031 }
00032
00033 QwtSpline spline;
00034 QwtSplineCurveFitter::FitMode fitMode;
00035 int splineSize;
00036 };
00037
00039 QwtSplineCurveFitter::QwtSplineCurveFitter()
00040 {
00041 d_data = new PrivateData;
00042 }
00043
00045 QwtSplineCurveFitter::~QwtSplineCurveFitter()
00046 {
00047 delete d_data;
00048 }
00049
00056 void QwtSplineCurveFitter::setFitMode(FitMode mode)
00057 {
00058 d_data->fitMode = mode;
00059 }
00060
00065 QwtSplineCurveFitter::FitMode QwtSplineCurveFitter::fitMode() const
00066 {
00067 return d_data->fitMode;
00068 }
00069
00070 void QwtSplineCurveFitter::setSpline(const QwtSpline &spline)
00071 {
00072 d_data->spline = spline;
00073 d_data->spline.reset();
00074 }
00075
00076 const QwtSpline &QwtSplineCurveFitter::spline() const
00077 {
00078 return d_data->spline;
00079 }
00080
00081 QwtSpline &QwtSplineCurveFitter::spline()
00082 {
00083 return d_data->spline;
00084 }
00085
00086 void QwtSplineCurveFitter::setSplineSize(int splineSize)
00087 {
00088 d_data->splineSize = qwtMax(splineSize, 10);
00089 }
00090
00091 int QwtSplineCurveFitter::splineSize() const
00092 {
00093 return d_data->splineSize;
00094 }
00095
00102 #if QT_VERSION < 0x040000
00103 QwtArray<QwtDoublePoint> QwtSplineCurveFitter::fitCurve(
00104 const QwtArray<QwtDoublePoint> & points) const
00105 #else
00106 QPolygonF QwtSplineCurveFitter::fitCurve(const QPolygonF &points) const
00107 #endif
00108 {
00109 const int size = (int)points.size();
00110 if ( size <= 2 )
00111 return points;
00112
00113 FitMode fitMode = d_data->fitMode;
00114 if ( fitMode == Auto )
00115 {
00116 fitMode = Spline;
00117
00118 const QwtDoublePoint *p = points.data();
00119 for ( int i = 1; i < size; i++ )
00120 {
00121 if ( p[i].x() <= p[i-1].x() )
00122 {
00123 fitMode = ParametricSpline;
00124 break;
00125 }
00126 };
00127 }
00128
00129 if ( fitMode == ParametricSpline )
00130 return fitParametric(points);
00131 else
00132 return fitSpline(points);
00133 }
00134
00135 #if QT_VERSION < 0x040000
00136 QwtArray<QwtDoublePoint> QwtSplineCurveFitter::fitSpline(
00137 const QwtArray<QwtDoublePoint> &points) const
00138 #else
00139 QPolygonF QwtSplineCurveFitter::fitSpline(
00140 const QPolygonF &points) const
00141 #endif
00142 {
00143 d_data->spline.setPoints(points);
00144 if ( !d_data->spline.isValid() )
00145 return points;
00146
00147 #if QT_VERSION < 0x040000
00148 QwtArray<QwtDoublePoint> fittedPoints(d_data->splineSize);
00149 #else
00150 QPolygonF fittedPoints(d_data->splineSize);
00151 #endif
00152
00153 const double x1 = points[0].x();
00154 const double x2 = points[int(points.size() - 1)].x();
00155 const double dx = x2 - x1;
00156 const double delta = dx / (d_data->splineSize - 1);
00157
00158 for (int i = 0; i < d_data->splineSize; i++)
00159 {
00160 QwtDoublePoint &p = fittedPoints[i];
00161
00162 const double v = x1 + i * delta;
00163 const double sv = d_data->spline.value(v);
00164
00165 p.setX(qRound(v));
00166 p.setY(qRound(sv));
00167 }
00168 d_data->spline.reset();
00169
00170 return fittedPoints;
00171 }
00172
00173 #if QT_VERSION < 0x040000
00174 QwtArray<QwtDoublePoint> QwtSplineCurveFitter::fitParametric(
00175 const QwtArray<QwtDoublePoint> &points) const
00176 #else
00177 QPolygonF QwtSplineCurveFitter::fitParametric(
00178 const QPolygonF &points) const
00179 #endif
00180 {
00181 int i;
00182 const int size = points.size();
00183
00184 #if QT_VERSION < 0x040000
00185 QwtArray<QwtDoublePoint> fittedPoints(d_data->splineSize);
00186 QwtArray<QwtDoublePoint> splinePointsX(size);
00187 QwtArray<QwtDoublePoint> splinePointsY(size);
00188 #else
00189 QPolygonF fittedPoints(d_data->splineSize);
00190 QPolygonF splinePointsX(size);
00191 QPolygonF splinePointsY(size);
00192 #endif
00193
00194 const QwtDoublePoint *p = points.data();
00195 QwtDoublePoint *spX = splinePointsX.data();
00196 QwtDoublePoint *spY = splinePointsY.data();
00197
00198 double param = 0.0;
00199 for (i = 0; i < size; i++)
00200 {
00201 const double x = p[i].x();
00202 const double y = p[i].y();
00203 if ( i > 0 )
00204 {
00205 const double delta = sqrt( qwtSqr(x - spX[i-1].y())
00206 + qwtSqr( y - spY[i-1].y() ) );
00207 param += qwtMax(delta, 1.0);
00208 }
00209 spX[i].setX(param);
00210 spX[i].setY(x);
00211 spY[i].setX(param);
00212 spY[i].setY(y);
00213 }
00214
00215 d_data->spline.setPoints(splinePointsX);
00216 if ( !d_data->spline.isValid() )
00217 return points;
00218
00219 const double deltaX =
00220 splinePointsX[size - 1].x() / (d_data->splineSize-1);
00221 for (i = 0; i < d_data->splineSize; i++)
00222 {
00223 const double dtmp = i * deltaX;
00224 fittedPoints[i].setX(qRound(d_data->spline.value(dtmp)));
00225 }
00226
00227 d_data->spline.setPoints(splinePointsY);
00228 if ( !d_data->spline.isValid() )
00229 return points;
00230
00231 const double deltaY =
00232 splinePointsY[size - 1].x() / (d_data->splineSize-1);
00233 for (i = 0; i < d_data->splineSize; i++)
00234 {
00235 const double dtmp = i * deltaY;
00236 fittedPoints[i].setY(qRound(d_data->spline.value(dtmp)));
00237 }
00238
00239 return fittedPoints;
00240 }