source: ntrip/trunk/BNC/qwt/qwt_matrix_raster_data.cpp@ 9274

Last change on this file since 9274 was 8127, checked in by stoecker, 8 years ago

update qwt and qwtpolar, many QT5 fixes (unfinished)

File size: 7.8 KB
RevLine 
[4271]1/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10#include "qwt_matrix_raster_data.h"
11#include <qnumeric.h>
12#include <qmath.h>
13
14class QwtMatrixRasterData::PrivateData
15{
16public:
17 PrivateData():
18 resampleMode(QwtMatrixRasterData::NearestNeighbour),
19 numColumns(0)
20 {
21 }
22
[8127]23 inline double value(int row, int col) const
[4271]24 {
25 return values.data()[ row * numColumns + col ];
26 }
27
28 QwtMatrixRasterData::ResampleMode resampleMode;
29
30 QVector<double> values;
[8127]31 int numColumns;
32 int numRows;
[4271]33
34 double dx;
35 double dy;
36};
37
38//! Constructor
39QwtMatrixRasterData::QwtMatrixRasterData()
40{
41 d_data = new PrivateData();
42 update();
43}
44
45//! Destructor
46QwtMatrixRasterData::~QwtMatrixRasterData()
47{
48 delete d_data;
49}
50
51/*!
52 \brief Set the resampling algorithm
53
54 \param mode Resampling mode
55 \sa resampleMode(), value()
56*/
[8127]57void QwtMatrixRasterData::setResampleMode( ResampleMode mode )
[4271]58{
59 d_data->resampleMode = mode;
60}
61
62/*!
63 \return resampling algorithm
64 \sa setResampleMode(), value()
65*/
66QwtMatrixRasterData::ResampleMode QwtMatrixRasterData::resampleMode() const
67{
68 return d_data->resampleMode;
69}
70
71/*!
72 \brief Assign the bounding interval for an axis
73
74 Setting the bounding intervals for the X/Y axis is mandatory
75 to define the positions for the values of the value matrix.
76 The interval in Z direction defines the possible range for
77 the values in the matrix, what is f.e used by QwtPlotSpectrogram
78 to map values to colors. The Z-interval might be the bounding
79 interval of the values in the matrix, but usually it isn't.
80 ( f.e a interval of 0.0-100.0 for values in percentage )
81
82 \param axis X, Y or Z axis
83 \param interval Interval
84
85 \sa QwtRasterData::interval(), setValueMatrix()
86*/
87void QwtMatrixRasterData::setInterval(
88 Qt::Axis axis, const QwtInterval &interval )
89{
90 QwtRasterData::setInterval( axis, interval );
91 update();
92}
93
94/*!
95 \brief Assign a value matrix
96
97 The positions of the values are calculated by dividing
98 the bounding rectangle of the X/Y intervals into equidistant
99 rectangles ( pixels ). Each value corresponds to the center of
100 a pixel.
101
102 \param values Vector of values
103 \param numColumns Number of columns
104
105 \sa valueMatrix(), numColumns(), numRows(), setInterval()()
106*/
107void QwtMatrixRasterData::setValueMatrix(
[8127]108 const QVector<double> &values, int numColumns )
[4271]109{
110 d_data->values = values;
[8127]111 d_data->numColumns = qMax( numColumns, 0 );
[4271]112 update();
113}
114
115/*!
116 \return Value matrix
117 \sa setValueMatrix(), numColumns(), numRows(), setInterval()
118*/
119const QVector<double> QwtMatrixRasterData::valueMatrix() const
120{
121 return d_data->values;
122}
123
124/*!
[8127]125 \brief Change a single value in the matrix
126
127 \param row Row index
128 \param col Column index
129 \param value New value
130
131 \sa value(), setValueMatrix()
132*/
133void QwtMatrixRasterData::setValue( int row, int col, double value )
134{
135 if ( row >= 0 && row < d_data->numRows &&
136 col >= 0 && col < d_data->numColumns )
137 {
138 const int index = row * d_data->numColumns + col;
139 d_data->values.data()[ index ] = value;
140 }
141}
142
143/*!
[4271]144 \return Number of columns of the value matrix
145 \sa valueMatrix(), numRows(), setValueMatrix()
146*/
[8127]147int QwtMatrixRasterData::numColumns() const
[4271]148{
149 return d_data->numColumns;
150}
151
152/*!
153 \return Number of rows of the value matrix
154 \sa valueMatrix(), numColumns(), setValueMatrix()
155*/
[8127]156int QwtMatrixRasterData::numRows() const
[4271]157{
158 return d_data->numRows;
159}
160
161/*!
[8127]162 \brief Calculate the pixel hint
[4271]163
[8127]164 pixelHint() returns the geometry of a pixel, that can be used
165 to calculate the resolution and alignment of the plot item, that is
166 representing the data.
167
[4271]168 - NearestNeighbour\n
169 pixelHint() returns the surrounding pixel of the top left value
170 in the matrix.
171
172 - BilinearInterpolation\n
173 Returns an empty rectangle recommending
174 to render in target device ( f.e. screen ) resolution.
175
[8127]176 \param area Requested area, ignored
177 \return Calculated hint
178
[4271]179 \sa ResampleMode, setMatrix(), setInterval()
180*/
[8127]181QRectF QwtMatrixRasterData::pixelHint( const QRectF &area ) const
[4271]182{
[8127]183 Q_UNUSED( area )
184
[4271]185 QRectF rect;
186 if ( d_data->resampleMode == NearestNeighbour )
187 {
188 const QwtInterval intervalX = interval( Qt::XAxis );
189 const QwtInterval intervalY = interval( Qt::YAxis );
190 if ( intervalX.isValid() && intervalY.isValid() )
191 {
192 rect = QRectF( intervalX.minValue(), intervalY.minValue(),
193 d_data->dx, d_data->dy );
194 }
195 }
196
197 return rect;
198}
199
200/*!
201 \return the value at a raster position
202
203 \param x X value in plot coordinates
204 \param y Y value in plot coordinates
205
206 \sa ResampleMode
207*/
208double QwtMatrixRasterData::value( double x, double y ) const
209{
210 const QwtInterval xInterval = interval( Qt::XAxis );
211 const QwtInterval yInterval = interval( Qt::YAxis );
212
213 if ( !( xInterval.contains(x) && yInterval.contains(y) ) )
214 return qQNaN();
215
216 double value;
217
218 switch( d_data->resampleMode )
219 {
220 case BilinearInterpolation:
221 {
222 int col1 = qRound( (x - xInterval.minValue() ) / d_data->dx ) - 1;
223 int row1 = qRound( (y - yInterval.minValue() ) / d_data->dy ) - 1;
224 int col2 = col1 + 1;
225 int row2 = row1 + 1;
226
227 if ( col1 < 0 )
228 col1 = col2;
[8127]229 else if ( col2 >= static_cast<int>( d_data->numColumns ) )
[4271]230 col2 = col1;
231
232 if ( row1 < 0 )
233 row1 = row2;
[8127]234 else if ( row2 >= static_cast<int>( d_data->numRows ) )
[4271]235 row2 = row1;
236
237 const double v11 = d_data->value( row1, col1 );
238 const double v21 = d_data->value( row1, col2 );
239 const double v12 = d_data->value( row2, col1 );
240 const double v22 = d_data->value( row2, col2 );
241
242 const double x2 = xInterval.minValue() +
243 ( col2 + 0.5 ) * d_data->dx;
244 const double y2 = yInterval.minValue() +
245 ( row2 + 0.5 ) * d_data->dy;
246
247 const double rx = ( x2 - x ) / d_data->dx;
248 const double ry = ( y2 - y ) / d_data->dy;
249
250 const double vr1 = rx * v11 + ( 1.0 - rx ) * v21;
251 const double vr2 = rx * v12 + ( 1.0 - rx ) * v22;
252
253 value = ry * vr1 + ( 1.0 - ry ) * vr2;
254
255 break;
256 }
257 case NearestNeighbour:
258 default:
259 {
[8127]260 int row = int( (y - yInterval.minValue() ) / d_data->dy );
261 int col = int( (x - xInterval.minValue() ) / d_data->dx );
[4271]262
263 // In case of intervals, where the maximum is included
264 // we get out of bound for row/col, when the value for the
265 // maximum is requested. Instead we return the value
266 // from the last row/col
267
268 if ( row >= d_data->numRows )
269 row = d_data->numRows - 1;
270
271 if ( col >= d_data->numColumns )
272 col = d_data->numColumns - 1;
273
274 value = d_data->value( row, col );
275 }
276 }
277
278 return value;
279}
280
281void QwtMatrixRasterData::update()
282{
283 d_data->numRows = 0;
284 d_data->dx = 0.0;
285 d_data->dy = 0.0;
286
287 if ( d_data->numColumns > 0 )
288 {
289 d_data->numRows = d_data->values.size() / d_data->numColumns;
290
291 const QwtInterval xInterval = interval( Qt::XAxis );
292 const QwtInterval yInterval = interval( Qt::YAxis );
293 if ( xInterval.isValid() )
294 d_data->dx = xInterval.width() / d_data->numColumns;
295 if ( yInterval.isValid() )
296 d_data->dy = yInterval.width() / d_data->numRows;
297 }
298}
Note: See TracBrowser for help on using the repository browser.