qwt_point_mapper.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_point_mapper.h"
11 #include "qwt_scale_map.h"
12 #include "qwt_pixel_matrix.h"
13 #include <qpolygon.h>
14 #include <qimage.h>
15 #include <qpen.h>
16 #include <qpainter.h>
17 
18 #include <qthread.h>
19 #include <qfuture.h>
20 #include <qtconcurrentrun.h>
21 
22 #if !defined(QT_NO_QFUTURE)
23 #define QWT_USE_THREADS 1
24 #endif
25 
26 static QRectF qwtInvalidRect( 0.0, 0.0, -1.0, -1.0 );
27 
28 static inline int qwtRoundValue( double value )
29 {
30  return qRound( value );
31 }
32 
33 static inline double qwtRoundValueF( double value )
34 {
35 #if 1
36  // MS Windows and at least IRIX does not have C99's nearbyint() function
37  return ( value >= 0.0 ) ? ::floor( value + 0.5 ) : ::ceil( value - 0.5 );
38 #else
39  return nearbyint( value );
40 #endif
41 }
42 
43 static Qt::Orientation qwtProbeOrientation(
44  const QwtSeriesData<QPointF> *series, int from, int to )
45 {
46  if ( to - from < 20 )
47  {
48  // not enough points to "have an orientation"
49  return Qt::Horizontal;
50  }
51 
52  const double x0 = series->sample( from ).x();
53  const double xn = series->sample( to ).x();
54 
55  if ( x0 == xn )
56  return Qt::Vertical;
57 
58  const int step = ( to - from ) / 10;
59  const bool isIncreasing = xn > x0;
60 
61  double x1 = x0;
62  for ( int i = from + step; i < to; i += step )
63  {
64  const double x2 = series->sample( i ).x();
65  if ( x2 != x1 )
66  {
67  if ( ( x2 > x1 ) != isIncreasing )
68  return Qt::Vertical;
69  }
70 
71  x1 = x2;
72  }
73 
74  return Qt::Horizontal;
75 }
76 
77 template <class Polygon, class Point>
79 {
80 public:
81  inline void start( int x, int y )
82  {
83  x0 = x;
84  y1 = yMin = yMax = y2 = y;
85  }
86 
87  inline bool append( int x, int y )
88  {
89  if ( x0 != x )
90  return false;
91 
92  if ( y < yMin )
93  yMin = y;
94  else if ( y > yMax )
95  yMax = y;
96 
97  y2 = y;
98 
99  return true;
100  }
101 
102  inline void flush( Polygon &polyline )
103  {
104  appendTo( y1, polyline );
105 
106  if ( y2 > y1 )
107  qSwap( yMin, yMax );
108 
109  if ( yMax != y1 )
110  appendTo( yMax, polyline );
111 
112  if ( yMin != yMax )
113  appendTo( yMin, polyline );
114 
115  if ( y2 != yMin )
116  appendTo( y2, polyline );
117  }
118 
119 private:
120  inline void appendTo( int y, Polygon &polyline )
121  {
122  polyline += Point( x0, y );
123  }
124 
125 private:
126  int x0, y1, yMin, yMax, y2;
127 };
128 
129 template <class Polygon, class Point>
131 {
132 public:
133  inline void start( int x, int y )
134  {
135  y0 = y;
136  x1 = xMin = xMax = x2 = x;
137  }
138 
139  inline bool append( int x, int y )
140  {
141  if ( y0 != y )
142  return false;
143 
144  if ( x < xMin )
145  xMin = x;
146  else if ( x > xMax )
147  xMax = x;
148 
149  x2 = x;
150 
151  return true;
152  }
153 
154  inline void flush( Polygon &polyline )
155  {
156  appendTo( x1, polyline );
157 
158  if ( x2 > x1 )
159  qSwap( xMin, xMax );
160 
161  if ( xMax != x1 )
162  appendTo( xMax, polyline );
163 
164  if ( xMin != xMax )
165  appendTo( xMin, polyline );
166 
167  if ( x2 != xMin )
168  appendTo( x2, polyline );
169  }
170 
171 private:
172  inline void appendTo( int x, Polygon &polyline )
173  {
174  polyline += Point( x, y0 );
175  }
176 
177  int y0, x1, xMin, xMax, x2;
178 };
179 
180 template <class Polygon, class Point, class PolygonQuadrupel>
181 static Polygon qwtMapPointsQuad( const QwtScaleMap &xMap, const QwtScaleMap &yMap,
182  const QwtSeriesData<QPointF> *series, int from, int to )
183 {
184  const QPointF sample0 = series->sample( from );
185 
186  PolygonQuadrupel q;
187  q.start( qwtRoundValue( xMap.transform( sample0.x() ) ),
188  qwtRoundValue( yMap.transform( sample0.y() ) ) );
189 
190  Polygon polyline;
191  for ( int i = from; i <= to; i++ )
192  {
193  const QPointF sample = series->sample( i );
194 
195  const int x = qwtRoundValue( xMap.transform( sample.x() ) );
196  const int y = qwtRoundValue( yMap.transform( sample.y() ) );
197 
198  if ( !q.append( x, y ) )
199  {
200  q.flush( polyline );
201  q.start( x, y );
202  }
203  }
204  q.flush( polyline );
205 
206  return polyline;
207 }
208 
209 template <class Polygon, class Point, class PolygonQuadrupel>
210 static Polygon qwtMapPointsQuad( const Polygon &polyline )
211 {
212  const int numPoints = polyline.size();
213 
214  if ( numPoints < 3 )
215  return polyline;
216 
217  const Point *points = polyline.constData();
218 
219  Polygon polylineXY;
220 
221  PolygonQuadrupel q;
222  q.start( points[0].x(), points[0].y() );
223 
224  for ( int i = 0; i < numPoints; i++ )
225  {
226  const int x = points[i].x();
227  const int y = points[i].y();
228 
229  if ( !q.append( x, y ) )
230  {
231  q.flush( polylineXY );
232  q.start( x, y );
233  }
234  }
235  q.flush( polylineXY );
236 
237  return polylineXY;
238 }
239 
240 
241 template <class Polygon, class Point>
242 static Polygon qwtMapPointsQuad( const QwtScaleMap &xMap, const QwtScaleMap &yMap,
243  const QwtSeriesData<QPointF> *series, int from, int to )
244 {
245  Polygon polyline;
246  if ( from > to )
247  return polyline;
248 
249  /*
250  probing some values, to decide if it is better
251  to start with x or y coordinates
252  */
253  const Qt::Orientation orientation = qwtProbeOrientation( series, from, to );
254 
255  if ( orientation == Qt::Horizontal )
256  {
257  polyline = qwtMapPointsQuad< Polygon, Point,
258  QwtPolygonQuadrupelY<Polygon, Point> >( xMap, yMap, series, from, to );
259 
260  polyline = qwtMapPointsQuad< Polygon, Point,
262  }
263  else
264  {
265  polyline = qwtMapPointsQuad< Polygon, Point,
266  QwtPolygonQuadrupelX<Polygon, Point> >( xMap, yMap, series, from, to );
267 
268  polyline = qwtMapPointsQuad< Polygon, Point,
270  }
271 
272  return polyline;
273 }
274 
275 // Helper class to work around the 5 parameters
276 // limitation of QtConcurrent::run()
278 {
279 public:
281  int from;
282  int to;
283  QRgb rgb;
284 };
285 
286 static void qwtRenderDots(
287  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
288  const QwtDotsCommand &command, const QPoint &pos, QImage *image )
289 {
290  const QRgb rgb = command.rgb;
291  QRgb *bits = reinterpret_cast<QRgb *>( image->bits() );
292 
293  const int w = image->width();
294  const int h = image->height();
295 
296  const int x0 = pos.x();
297  const int y0 = pos.y();
298 
299  for ( int i = command.from; i <= command.to; i++ )
300  {
301  const QPointF sample = command.series->sample( i );
302 
303  const int x = static_cast<int>( xMap.transform( sample.x() ) + 0.5 ) - x0;
304  const int y = static_cast<int>( yMap.transform( sample.y() ) + 0.5 ) - y0;
305 
306  if ( x >= 0 && x < w && y >= 0 && y < h )
307  bits[ y * w + x ] = rgb;
308  }
309 }
310 
311 // some functors, so that the compile can inline
312 struct QwtRoundI
313 {
314  inline int operator()( double value ) const
315  {
316  return qwtRoundValue( value );
317  }
318 };
319 
320 struct QwtRoundF
321 {
322  inline double operator()( double value ) const
323  {
324  return qwtRoundValueF( value );
325  }
326 };
327 
329 {
330  inline double operator()( double value ) const
331  {
332  return value;
333  }
334 };
335 
336 // mapping points without any filtering - beside checking
337 // the bounding rectangle
338 
339 template<class Polygon, class Point, class Round>
340 static inline Polygon qwtToPoints(
341  const QRectF &boundingRect,
342  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
343  const QwtSeriesData<QPointF> *series,
344  int from, int to, Round round )
345 {
346  Polygon polyline( to - from + 1 );
347  Point *points = polyline.data();
348 
349  int numPoints = 0;
350 
351  if ( boundingRect.isValid() )
352  {
353  // iterating over all values
354  // filtering out all points outside of
355  // the bounding rectangle
356 
357  for ( int i = from; i <= to; i++ )
358  {
359  const QPointF sample = series->sample( i );
360 
361  const double x = xMap.transform( sample.x() );
362  const double y = yMap.transform( sample.y() );
363 
364  if ( boundingRect.contains( x, y ) )
365  {
366  points[ numPoints ].rx() = round( x );
367  points[ numPoints ].ry() = round( y );
368 
369  numPoints++;
370  }
371  }
372 
373  polyline.resize( numPoints );
374  }
375  else
376  {
377  // simply iterating over all values
378  // without any filtering
379 
380  for ( int i = from; i <= to; i++ )
381  {
382  const QPointF sample = series->sample( i );
383 
384  const double x = xMap.transform( sample.x() );
385  const double y = yMap.transform( sample.y() );
386 
387  points[ numPoints ].rx() = round( x );
388  points[ numPoints ].ry() = round( y );
389 
390  numPoints++;
391  }
392  }
393 
394  return polyline;
395 }
396 
397 static inline QPolygon qwtToPointsI(
398  const QRectF &boundingRect,
399  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
400  const QwtSeriesData<QPointF> *series,
401  int from, int to )
402 {
403  return qwtToPoints<QPolygon, QPoint>(
404  boundingRect, xMap, yMap, series, from, to, QwtRoundI() );
405 }
406 
407 template<class Round>
408 static inline QPolygonF qwtToPointsF(
409  const QRectF &boundingRect,
410  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
411  const QwtSeriesData<QPointF> *series,
412  int from, int to, Round round )
413 {
414  return qwtToPoints<QPolygonF, QPointF>(
415  boundingRect, xMap, yMap, series, from, to, round );
416 }
417 
418 // Mapping points with filtering out consecutive
419 // points mapped to the same position
420 
421 template<class Polygon, class Point, class Round>
422 static inline Polygon qwtToPolylineFiltered(
423  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
424  const QwtSeriesData<QPointF> *series,
425  int from, int to, Round round )
426 {
427  // in curves with many points consecutive points
428  // are often mapped to the same position. As this might
429  // result in empty lines ( or symbols hidden by others )
430  // we try to filter them out
431 
432  Polygon polyline( to - from + 1 );
433  Point *points = polyline.data();
434 
435  const QPointF sample0 = series->sample( from );
436 
437  points[0].rx() = round( xMap.transform( sample0.x() ) );
438  points[0].ry() = round( yMap.transform( sample0.y() ) );
439 
440  int pos = 0;
441  for ( int i = from + 1; i <= to; i++ )
442  {
443  const QPointF sample = series->sample( i );
444 
445  const Point p( round( xMap.transform( sample.x() ) ),
446  round( yMap.transform( sample.y() ) ) );
447 
448  if ( points[pos] != p )
449  points[++pos] = p;
450  }
451 
452  polyline.resize( pos + 1 );
453  return polyline;
454 }
455 
456 static inline QPolygon qwtToPolylineFilteredI(
457  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
458  const QwtSeriesData<QPointF> *series,
459  int from, int to )
460 {
461  return qwtToPolylineFiltered<QPolygon, QPoint>(
462  xMap, yMap, series, from, to, QwtRoundI() );
463 }
464 
465 template<class Round>
466 static inline QPolygonF qwtToPolylineFilteredF(
467  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
468  const QwtSeriesData<QPointF> *series,
469  int from, int to, Round round )
470 {
471  return qwtToPolylineFiltered<QPolygonF, QPointF>(
472  xMap, yMap, series, from, to, round );
473 }
474 
475 template<class Polygon, class Point>
476 static inline Polygon qwtToPointsFiltered(
477  const QRectF &boundingRect,
478  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
479  const QwtSeriesData<QPointF> *series, int from, int to )
480 {
481  // F.e. in scatter plots ( no connecting lines ) we
482  // can sort out all duplicates ( not only consecutive points )
483 
484  Polygon polygon( to - from + 1 );
485  Point *points = polygon.data();
486 
487  QwtPixelMatrix pixelMatrix( boundingRect.toAlignedRect() );
488 
489  int numPoints = 0;
490  for ( int i = from; i <= to; i++ )
491  {
492  const QPointF sample = series->sample( i );
493 
494  const int x = qwtRoundValue( xMap.transform( sample.x() ) );
495  const int y = qwtRoundValue( yMap.transform( sample.y() ) );
496 
497  if ( pixelMatrix.testAndSetPixel( x, y, true ) == false )
498  {
499  points[ numPoints ].rx() = x;
500  points[ numPoints ].ry() = y;
501 
502  numPoints++;
503  }
504  }
505 
506  polygon.resize( numPoints );
507  return polygon;
508 }
509 
510 static inline QPolygon qwtToPointsFilteredI(
511  const QRectF &boundingRect,
512  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
513  const QwtSeriesData<QPointF> *series, int from, int to )
514 {
515  return qwtToPointsFiltered<QPolygon, QPoint>(
516  boundingRect, xMap, yMap, series, from, to );
517 }
518 
519 static inline QPolygonF qwtToPointsFilteredF(
520  const QRectF &boundingRect,
521  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
522  const QwtSeriesData<QPointF> *series, int from, int to )
523 {
524  return qwtToPointsFiltered<QPolygonF, QPointF>(
525  boundingRect, xMap, yMap, series, from, to );
526 }
527 
529 {
530 public:
532  boundingRect( qwtInvalidRect )
533  {
534  }
535 
536  QRectF boundingRect;
538 };
539 
542 {
543  d_data = new PrivateData();
544 }
545 
548 {
549  delete d_data;
550 }
551 
559 {
560  d_data->flags = flags;
561 }
562 
568 {
569  return d_data->flags;
570 }
571 
581 {
582  if ( on )
583  d_data->flags |= flag;
584  else
585  d_data->flags &= ~flag;
586 }
587 
594 {
595  return d_data->flags & flag;
596 }
597 
606 void QwtPointMapper::setBoundingRect( const QRectF &rect )
607 {
608  d_data->boundingRect = rect;
609 }
610 
616 {
617  return d_data->boundingRect;
618 }
619 
642  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
643  const QwtSeriesData<QPointF> *series, int from, int to ) const
644 {
645  QPolygonF polyline;
646 
647  if ( d_data->flags & RoundPoints )
648  {
649  if ( d_data->flags & WeedOutIntermediatePoints )
650  {
651  polyline = qwtMapPointsQuad<QPolygonF, QPointF>(
652  xMap, yMap, series, from, to );
653  }
654  else if ( d_data->flags & WeedOutPoints )
655  {
656  polyline = qwtToPolylineFilteredF(
657  xMap, yMap, series, from, to, QwtRoundF() );
658  }
659  else
660  {
661  polyline = qwtToPointsF( qwtInvalidRect,
662  xMap, yMap, series, from, to, QwtRoundF() );
663  }
664  }
665  else
666  {
667  if ( d_data->flags & WeedOutPoints )
668  {
669  polyline = qwtToPolylineFilteredF(
670  xMap, yMap, series, from, to, QwtNoRoundF() );
671  }
672  else
673  {
674  polyline = qwtToPointsF( qwtInvalidRect,
675  xMap, yMap, series, from, to, QwtNoRoundF() );
676  }
677  }
678 
679  return polyline;
680 }
681 
697  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
698  const QwtSeriesData<QPointF> *series, int from, int to ) const
699 {
700  QPolygon polyline;
701 
702  if ( d_data->flags & WeedOutIntermediatePoints )
703  {
704  // TODO WeedOutIntermediatePointsY ...
705  polyline = qwtMapPointsQuad<QPolygon, QPoint>(
706  xMap, yMap, series, from, to );
707  }
708  else if ( d_data->flags & WeedOutPoints )
709  {
710  polyline = qwtToPolylineFilteredI(
711  xMap, yMap, series, from, to );
712  }
713  else
714  {
715  polyline = qwtToPointsI(
716  qwtInvalidRect, xMap, yMap, series, from, to );
717  }
718 
719  return polyline;
720 }
721 
754  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
755  const QwtSeriesData<QPointF> *series, int from, int to ) const
756 {
757  QPolygonF points;
758 
759  if ( d_data->flags & WeedOutPoints )
760  {
761  if ( d_data->flags & RoundPoints )
762  {
763  if ( d_data->boundingRect.isValid() )
764  {
765  points = qwtToPointsFilteredF( d_data->boundingRect,
766  xMap, yMap, series, from, to );
767  }
768  else
769  {
770  // without a bounding rectangle all we can
771  // do is to filter out duplicates of
772  // consecutive points
773 
774  points = qwtToPolylineFilteredF(
775  xMap, yMap, series, from, to, QwtRoundF() );
776  }
777  }
778  else
779  {
780  // when rounding is not allowed we can't use
781  // qwtToPointsFilteredF
782 
783  points = qwtToPolylineFilteredF(
784  xMap, yMap, series, from, to, QwtNoRoundF() );
785  }
786  }
787  else
788  {
789  if ( d_data->flags & RoundPoints )
790  {
791  points = qwtToPointsF( d_data->boundingRect,
792  xMap, yMap, series, from, to, QwtRoundF() );
793  }
794  else
795  {
796  points = qwtToPointsF( d_data->boundingRect,
797  xMap, yMap, series, from, to, QwtNoRoundF() );
798  }
799  }
800 
801  return points;
802 }
803 
828  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
829  const QwtSeriesData<QPointF> *series, int from, int to ) const
830 {
831  QPolygon points;
832 
833  if ( d_data->flags & WeedOutPoints )
834  {
835  if ( d_data->boundingRect.isValid() )
836  {
837  points = qwtToPointsFilteredI( d_data->boundingRect,
838  xMap, yMap, series, from, to );
839  }
840  else
841  {
842  // when we don't have the bounding rectangle all
843  // we can do is to filter out consecutive duplicates
844 
845  points = qwtToPolylineFilteredI(
846  xMap, yMap, series, from, to );
847  }
848  }
849  else
850  {
851  points = qwtToPointsI(
852  d_data->boundingRect, xMap, yMap, series, from, to );
853  }
854 
855  return points;
856 }
857 
858 
878  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
879  const QwtSeriesData<QPointF> *series, int from, int to,
880  const QPen &pen, bool antialiased, uint numThreads ) const
881 {
882  Q_UNUSED( antialiased )
883 
884 #if QWT_USE_THREADS
885  if ( numThreads == 0 )
886  numThreads = QThread::idealThreadCount();
887 
888  if ( numThreads <= 0 )
889  numThreads = 1;
890 #else
891  Q_UNUSED( numThreads )
892 #endif
893 
894  // a very special optimization for scatter plots
895  // where every sample is mapped to one pixel only.
896 
897  const QRect rect = d_data->boundingRect.toAlignedRect();
898 
899  QImage image( rect.size(), QImage::Format_ARGB32 );
900  image.fill( Qt::transparent );
901 
902  if ( pen.width() <= 1 && pen.color().alpha() == 255 )
903  {
905  command.series = series;
906  command.rgb = pen.color().rgba();
907 
908 #if QWT_USE_THREADS
909  const int numPoints = ( to - from + 1 ) / numThreads;
910 
911  QList< QFuture<void> > futures;
912  for ( uint i = 0; i < numThreads; i++ )
913  {
914  const QPoint pos = rect.topLeft();
915 
916  const int index0 = from + i * numPoints;
917  if ( i == numThreads - 1 )
918  {
919  command.from = index0;
920  command.to = to;
921 
922  qwtRenderDots( xMap, yMap, command, pos, &image );
923  }
924  else
925  {
926  command.from = index0;
927  command.to = index0 + numPoints - 1;
928 
929  futures += QtConcurrent::run( &qwtRenderDots,
930  xMap, yMap, command, pos, &image );
931  }
932  }
933  for ( int i = 0; i < futures.size(); i++ )
934  futures[i].waitForFinished();
935 #else
936  command.from = from;
937  command.to = to;
938 
939  qwtRenderDots( xMap, yMap, command, rect.topLeft(), &image );
940 #endif
941  }
942  else
943  {
944  // fallback implementation: to be replaced later by
945  // setting the pixels of the image like above, TODO ...
946 
947  QPainter painter( &image );
948  painter.setPen( pen );
949  painter.setRenderHint( QPainter::Antialiasing, antialiased );
950 
951  const int chunkSize = 1000;
952  for ( int i = from; i <= to; i += chunkSize )
953  {
954  const int indexTo = qMin( i + chunkSize - 1, to );
955  const QPolygon points = toPoints(
956  xMap, yMap, series, i, indexTo );
957 
958  painter.drawPoints( points );
959  }
960  }
961 
962  return image;
963 }
QRectF boundingRect() const
void setFlags(TransformationFlags)
QFlags< TransformationFlag > TransformationFlags
Flags affecting the transformation process.
QPolygonF toPointsF(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
Translate a series into a QPolygonF.
A bit field corresponding to the pixels of a rectangle.
void setBoundingRect(const QRectF &)
int operator()(double value) const
QwtPointMapper()
Constructor.
TransformationFlag
Flags affecting the transformation process.
static QPolygon qwtToPointsI(const QRectF &boundingRect, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to)
static void qwtRenderDots(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtDotsCommand &command, const QPoint &pos, QImage *image)
void appendTo(int x, Polygon &polyline)
QPolygon toPolygon(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
Translate a series of points into a QPolygon.
TFSIMD_FORCE_INLINE const tfScalar & y() const
static QRectF qwtInvalidRect(0.0, 0.0,-1.0,-1.0)
bool append(int x, int y)
bool testFlag(TransformationFlag) const
void start(int x, int y)
void setFlag(TransformationFlag, bool on=true)
static Polygon qwtMapPointsQuad(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to)
TFSIMD_FORCE_INLINE const tfScalar & x() const
static QPolygon qwtToPolylineFilteredI(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to)
QPolygon toPoints(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
Translate a series of points into a QPolygon.
static QPolygonF qwtToPolylineFilteredF(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to, Round round)
ROSLIB_DECL std::string command(const std::string &cmd)
~QwtPointMapper()
Destructor.
void appendTo(int y, Polygon &polyline)
double operator()(double value) const
static QPolygonF qwtToPointsFilteredF(const QRectF &boundingRect, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to)
TFSIMD_FORCE_INLINE const tfScalar & y() const
static int qwtRoundValue(double value)
TFSIMD_FORCE_INLINE const tfScalar & x() const
bool append(int x, int y)
A scale map.
Definition: qwt_scale_map.h:30
static Polygon qwtToPoints(const QRectF &boundingRect, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to, Round round)
TFSIMD_FORCE_INLINE const tfScalar & w() const
unsigned int step
const QwtSeriesData< QPointF > * series
void flush(Polygon &polyline)
QPolygonF toPolygonF(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
Translate a series of points into a QPolygonF.
double operator()(double value) const
static Polygon qwtToPointsFiltered(const QRectF &boundingRect, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to)
void flush(Polygon &polyline)
virtual T sample(size_t i) const =0
static QPolygonF qwtToPointsF(const QRectF &boundingRect, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to, Round round)
QImage toImage(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to, const QPen &, bool antialiased, uint numThreads) const
Translate a series into a QImage.
static Polygon qwtToPolylineFiltered(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to, Round round)
double transform(double s) const
void start(int x, int y)
int i
static double qwtRoundValueF(double value)
QwtPointMapper::TransformationFlags flags
static Qt::Orientation qwtProbeOrientation(const QwtSeriesData< QPointF > *series, int from, int to)
static QPolygon qwtToPointsFilteredI(const QRectF &boundingRect, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to)
TransformationFlags flags() const


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:17