qwt_matrix_raster_data.cpp
Go to the documentation of this file.
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 "qwt_interval.h"
12 
13 #include <qvector.h>
14 #include <qnumeric.h>
15 #include <qrect.h>
16 
17 static inline double qwtHermiteInterpolate(
18  double A, double B, double C, double D, double t )
19 {
20  const double t2 = t * t;
21  const double t3 = t2 * t;
22 
23  const double a = -A / 2.0 + ( 3.0 * B ) / 2.0 - ( 3.0 * C ) / 2.0 + D / 2.0;
24  const double b = A - ( 5.0 * B ) / 2.0 + 2.0 * C - D / 2.0;
25  const double c = -A / 2.0 + C / 2.0;
26  const double d = B;
27 
28  return a * t3 + b * t2 + c * t + d;
29 }
30 
31 static inline double qwtBicubicInterpolate(
32  double v00, double v10, double v20, double v30,
33  double v01, double v11, double v21, double v31,
34  double v02, double v12, double v22, double v32,
35  double v03, double v13, double v23, double v33,
36  double dx, double dy )
37 {
38  const double v0 = qwtHermiteInterpolate( v00, v10, v20, v30, dx );
39  const double v1 = qwtHermiteInterpolate( v01, v11, v21, v31, dx );
40  const double v2 = qwtHermiteInterpolate( v02, v12, v22, v32, dx );
41  const double v3 = qwtHermiteInterpolate( v03, v13, v23, v33, dx );
42 
43  return qwtHermiteInterpolate( v0, v1, v2, v3, dy );
44 }
45 
47 {
48 public:
51  numColumns(0)
52  {
53  }
54 
55  inline double value(int row, int col) const
56  {
57  return values.data()[ row * numColumns + col ];
58  }
59 
62 
65  int numRows;
66 
67  double dx;
68  double dy;
69 };
70 
73 {
74  d_data = new PrivateData();
75  update();
76 }
77 
80 {
81  delete d_data;
82 }
83 
91 {
92  d_data->resampleMode = mode;
93 }
94 
100 {
101  return d_data->resampleMode;
102 }
103 
121  Qt::Axis axis, const QwtInterval &interval )
122 {
123  if ( axis >= 0 && axis <= 2 )
124  {
125  d_data->intervals[axis] = interval;
126  update();
127  }
128 }
129 
135 {
136  if ( axis >= 0 && axis <= 2 )
137  return d_data->intervals[ axis ];
138 
139  return QwtInterval();
140 }
141 
156  const QVector<double> &values, int numColumns )
157 {
158  d_data->values = values;
159  d_data->numColumns = qMax( numColumns, 0 );
160  update();
161 }
162 
168 {
169  return d_data->values;
170 }
171 
181 void QwtMatrixRasterData::setValue( int row, int col, double value )
182 {
183  if ( row >= 0 && row < d_data->numRows &&
184  col >= 0 && col < d_data->numColumns )
185  {
186  const int index = row * d_data->numColumns + col;
187  d_data->values.data()[ index ] = value;
188  }
189 }
190 
196 {
197  return d_data->numColumns;
198 }
199 
205 {
206  return d_data->numRows;
207 }
208 
229 QRectF QwtMatrixRasterData::pixelHint( const QRectF &area ) const
230 {
231  Q_UNUSED( area )
232 
233  QRectF rect;
235  {
236  const QwtInterval intervalX = interval( Qt::XAxis );
237  const QwtInterval intervalY = interval( Qt::YAxis );
238  if ( intervalX.isValid() && intervalY.isValid() )
239  {
240  rect = QRectF( intervalX.minValue(), intervalY.minValue(),
241  d_data->dx, d_data->dy );
242  }
243  }
244 
245  return rect;
246 }
247 
256 double QwtMatrixRasterData::value( double x, double y ) const
257 {
258  const QwtInterval xInterval = interval( Qt::XAxis );
259  const QwtInterval yInterval = interval( Qt::YAxis );
260 
261  if ( !( xInterval.contains(x) && yInterval.contains(y) ) )
262  return qQNaN();
263 
264  double value;
265 
266  switch( d_data->resampleMode )
267  {
269  {
270  const double colF = ( x - xInterval.minValue() ) / d_data->dx;
271  const double rowF = ( y - yInterval.minValue() ) / d_data->dy;
272 
273  const int col = qRound( colF );
274  const int row = qRound( rowF );
275 
276  int col0 = col - 2;
277  int col1 = col - 1;
278  int col2 = col;
279  int col3 = col + 1;
280 
281  if ( col1 < 0 )
282  col1 = col2;
283 
284  if ( col0 < 0 )
285  col0 = col1;
286 
287  if ( col2 >= d_data->numColumns )
288  col2 = col1;
289 
290  if ( col3 >= d_data->numColumns )
291  col3 = col2;
292 
293  int row0 = row - 2;
294  int row1 = row - 1;
295  int row2 = row;
296  int row3 = row + 1;
297 
298  if ( row1 < 0 )
299  row1 = row2;
300 
301  if ( row0 < 0 )
302  row0 = row1;
303 
304  if ( row2 >= d_data->numRows )
305  row2 = row1;
306 
307  if ( row3 >= d_data->numRows )
308  row3 = row2;
309 
310  // First row
311  const double v00 = d_data->value( row0, col0 );
312  const double v10 = d_data->value( row0, col1 );
313  const double v20 = d_data->value( row0, col2 );
314  const double v30 = d_data->value( row0, col3 );
315 
316  // Second row
317  const double v01 = d_data->value( row1, col0 );
318  const double v11 = d_data->value( row1, col1 );
319  const double v21 = d_data->value( row1, col2 );
320  const double v31 = d_data->value( row1, col3 );
321 
322  // Third row
323  const double v02 = d_data->value( row2, col0 );
324  const double v12 = d_data->value( row2, col1 );
325  const double v22 = d_data->value( row2, col2 );
326  const double v32 = d_data->value( row2, col3 );
327 
328  // Fourth row
329  const double v03 = d_data->value( row3, col0 );
330  const double v13 = d_data->value( row3, col1 );
331  const double v23 = d_data->value( row3, col2 );
332  const double v33 = d_data->value( row3, col3 );
333 
334  value = qwtBicubicInterpolate(
335  v00, v10, v20, v30, v01, v11, v21, v31,
336  v02, v12, v22, v32, v03, v13, v23, v33,
337  colF - col + 0.5, rowF - row + 0.5 );
338 
339  break;
340  }
342  {
343  int col1 = qRound( ( x - xInterval.minValue() ) / d_data->dx ) - 1;
344  int row1 = qRound( ( y - yInterval.minValue() ) / d_data->dy ) - 1;
345  int col2 = col1 + 1;
346  int row2 = row1 + 1;
347 
348  if ( col1 < 0 )
349  col1 = col2;
350  else if ( col2 >= d_data->numColumns )
351  col2 = col1;
352 
353  if ( row1 < 0 )
354  row1 = row2;
355  else if ( row2 >= d_data->numRows )
356  row2 = row1;
357 
358  const double v11 = d_data->value( row1, col1 );
359  const double v21 = d_data->value( row1, col2 );
360  const double v12 = d_data->value( row2, col1 );
361  const double v22 = d_data->value( row2, col2 );
362 
363  const double x2 = xInterval.minValue() + ( col2 + 0.5 ) * d_data->dx;
364  const double y2 = yInterval.minValue() + ( row2 + 0.5 ) * d_data->dy;
365 
366  const double rx = ( x2 - x ) / d_data->dx;
367  const double ry = ( y2 - y ) / d_data->dy;
368 
369  const double vr1 = rx * v11 + ( 1.0 - rx ) * v21;
370  const double vr2 = rx * v12 + ( 1.0 - rx ) * v22;
371 
372  value = ry * vr1 + ( 1.0 - ry ) * vr2;
373 
374  break;
375  }
376  case NearestNeighbour:
377  default:
378  {
379  int row = int( ( y - yInterval.minValue() ) / d_data->dy );
380  int col = int( ( x - xInterval.minValue() ) / d_data->dx );
381 
382  // In case of intervals, where the maximum is included
383  // we get out of bound for row/col, when the value for the
384  // maximum is requested. Instead we return the value
385  // from the last row/col
386 
387  if ( row >= d_data->numRows )
388  row = d_data->numRows - 1;
389 
390  if ( col >= d_data->numColumns )
391  col = d_data->numColumns - 1;
392 
393  value = d_data->value( row, col );
394  }
395  }
396 
397  return value;
398 }
399 
401 {
402  d_data->numRows = 0;
403  d_data->dx = 0.0;
404  d_data->dy = 0.0;
405 
406  if ( d_data->numColumns > 0 )
407  {
409 
410  const QwtInterval xInterval = interval( Qt::XAxis );
411  const QwtInterval yInterval = interval( Qt::YAxis );
412  if ( xInterval.isValid() )
413  d_data->dx = xInterval.width() / d_data->numColumns;
414  if ( yInterval.isValid() )
415  d_data->dy = yInterval.width() / d_data->numRows;
416  }
417 }
virtual QwtInterval interval(Qt::Axis axis) const QWT_OVERRIDE QWT_FINAL
static double qwtBicubicInterpolate(double v00, double v10, double v20, double v30, double v01, double v11, double v21, double v31, double v02, double v12, double v22, double v32, double v03, double v13, double v23, double v33, double dx, double dy)
bool contains(double value) const
A class representing an interval.
Definition: qwt_interval.h:22
MQTTClient d
Definition: test10.c:1656
double minValue() const
Definition: qwt_interval.h:190
void setResampleMode(ResampleMode mode)
Set the resampling algorithm.
void setInterval(Qt::Axis, const QwtInterval &)
Assign the bounding interval for an axis.
ResampleMode
Resampling algorithm The default setting is NearestNeighbour;.
virtual double value(double x, double y) const QWT_OVERRIDE
double value(int row, int col) const
static double qwtHermiteInterpolate(double A, double B, double C, double D, double t)
virtual ~QwtMatrixRasterData()
Destructor.
A class representing a matrix of values as raster data.
bool isValid() const
Definition: qwt_interval.h:208
virtual QRectF pixelHint(const QRectF &) const QWT_OVERRIDE
Calculate the pixel hint.
void setValue(int row, int col, double value)
Change a single value in the matrix.
const QVector< double > valueMatrix() const
MQTTClient c
Definition: test10.c:1656
ResampleMode resampleMode() const
void setValueMatrix(const QVector< double > &values, int numColumns)
Assign a value matrix.
double width() const
Return the width of an interval.
Definition: qwt_interval.h:225
QwtMatrixRasterData()
Constructor.
QwtMatrixRasterData::ResampleMode resampleMode


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:10