Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "qwt_matrix_raster_data.h"
00011 #include <qnumeric.h>
00012 #include <qmath.h>
00013
00014 class QwtMatrixRasterData::PrivateData
00015 {
00016 public:
00017 PrivateData():
00018 resampleMode(QwtMatrixRasterData::NearestNeighbour),
00019 numColumns(0)
00020 {
00021 }
00022
00023 inline double value(int row, int col) const
00024 {
00025 return values.data()[ row * numColumns + col ];
00026 }
00027
00028 QwtInterval intervals[3];
00029 QwtMatrixRasterData::ResampleMode resampleMode;
00030
00031 QVector<double> values;
00032 int numColumns;
00033 int numRows;
00034
00035 double dx;
00036 double dy;
00037 };
00038
00040 QwtMatrixRasterData::QwtMatrixRasterData()
00041 {
00042 d_data = new PrivateData();
00043 update();
00044 }
00045
00047 QwtMatrixRasterData::~QwtMatrixRasterData()
00048 {
00049 delete d_data;
00050 }
00051
00058 void QwtMatrixRasterData::setResampleMode( ResampleMode mode )
00059 {
00060 d_data->resampleMode = mode;
00061 }
00062
00067 QwtMatrixRasterData::ResampleMode QwtMatrixRasterData::resampleMode() const
00068 {
00069 return d_data->resampleMode;
00070 }
00071
00088 void QwtMatrixRasterData::setInterval(
00089 Qt::Axis axis, const QwtInterval &interval )
00090 {
00091 if ( axis >= 0 && axis <= 2 )
00092 {
00093 d_data->intervals[axis] = interval;
00094 update();
00095 }
00096 }
00097
00102 QwtInterval QwtMatrixRasterData::interval( Qt::Axis axis ) const
00103 {
00104 if ( axis >= 0 && axis <= 2 )
00105 return d_data->intervals[ axis ];
00106
00107 return QwtInterval();
00108 }
00109
00123 void QwtMatrixRasterData::setValueMatrix(
00124 const QVector<double> &values, int numColumns )
00125 {
00126 d_data->values = values;
00127 d_data->numColumns = qMax( numColumns, 0 );
00128 update();
00129 }
00130
00135 const QVector<double> QwtMatrixRasterData::valueMatrix() const
00136 {
00137 return d_data->values;
00138 }
00139
00149 void QwtMatrixRasterData::setValue( int row, int col, double value )
00150 {
00151 if ( row >= 0 && row < d_data->numRows &&
00152 col >= 0 && col < d_data->numColumns )
00153 {
00154 const int index = row * d_data->numColumns + col;
00155 d_data->values.data()[ index ] = value;
00156 }
00157 }
00158
00163 int QwtMatrixRasterData::numColumns() const
00164 {
00165 return d_data->numColumns;
00166 }
00167
00172 int QwtMatrixRasterData::numRows() const
00173 {
00174 return d_data->numRows;
00175 }
00176
00197 QRectF QwtMatrixRasterData::pixelHint( const QRectF &area ) const
00198 {
00199 Q_UNUSED( area )
00200
00201 QRectF rect;
00202 if ( d_data->resampleMode == NearestNeighbour )
00203 {
00204 const QwtInterval intervalX = interval( Qt::XAxis );
00205 const QwtInterval intervalY = interval( Qt::YAxis );
00206 if ( intervalX.isValid() && intervalY.isValid() )
00207 {
00208 rect = QRectF( intervalX.minValue(), intervalY.minValue(),
00209 d_data->dx, d_data->dy );
00210 }
00211 }
00212
00213 return rect;
00214 }
00215
00224 double QwtMatrixRasterData::value( double x, double y ) const
00225 {
00226 const QwtInterval xInterval = interval( Qt::XAxis );
00227 const QwtInterval yInterval = interval( Qt::YAxis );
00228
00229 if ( !( xInterval.contains(x) && yInterval.contains(y) ) )
00230 return qQNaN();
00231
00232 double value;
00233
00234 switch( d_data->resampleMode )
00235 {
00236 case BilinearInterpolation:
00237 {
00238 int col1 = qRound( (x - xInterval.minValue() ) / d_data->dx ) - 1;
00239 int row1 = qRound( (y - yInterval.minValue() ) / d_data->dy ) - 1;
00240 int col2 = col1 + 1;
00241 int row2 = row1 + 1;
00242
00243 if ( col1 < 0 )
00244 col1 = col2;
00245 else if ( col2 >= static_cast<int>( d_data->numColumns ) )
00246 col2 = col1;
00247
00248 if ( row1 < 0 )
00249 row1 = row2;
00250 else if ( row2 >= static_cast<int>( d_data->numRows ) )
00251 row2 = row1;
00252
00253 const double v11 = d_data->value( row1, col1 );
00254 const double v21 = d_data->value( row1, col2 );
00255 const double v12 = d_data->value( row2, col1 );
00256 const double v22 = d_data->value( row2, col2 );
00257
00258 const double x2 = xInterval.minValue() +
00259 ( col2 + 0.5 ) * d_data->dx;
00260 const double y2 = yInterval.minValue() +
00261 ( row2 + 0.5 ) * d_data->dy;
00262
00263 const double rx = ( x2 - x ) / d_data->dx;
00264 const double ry = ( y2 - y ) / d_data->dy;
00265
00266 const double vr1 = rx * v11 + ( 1.0 - rx ) * v21;
00267 const double vr2 = rx * v12 + ( 1.0 - rx ) * v22;
00268
00269 value = ry * vr1 + ( 1.0 - ry ) * vr2;
00270
00271 break;
00272 }
00273 case NearestNeighbour:
00274 default:
00275 {
00276 int row = int( (y - yInterval.minValue() ) / d_data->dy );
00277 int col = int( (x - xInterval.minValue() ) / d_data->dx );
00278
00279
00280
00281
00282
00283
00284 if ( row >= d_data->numRows )
00285 row = d_data->numRows - 1;
00286
00287 if ( col >= d_data->numColumns )
00288 col = d_data->numColumns - 1;
00289
00290 value = d_data->value( row, col );
00291 }
00292 }
00293
00294 return value;
00295 }
00296
00297 void QwtMatrixRasterData::update()
00298 {
00299 d_data->numRows = 0;
00300 d_data->dx = 0.0;
00301 d_data->dy = 0.0;
00302
00303 if ( d_data->numColumns > 0 )
00304 {
00305 d_data->numRows = d_data->values.size() / d_data->numColumns;
00306
00307 const QwtInterval xInterval = interval( Qt::XAxis );
00308 const QwtInterval yInterval = interval( Qt::YAxis );
00309 if ( xInterval.isValid() )
00310 d_data->dx = xInterval.width() / d_data->numColumns;
00311 if ( yInterval.isValid() )
00312 d_data->dy = yInterval.width() / d_data->numRows;
00313 }
00314 }