qwt_polar_spectrogram.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * QwtPolar Widget Library
3  * Copyright (C) 2008 Uwe Rathmann
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the Qwt License, Version 1.0
7  *****************************************************************************/
8 
10 #include "qwt_polar.h"
11 #include "qwt_polar_plot.h"
12 #include "qwt_color_map.h"
13 #include "qwt_scale_map.h"
14 #include "qwt_raster_data.h"
15 #include "qwt_math.h"
16 #include "qwt_clipper.h"
17 
18 #include <qpainter.h>
19 #include <qpainterpath.h>
20 #include <qthread.h>
21 #include <qfuture.h>
22 #include <qtconcurrentrun.h>
23 
24 #if QT_VERSION < 0x050000
25 #include <qnumeric.h>
26 #endif
27 
29 {
30  public:
31  QPoint imagePos;
32  QRect rect;
33  QImage* image;
34 };
35 
37 {
38  public:
40  : data( NULL )
41  {
43  }
44 
46  {
47  delete data;
48  delete colorMap;
49  }
50 
53 
54  QwtPolarSpectrogram::PaintAttributes paintAttributes;
55 };
56 
59  : QwtPolarItem( QwtText( "Spectrogram" ) )
60 {
61  m_data = new PrivateData;
62 
65 
66  setZ( 20.0 );
67 }
68 
71 {
72  delete m_data;
73 }
74 
77 {
79 }
80 
92 {
93  if ( data != m_data->data )
94  {
95  delete m_data->data;
96  m_data->data = data;
97 
98  itemChanged();
99  }
100 }
101 
107 {
108  return m_data->data;
109 }
110 
123 {
124  if ( m_data->colorMap != colorMap )
125  {
126  delete m_data->colorMap;
128  }
129 
130  itemChanged();
131 }
132 
138 {
139  return m_data->colorMap;
140 }
141 
150 {
151  if ( on )
152  m_data->paintAttributes |= attribute;
153  else
154  m_data->paintAttributes &= ~attribute;
155 }
156 
163 {
164  return ( m_data->paintAttributes & attribute );
165 }
166 
177 void QwtPolarSpectrogram::draw( QPainter* painter,
178  const QwtScaleMap& azimuthMap, const QwtScaleMap& radialMap,
179  const QPointF& pole, double,
180  const QRectF& canvasRect ) const
181 {
182  const QRectF plotRect = plot()->plotRect( canvasRect.toRect() );
183  QRect imageRect = canvasRect.toRect();
184 
185  painter->save();
186 
187  painter->setClipRect( canvasRect );
188 
189  QPainterPath clipPathCanvas;
190  clipPathCanvas.addEllipse( plotRect );
191  painter->setClipPath( clipPathCanvas, Qt::IntersectClip );
192 
193  imageRect &= plotRect.toAlignedRect(); // outer rect
194 
195  const QwtInterval radialInterval = boundingInterval( QwtPolar::ScaleRadius );
196  if ( radialInterval.isValid() )
197  {
198  const double radius = radialMap.transform( radialInterval.maxValue() ) -
199  radialMap.transform( radialInterval.minValue() );
200 
201  QRectF clipRect( 0, 0, 2 * radius, 2 * radius );
202  clipRect.moveCenter( pole );
203 
204  imageRect &= clipRect.toRect(); // inner rect, we don't have points outside
205 
206  QPainterPath clipPathRadial;
207  clipPathRadial.addEllipse( clipRect );
208  painter->setClipPath( clipPathRadial, Qt::IntersectClip );
209  }
210 
211  const QImage image = renderImage( azimuthMap, radialMap, pole, imageRect );
212  painter->drawImage( imageRect, image );
213 
214  painter->restore();
215 }
216 
236  const QwtScaleMap& azimuthMap, const QwtScaleMap& radialMap,
237  const QPointF& pole, const QRect& rect ) const
238 {
239  if ( m_data->data == NULL || m_data->colorMap == NULL )
240  return QImage();
241 
242  QImage image( rect.size(), m_data->colorMap->format() == QwtColorMap::RGB
243  ? QImage::Format_ARGB32 : QImage::Format_Indexed8 );
244 
245  const QwtInterval intensityRange = m_data->data->interval( Qt::ZAxis );
246  if ( !intensityRange.isValid() )
247  return image;
248 
250  image.setColorTable( m_data->colorMap->colorTable256() );
251 
252  /*
253  For the moment we only announce the composition of the image by
254  calling initRaster(), but we don't pass any useful parameters.
255  ( How to map rect into something, that is useful to initialize a matrix
256  of values in polar coordinates ? )
257  */
258  m_data->data->initRaster( QRectF(), QSize() );
259 
260 
261 #if !defined( QT_NO_QFUTURE )
262  uint numThreads = renderThreadCount();
263 
264  if ( numThreads <= 0 )
265  numThreads = QThread::idealThreadCount();
266 
267  if ( numThreads <= 0 )
268  numThreads = 1;
269 
270  const int numRows = rect.height() / numThreads;
271 
272 
273  QVector< TileInfo > tileInfos;
274  for ( uint i = 0; i < numThreads; i++ )
275  {
276  QRect tile( rect.x(), rect.y() + i * numRows, rect.width(), numRows );
277  if ( i == numThreads - 1 )
278  tile.setHeight( rect.height() - i * numRows );
279 
280  TileInfo tileInfo;
281  tileInfo.imagePos = rect.topLeft();
282  tileInfo.rect = tile;
283  tileInfo.image = &image;
284 
285  tileInfos += tileInfo;
286  }
287 
288  QVector< QFuture< void > > futures;
289  for ( int i = 0; i < tileInfos.size(); i++ )
290  {
291  if ( i == tileInfos.size() - 1 )
292  {
293  renderTileInfo( azimuthMap, radialMap, pole, &tileInfos[i] );
294  }
295  else
296  {
297  futures += QtConcurrent::run(
298 #if QT_VERSION >= 0x060000
300 #else
302 #endif
303  azimuthMap, radialMap, pole, &tileInfos[i] );
304  }
305  }
306 
307  for ( int i = 0; i < futures.size(); i++ )
308  futures[i].waitForFinished();
309 
310 #else
311  renderTile( azimuthMap, radialMap, pole, rect.topLeft(), rect, &image );
312 #endif
313 
315 
316  return image;
317 }
318 
320  const QwtScaleMap& azimuthMap, const QwtScaleMap& radialMap,
321  const QPointF& pole, TileInfo* tileInfo ) const
322 {
323  renderTile( azimuthMap, radialMap, pole,
324  tileInfo->imagePos, tileInfo->rect, tileInfo->image );
325 }
326 
344  const QwtScaleMap& azimuthMap, const QwtScaleMap& radialMap,
345  const QPointF& pole, const QPoint& imagePos,
346  const QRect& tile, QImage* image ) const
347 {
348  const QwtInterval intensityRange = m_data->data->interval( Qt::ZAxis );
349  if ( !intensityRange.isValid() )
350  return;
351 
352  const bool doFastAtan = testPaintAttribute( ApproximatedAtan );
353 
354  const int y0 = imagePos.y();
355  const int y1 = tile.top();
356  const int y2 = tile.bottom();
357 
358  const int x0 = imagePos.x();
359  const int x1 = tile.left();
360  const int x2 = tile.right();
361 
362  if ( m_data->colorMap->format() == QwtColorMap::RGB )
363  {
364  for ( int y = y1; y <= y2; y++ )
365  {
366  const double dy = pole.y() - y;
367  const double dy2 = qwtSqr( dy );
368 
369  QRgb* line = reinterpret_cast< QRgb* >( image->scanLine( y - y0 ) );
370  line += x1 - x0;
371 
372  for ( int x = x1; x <= x2; x++ )
373  {
374  const double dx = x - pole.x();
375 
376  double a = doFastAtan ? qwtFastAtan2( dy, dx ) : qAtan2( dy, dx );
377 
378  if ( a < 0.0 )
379  a += 2 * M_PI;
380 
381  if ( a < azimuthMap.p1() )
382  a += 2 * M_PI;
383 
384  const double r = qSqrt( qwtSqr( dx ) + dy2 );
385 
386  const double azimuth = azimuthMap.invTransform( a );
387  const double radius = radialMap.invTransform( r );
388 
389  const double value = m_data->data->value( azimuth, radius );
390  if ( qIsNaN( value ) )
391  {
392  *line++ = 0u;
393  }
394  else
395  {
396  *line++ = m_data->colorMap->rgb( intensityRange, value );
397  }
398  }
399  }
400  }
401  else if ( m_data->colorMap->format() == QwtColorMap::Indexed )
402  {
403  for ( int y = y1; y <= y2; y++ )
404  {
405  const double dy = pole.y() - y;
406  const double dy2 = qwtSqr( dy );
407 
408  unsigned char* line = image->scanLine( y - y0 );
409  line += x1 - x0;
410  for ( int x = x1; x <= x2; x++ )
411  {
412  const double dx = x - pole.x();
413 
414  double a = doFastAtan ? qwtFastAtan2( dy, dx ) : qAtan2( dy, dx );
415  if ( a < 0.0 )
416  a += 2 * M_PI;
417  if ( a < azimuthMap.p1() )
418  a += 2 * M_PI;
419 
420  const double r = qSqrt( qwtSqr( dx ) + dy2 );
421 
422  const double azimuth = azimuthMap.invTransform( a );
423  const double radius = radialMap.invTransform( r );
424 
425  const double value = m_data->data->value( azimuth, radius );
426 
427  const uint index = m_data->colorMap->colorIndex( 256, intensityRange, value );
428  *line++ = static_cast< unsigned char >( index );
429  }
430  }
431  }
432 }
433 
444 {
445  if ( scaleId == QwtPolar::ScaleRadius )
446  return m_data->data->interval( Qt::YAxis );
447 
448  return QwtPolarItem::boundingInterval( scaleId );
449 }
QwtInterval::isValid
bool isValid() const
Definition: qwt_interval.h:210
QwtPolarSpectrogram::colorMap
const QwtColorMap * colorMap() const
Definition: qwt_polar_spectrogram.cpp:137
QwtPolarItem::setItemAttribute
void setItemAttribute(ItemAttribute, bool on=true)
Definition: qwt_polar_item.cpp:201
QwtPolarItem::AutoScale
@ AutoScale
Definition: qwt_polar_item.h:83
qwtSqr
double qwtSqr(double x)
Return the square of a number.
Definition: qwt_math.h:195
QwtScaleMap::invTransform
double invTransform(double p) const
Definition: qwt_scale_map.h:154
QwtPolarItem::Legend
@ Legend
The item is represented on the legend.
Definition: qwt_polar_item.h:77
QwtLinearColorMap
QwtLinearColorMap builds a color map from color stops.
Definition: qwt_color_map.h:98
QwtRasterData::initRaster
virtual void initRaster(const QRectF &, const QSize &raster)
Initialize a raster.
Definition: qwt_raster_data.cpp:221
QwtColorMap::colorTable256
virtual QVector< QRgb > colorTable256() const
Definition: qwt_color_map.cpp:304
QwtPolarSpectrogram::data
const QwtRasterData * data() const
Definition: qwt_polar_spectrogram.cpp:106
qwt_polar.h
QVector
Definition: qwt_clipper.h:23
QwtInterval::minValue
double minValue() const
Definition: qwt_interval.h:192
QwtPolarItem::boundingInterval
virtual QwtInterval boundingInterval(int scaleId) const
Definition: qwt_polar_item.cpp:381
QwtPolarItem::Rtti_PolarSpectrogram
@ Rtti_PolarSpectrogram
For QwtPolarSpectrogram.
Definition: qwt_polar_item.h:61
QwtRasterData::interval
virtual QwtInterval interval(Qt::Axis) const =0
QwtColorMap::Indexed
@ Indexed
Definition: qwt_color_map.h:60
qwtFastAtan2
double qwtFastAtan2(double y, double x)
Approximation of arc tangent ( error below 0,005 radians )
Definition: qwt_math.h:213
QwtPolarItem::renderThreadCount
uint renderThreadCount() const
Definition: qwt_polar_item.cpp:282
QwtPolarSpectrogram::setData
void setData(QwtRasterData *data)
Definition: qwt_polar_spectrogram.cpp:91
mqtt_test_proto.x
x
Definition: mqtt_test_proto.py:34
qwt_math.h
QwtPolarSpectrogram::setColorMap
void setColorMap(QwtColorMap *)
Definition: qwt_polar_spectrogram.cpp:122
mqtt_test_proto.y
y
Definition: mqtt_test_proto.py:35
QwtPolarItem::setZ
void setZ(double z)
Set the z value.
Definition: qwt_polar_item.cpp:142
QwtPolarSpectrogram::renderImage
virtual QImage renderImage(const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, const QPointF &pole, const QRect &rect) const
Render an image from the data and color map.
Definition: qwt_polar_spectrogram.cpp:235
M_PI
#define M_PI
Definition: qwt_math.h:56
QwtPolarSpectrogram::PrivateData::colorMap
QwtColorMap * colorMap
Definition: qwt_polar_spectrogram.cpp:52
qwt_raster_data.h
QwtColorMap::colorIndex
virtual uint colorIndex(int numColors, const QwtInterval &interval, double value) const
Map a value of a given interval into a color index.
Definition: qwt_color_map.cpp:278
QwtColorMap::RGB
@ RGB
The map is intended to map into RGB values.
Definition: qwt_color_map.h:48
QwtPolarSpectrogram::~QwtPolarSpectrogram
virtual ~QwtPolarSpectrogram()
Destructor.
Definition: qwt_polar_spectrogram.cpp:70
QwtScaleMap::p1
double p1() const
Definition: qwt_scale_map.h:99
qwt_clipper.h
QwtInterval
A class representing an interval.
Definition: qwt_interval.h:22
qwt_scale_map.h
QwtText
A class representing a text.
Definition: qwt_text.h:51
qwt_polar_spectrogram.h
QwtPolarItem::itemChanged
virtual void itemChanged()
Definition: qwt_polar_item.cpp:355
qwt_color_map.h
QwtPolarSpectrogram::renderTileInfo
void renderTileInfo(const QwtScaleMap &, const QwtScaleMap &, const QPointF &pole, TileInfo *) const
Definition: qwt_polar_spectrogram.cpp:319
QwtPolarSpectrogram::TileInfo::imagePos
QPoint imagePos
Definition: qwt_polar_spectrogram.cpp:37
QwtPolarItem
Base class for items on a polar plot.
Definition: qwt_polar_item.h:37
QwtPolarSpectrogram::renderTile
virtual void renderTile(const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, const QPointF &pole, const QPoint &imagePos, const QRect &tile, QImage *image) const
Render a sub-rectangle of an image.
Definition: qwt_polar_spectrogram.cpp:343
QwtPolarSpectrogram::testPaintAttribute
bool testPaintAttribute(PaintAttribute) const
Definition: qwt_polar_spectrogram.cpp:162
QwtScaleMap::transform
double transform(double s) const
Definition: qwt_scale_map.h:137
QwtPolarSpectrogram::TileInfo::image
QImage * image
Definition: qwt_polar_spectrogram.cpp:39
QwtColorMap::format
Format format() const
Definition: qwt_color_map.h:257
QwtScaleMap
A scale map.
Definition: qwt_scale_map.h:26
QwtPolarSpectrogram::rtti
virtual int rtti() const QWT_OVERRIDE
Definition: qwt_polar_spectrogram.cpp:76
QwtColorMap::rgb
virtual QRgb rgb(const QwtInterval &interval, double value) const =0
QwtRasterData::discardRaster
virtual void discardRaster()
Discard a raster.
Definition: qwt_raster_data.cpp:237
QwtPolarSpectrogram::PaintAttribute
PaintAttribute
Definition: qwt_polar_spectrogram.h:37
QwtPolarSpectrogram::TileInfo
Definition: qwt_polar_spectrogram.cpp:28
QwtPolarSpectrogram::PrivateData::paintAttributes
QwtPolarSpectrogram::PaintAttributes paintAttributes
Definition: qwt_polar_spectrogram.cpp:54
QwtRasterData::value
virtual double value(double x, double y) const =0
QwtPolar::ScaleRadius
@ ScaleRadius
Radial scale.
Definition: qwt_polar.h:83
QwtPolarSpectrogram::m_data
PrivateData * m_data
Definition: qwt_polar_spectrogram.h:85
QwtPolarSpectrogram::draw
virtual void draw(QPainter *painter, const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, const QPointF &pole, double radius, const QRectF &canvasRect) const QWT_OVERRIDE
Definition: qwt_polar_spectrogram.cpp:177
mqtt_test.data
dictionary data
Definition: mqtt_test.py:22
QwtRasterData
QwtRasterData defines an interface to any type of raster data.
Definition: qwt_raster_data.h:42
qwt_polar_plot.h
QwtInterval::maxValue
double maxValue() const
Definition: qwt_interval.h:198
QwtPolarPlot::plotRect
QRectF plotRect() const
Definition: qwt_polar_plot.cpp:1120
QwtColorMap
QwtColorMap is used to map values into colors.
Definition: qwt_color_map.h:37
QwtPolarSpectrogram::QwtPolarSpectrogram
QwtPolarSpectrogram()
Constructor.
Definition: qwt_polar_spectrogram.cpp:58
QwtPolarSpectrogram::PrivateData
Definition: qwt_polar_spectrogram.cpp:36
QwtPolarItem::plot
QwtPolarPlot * plot() const
Definition: qwt_polar_item.cpp:118
QwtPolarSpectrogram::PrivateData::~PrivateData
~PrivateData()
Definition: qwt_polar_spectrogram.cpp:45
QwtPolarSpectrogram::ApproximatedAtan
@ ApproximatedAtan
Definition: qwt_polar_spectrogram.h:44
QwtPolarSpectrogram::PrivateData::PrivateData
PrivateData()
Definition: qwt_polar_spectrogram.cpp:39
QwtPolarSpectrogram::PrivateData::data
QwtRasterData * data
Definition: qwt_polar_spectrogram.cpp:51
QwtPolarSpectrogram::TileInfo::rect
QRect rect
Definition: qwt_polar_spectrogram.cpp:38
QwtPolarSpectrogram::boundingInterval
virtual QwtInterval boundingInterval(int scaleId) const QWT_OVERRIDE
Definition: qwt_polar_spectrogram.cpp:443
QwtPolarSpectrogram::setPaintAttribute
void setPaintAttribute(PaintAttribute, bool on=true)
Definition: qwt_polar_spectrogram.cpp:149


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Aug 11 2024 02:24:24