qwt_polar_curve.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
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 
9 #include "qwt_polar_curve.h"
10 #include "qwt_polar.h"
11 #include "qwt_painter.h"
12 #include "qwt_scale_map.h"
13 #include "qwt_math.h"
14 #include "qwt_symbol.h"
15 #include "qwt_legend.h"
16 #include "qwt_curve_fitter.h"
17 #include "qwt_clipper.h"
18 
19 #include <qpainter.h>
20 
21 static inline bool qwtInsidePole( const QwtScaleMap &map, double radius )
22 {
23  return map.isInverting() ? ( radius > map.s1() ) : ( radius < map.s1() );
24 }
25 
26 static int qwtVerifyRange( int size, int &i1, int &i2 )
27 {
28  if ( size < 1 )
29  return 0;
30 
31  i1 = qBound( 0, i1, size - 1 );
32  i2 = qBound( 0, i2, size - 1 );
33 
34  if ( i1 > i2 )
35  qSwap( i1, i2 );
36 
37  return ( i2 - i1 + 1 );
38 }
39 
41 {
42 public:
45  curveFitter( NULL )
46  {
47  symbol = new QwtSymbol();
48  pen = QPen( Qt::black );
49  }
50 
52  {
53  delete symbol;
54  delete curveFitter;
55  }
56 
58  const QwtSymbol *symbol;
59  QPen pen;
61 
63 };
64 
68 {
69  init();
70 }
71 
77  QwtPolarItem( title )
78 {
79  init();
80 }
81 
87  QwtPolarItem( QwtText( title ) )
88 {
89  init();
90 }
91 
94 {
95  delete d_series;
96  delete d_data;
97 }
98 
101 {
102  d_data = new PrivateData;
103  d_series = NULL;
104 
107  setZ( 20.0 );
108 
110 }
111 
114 {
116 }
117 
126 {
127  if ( on )
128  d_data->legendAttributes |= attribute;
129  else
130  d_data->legendAttributes &= ~attribute;
131 }
132 
142 {
143  return ( d_data->legendAttributes & attribute );
144 }
145 
153 {
154  if ( style != d_data->style )
155  {
156  d_data->style = style;
157  itemChanged();
158  }
159 }
160 
166 {
167  return d_data->style;
168 }
169 
176 {
177  if ( symbol != d_data->symbol )
178  {
179  delete d_data->symbol;
180  d_data->symbol = symbol;
181  itemChanged();
182  }
183 }
184 
190 {
191  return d_data->symbol;
192 }
193 
199 void QwtPolarCurve::setPen( const QPen &pen )
200 {
201  if ( pen != d_data->pen )
202  {
203  d_data->pen = pen;
204  itemChanged();
205  }
206 }
207 
212 const QPen& QwtPolarCurve::pen() const
213 {
214  return d_data->pen;
215 }
216 
226 {
227  if ( d_series != data )
228  {
229  delete d_series;
230  d_series = data;
231  itemChanged();
232  }
233 }
234 
247 {
248  if ( curveFitter != d_data->curveFitter )
249  {
250  delete d_data->curveFitter;
252 
253  itemChanged();
254  }
255 }
256 
262 {
263  return d_data->curveFitter;
264 }
265 
276 void QwtPolarCurve::draw( QPainter *painter,
277  const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap,
278  const QPointF &pole, double radius,
279  const QRectF &canvasRect ) const
280 {
281  Q_UNUSED( radius );
282  Q_UNUSED( canvasRect );
283 
284  draw( painter, azimuthMap, radialMap, pole, 0, -1 );
285 }
286 
299 void QwtPolarCurve::draw( QPainter *painter,
300  const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap,
301  const QPointF &pole, int from, int to ) const
302 {
303  if ( !painter || dataSize() <= 0 )
304  return;
305 
306  if ( to < 0 )
307  to = dataSize() - 1;
308 
309  if ( qwtVerifyRange( dataSize(), from, to ) > 0 )
310  {
311  painter->save();
312  painter->setPen( d_data->pen );
313 
314  drawCurve( painter, d_data->style,
315  azimuthMap, radialMap, pole, from, to );
316 
317  painter->restore();
318 
319  if ( d_data->symbol->style() != QwtSymbol::NoSymbol )
320  {
321  painter->save();
322  drawSymbols( painter, *d_data->symbol,
323  azimuthMap, radialMap, pole, from, to );
324  painter->restore();
325  }
326  }
327 }
328 
341 void QwtPolarCurve::drawCurve( QPainter *painter, int style,
342  const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap,
343  const QPointF &pole, int from, int to ) const
344 {
345  switch ( style )
346  {
347  case Lines:
348  drawLines( painter, azimuthMap, radialMap, pole, from, to );
349  break;
350  case NoCurve:
351  default:
352  break;
353  }
354 }
355 
367 void QwtPolarCurve::drawLines( QPainter *painter,
368  const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap,
369  const QPointF &pole, int from, int to ) const
370 {
371  int size = to - from + 1;
372  if ( size <= 0 )
373  return;
374 
375  QPolygonF polyline;
376 
377  if ( d_data->curveFitter )
378  {
379  QPolygonF points( size );
380  for ( int j = from; j <= to; j++ )
381  {
382  const QwtPointPolar point = sample( j );
383  points[j - from] = QPointF( point.azimuth(), point.radius() );
384  }
385 
386  points = d_data->curveFitter->fitCurve( points );
387 
388  polyline.resize( points.size() );
389 
390  QPointF *polylineData = polyline.data();
391  QPointF *pointsData = points.data();
392 
393  for ( int i = 0; i < points.size(); i++ )
394  {
395  const QwtPointPolar point( pointsData[i].x(), pointsData[i].y() );
396 
397  double r = radialMap.transform( point.radius() );
398  const double a = azimuthMap.transform( point.azimuth() );
399 
400  polylineData[i] = qwtPolar2Pos( pole, r, a );
401  }
402  }
403  else
404  {
405  polyline.resize( size );
406  QPointF *polylineData = polyline.data();
407 
408  for ( int i = from; i <= to; i++ )
409  {
410  QwtPointPolar point = sample( i );
411  if ( !qwtInsidePole( radialMap, point.radius() ) )
412  {
413  double r = radialMap.transform( point.radius() );
414  const double a = azimuthMap.transform( point.azimuth() );
415  polylineData[i - from] = qwtPolar2Pos( pole, r, a );
416  }
417  else
418  {
419  polylineData[i - from] = pole;
420  }
421  }
422  }
423 
424  QRectF clipRect;
425  if ( painter->hasClipping() )
426  {
427  clipRect = painter->clipRegion().boundingRect();
428  }
429  else
430  {
431  clipRect = painter->window();
432  if ( !clipRect.isEmpty() )
433  clipRect = painter->transform().inverted().mapRect( clipRect );
434  }
435 
436  if ( !clipRect.isEmpty() )
437  {
438  double off = qCeil( qMax( qreal( 1.0 ), painter->pen().widthF() ) );
439  clipRect = clipRect.toRect().adjusted( -off, -off, off, off );
440  QwtClipper::clipPolygonF( clipRect, polyline );
441  }
442 
443  QwtPainter::drawPolyline( painter, polyline );
444 }
445 
459 void QwtPolarCurve::drawSymbols( QPainter *painter, const QwtSymbol &symbol,
460  const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap,
461  const QPointF &pole, int from, int to ) const
462 {
463  painter->setBrush( symbol.brush() );
464  painter->setPen( symbol.pen() );
465 
466  const int chunkSize = 500;
467 
468  for ( int i = from; i <= to; i += chunkSize )
469  {
470  const int n = qMin( chunkSize, to - i + 1 );
471 
472  QPolygonF points;
473  for ( int j = 0; j < n; j++ )
474  {
475  const QwtPointPolar point = sample( i + j );
476 
477  if ( !qwtInsidePole( radialMap, point.radius() ) )
478  {
479  const double r = radialMap.transform( point.radius() );
480  const double a = azimuthMap.transform( point.azimuth() );
481 
482  points += qwtPolar2Pos( pole, r, a );
483  }
484  else
485  {
486  points += pole;
487  }
488  }
489 
490  if ( points.size() > 0 )
491  symbol.drawSymbols( painter, points );
492  }
493 }
494 
500 {
501  return d_series->size();
502 }
503 
514  const QSizeF &size ) const
515 {
516  Q_UNUSED( index );
517 
518  if ( size.isEmpty() )
519  return QwtGraphic();
520 
521  QwtGraphic graphic;
522  graphic.setDefaultSize( size );
524 
525  QPainter painter( &graphic );
526  painter.setRenderHint( QPainter::Antialiasing,
528 
529  if ( d_data->legendAttributes == 0 )
530  {
531  QBrush brush;
532 
533  if ( style() != QwtPolarCurve::NoCurve )
534  {
535  brush = QBrush( pen().color() );
536  }
537  else if ( d_data->symbol &&
539  {
540  brush = QBrush( d_data->symbol->pen().color() );
541  }
542 
543  if ( brush.style() != Qt::NoBrush )
544  {
545  QRectF r( 0, 0, size.width(), size.height() );
546  painter.fillRect( r, brush );
547  }
548  }
549 
551  {
552  if ( pen() != Qt::NoPen )
553  {
554  QPen pn = pen();
555  pn.setCapStyle( Qt::FlatCap );
556 
557  painter.setPen( pn );
558 
559  const double y = 0.5 * size.height();
560  QwtPainter::drawLine( &painter, 0.0, y, size.width(), y );
561  }
562  }
563 
565  {
566  if ( d_data->symbol )
567  {
568  QRectF r( 0, 0, size.width(), size.height() );
569  d_data->symbol->drawSymbol( &painter, r );
570  }
571  }
572 
573  return graphic;
574 }
575 
586 {
587  const QRectF boundingRect = d_series->boundingRect();
588 
589  if ( scaleId == QwtPolar::ScaleAzimuth )
590  return QwtInterval( boundingRect.left(), boundingRect.right() );
591 
592  if ( scaleId == QwtPolar::ScaleRadius )
593  return QwtInterval( boundingRect.top(), boundingRect.bottom() );
594 
595  return QwtInterval();
596 }
Style style() const
bool testLegendAttribute(LegendAttribute) const
Test if a lefend attribute is enables.
A point in polar coordinates.
void setData(QwtSeriesData< QwtPointPolar > *data)
double s1() const
Definition: qwt_scale_map.h:83
LegendAttribute
Attributes how to represent the curve on the legend.
virtual QRectF boundingRect() const =0
static void drawLine(QPainter *, qreal x1, qreal y1, qreal x2, qreal y2)
Wrapper for QPainter::drawLine()
Definition: qwt_painter.h:152
A class representing an interval.
Definition: qwt_interval.h:22
QwtPolarCurve::CurveStyle style
QPoint qwtPolar2Pos(const QPoint &pole, double radius, double angle)
Azimuth scale.
Definition: qwt_polar.h:74
void setStyle(CurveStyle style)
double radius() const
Returns the radius.
QwtSeriesData< QwtPointPolar > * d_series
An item, that represents a series of points.
QwtPolarCurve::LegendAttributes legendAttributes
virtual QwtInterval boundingInterval(int scaleId) const QWT_OVERRIDE
virtual void draw(QPainter *p, const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, const QPointF &pole, double radius, const QRectF &canvasRect) const QWT_OVERRIDE
void init()
Initialize data members.
A class for drawing symbols.
Definition: qwt_symbol.h:31
double azimuth() const
Returns the azimuth.
QFlags< LegendAttribute > LegendAttributes
Legend attributes.
virtual int rtti() const QWT_OVERRIDE
size_t dataSize() const
void setRenderHint(RenderHint, bool on=true)
void setDefaultSize(const QSizeF &)
Set a default size.
virtual ~QwtPolarCurve()
Destructor.
Base class for items on a polar plot.
QwtPointPolar sample(int i) const
const QwtSymbol * symbol() const
bool testRenderHint(RenderHint) const
void setItemAttribute(ItemAttribute, bool on=true)
void setZ(double z)
Set the z value.
static void clipPolygonF(const QRectF &, QPolygonF &, bool closePolygon=false)
const QPen & pen() const
A class representing a text.
Definition: qwt_text.h:51
void drawLines(QPainter *, const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, const QPointF &pole, int from, int to) const
QwtCurveFitter * curveFitter() const
void setLegendAttribute(LegendAttribute, bool on=true)
A paint device for scalable graphics.
Definition: qwt_graphic.h:75
void drawSymbols(QPainter *, const QPolygonF &) const
Draw symbols at the specified points.
Definition: qwt_symbol.h:251
A scale map.
Definition: qwt_scale_map.h:26
static bool qwtInsidePole(const QwtScaleMap &map, double radius)
If the curve has a valid symbol it is painted.
const QwtSeriesData< QwtPointPolar > * data() const
virtual void drawCurve(QPainter *, int style, const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, const QPointF &pole, int from, int to) const
virtual void drawSymbols(QPainter *, const QwtSymbol &, const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, const QPointF &pole, int from, int to) const
static void drawPolyline(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolyline()
CurveStyle style() const
Radial scale.
Definition: qwt_polar.h:77
void setSymbol(QwtSymbol *)
Assign a symbol.
virtual size_t size() const =0
void setPen(const QPen &)
Assign a pen.
virtual QPolygonF fitCurve(const QPolygonF &polygon) const =0
The item is represented on the legend.
const QwtText & title() const
bool isInverting() const
double transform(double s) const
static int qwtVerifyRange(int size, int &i1, int &i2)
Don&#39;t draw a curve. Note: This doesn&#39;t affect the symbols.
virtual void itemChanged()
QwtPolarCurve()
Constructor.
void drawSymbol(QPainter *, const QRectF &) const
Draw the symbol into a rectangle.
virtual QwtGraphic legendIcon(int index, const QSizeF &) const QWT_OVERRIDE
Abstract base class for a curve fitter.
const QBrush & brush() const
void setCurveFitter(QwtCurveFitter *)
Insert a curve fitter.
const QPen & pen() const
No Style. The symbol cannot be drawn.
Definition: qwt_symbol.h:41
PrivateData * d_data
void setRenderHint(RenderHint, bool on=true)


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