qwt_matrix_raster_data.cpp
Go to the documentation of this file.
00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
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             // In case of intervals, where the maximum is included
00280             // we get out of bound for row/col, when the value for the
00281             // maximum is requested. Instead we return the value
00282             // from the last row/col
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 }


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56