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

Last change on this file since 7008 was 4271, checked in by mervart, 12 years ago
File size: 7.1 KB
Line 
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
23 inline double value(size_t row, size_t col) const
24 {
25 return values.data()[ row * numColumns + col ];
26 }
27
28 QwtMatrixRasterData::ResampleMode resampleMode;
29
30 QVector<double> values;
31 size_t numColumns;
32 size_t numRows;
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*/
57void QwtMatrixRasterData::setResampleMode(ResampleMode mode)
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(
108 const QVector<double> &values, size_t numColumns )
109{
110 d_data->values = values;
111 d_data->numColumns = numColumns;
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/*!
125 \return Number of columns of the value matrix
126 \sa valueMatrix(), numRows(), setValueMatrix()
127*/
128size_t QwtMatrixRasterData::numColumns() const
129{
130 return d_data->numColumns;
131}
132
133/*!
134 \return Number of rows of the value matrix
135 \sa valueMatrix(), numColumns(), setValueMatrix()
136*/
137size_t QwtMatrixRasterData::numRows() const
138{
139 return d_data->numRows;
140}
141
142/*!
143 \brief Pixel hint
144
145 - NearestNeighbour\n
146 pixelHint() returns the surrounding pixel of the top left value
147 in the matrix.
148
149 - BilinearInterpolation\n
150 Returns an empty rectangle recommending
151 to render in target device ( f.e. screen ) resolution.
152
153 \sa ResampleMode, setMatrix(), setInterval()
154*/
155QRectF QwtMatrixRasterData::pixelHint( const QRectF & ) const
156{
157 QRectF rect;
158 if ( d_data->resampleMode == NearestNeighbour )
159 {
160 const QwtInterval intervalX = interval( Qt::XAxis );
161 const QwtInterval intervalY = interval( Qt::YAxis );
162 if ( intervalX.isValid() && intervalY.isValid() )
163 {
164 rect = QRectF( intervalX.minValue(), intervalY.minValue(),
165 d_data->dx, d_data->dy );
166 }
167 }
168
169 return rect;
170}
171
172/*!
173 \return the value at a raster position
174
175 \param x X value in plot coordinates
176 \param y Y value in plot coordinates
177
178 \sa ResampleMode
179*/
180double QwtMatrixRasterData::value( double x, double y ) const
181{
182 const QwtInterval xInterval = interval( Qt::XAxis );
183 const QwtInterval yInterval = interval( Qt::YAxis );
184
185 if ( !( xInterval.contains(x) && yInterval.contains(y) ) )
186 return qQNaN();
187
188 double value;
189
190 switch( d_data->resampleMode )
191 {
192 case BilinearInterpolation:
193 {
194 int col1 = qRound( (x - xInterval.minValue() ) / d_data->dx ) - 1;
195 int row1 = qRound( (y - yInterval.minValue() ) / d_data->dy ) - 1;
196 int col2 = col1 + 1;
197 int row2 = row1 + 1;
198
199 if ( col1 < 0 )
200 col1 = col2;
201 else if ( col2 >= (int)d_data->numColumns )
202 col2 = col1;
203
204 if ( row1 < 0 )
205 row1 = row2;
206 else if ( row2 >= (int)d_data->numRows )
207 row2 = row1;
208
209 const double v11 = d_data->value( row1, col1 );
210 const double v21 = d_data->value( row1, col2 );
211 const double v12 = d_data->value( row2, col1 );
212 const double v22 = d_data->value( row2, col2 );
213
214 const double x2 = xInterval.minValue() +
215 ( col2 + 0.5 ) * d_data->dx;
216 const double y2 = yInterval.minValue() +
217 ( row2 + 0.5 ) * d_data->dy;
218
219 const double rx = ( x2 - x ) / d_data->dx;
220 const double ry = ( y2 - y ) / d_data->dy;
221
222 const double vr1 = rx * v11 + ( 1.0 - rx ) * v21;
223 const double vr2 = rx * v12 + ( 1.0 - rx ) * v22;
224
225 value = ry * vr1 + ( 1.0 - ry ) * vr2;
226
227 break;
228 }
229 case NearestNeighbour:
230 default:
231 {
232 uint row = uint( (y - yInterval.minValue() ) / d_data->dy );
233 uint col = uint( (x - xInterval.minValue() ) / d_data->dx );
234
235 // In case of intervals, where the maximum is included
236 // we get out of bound for row/col, when the value for the
237 // maximum is requested. Instead we return the value
238 // from the last row/col
239
240 if ( row >= d_data->numRows )
241 row = d_data->numRows - 1;
242
243 if ( col >= d_data->numColumns )
244 col = d_data->numColumns - 1;
245
246 value = d_data->value( row, col );
247 }
248 }
249
250 return value;
251}
252
253void QwtMatrixRasterData::update()
254{
255 d_data->numRows = 0;
256 d_data->dx = 0.0;
257 d_data->dy = 0.0;
258
259 if ( d_data->numColumns > 0 )
260 {
261 d_data->numRows = d_data->values.size() / d_data->numColumns;
262
263 const QwtInterval xInterval = interval( Qt::XAxis );
264 const QwtInterval yInterval = interval( Qt::YAxis );
265 if ( xInterval.isValid() )
266 d_data->dx = xInterval.width() / d_data->numColumns;
267 if ( yInterval.isValid() )
268 d_data->dy = yInterval.width() / d_data->numRows;
269 }
270}
Note: See TracBrowser for help on using the repository browser.