20 #include <qtconcurrentrun.h> 22 #if !defined(QT_NO_QFUTURE) 23 #define QWT_USE_THREADS 1 30 return qRound( value );
37 return ( value >= 0.0 ) ? ::floor( value + 0.5 ) : ::ceil( value - 0.5 );
39 return nearbyint( value );
49 return Qt::Horizontal;
52 const double x0 = series->
sample( from ).x();
53 const double xn = series->
sample( to ).x();
58 const int step = ( to - from ) / 10;
59 const bool isIncreasing = xn > x0;
62 for (
int i = from + step;
i < to;
i += step )
64 const double x2 = series->
sample(
i ).x();
67 if ( ( x2 > x1 ) != isIncreasing )
74 return Qt::Horizontal;
77 template <
class Polygon,
class Po
int>
81 inline void start(
int x,
int y )
102 inline void flush( Polygon &polyline )
129 template <
class Polygon,
class Po
int>
136 x1 = xMin = xMax = x2 = x;
154 inline void flush( Polygon &polyline )
174 polyline +=
Point( x, y0 );
177 int y0, x1, xMin, xMax, x2;
180 template <
class Polygon,
class Po
int,
class PolygonQuadrupel>
184 const QPointF sample0 = series->
sample( from );
191 for (
int i = from;
i <= to;
i++ )
193 const QPointF sample = series->
sample(
i );
198 if ( !q.append( x, y ) )
209 template <
class Polygon,
class Po
int,
class PolygonQuadrupel>
212 const int numPoints = polyline.size();
217 const Point *points = polyline.constData();
222 q.start( points[0].
x(), points[0].
y() );
224 for (
int i = 0;
i < numPoints;
i++ )
226 const int x = points[
i].
x();
227 const int y = points[
i].
y();
229 if ( !q.append( x, y ) )
231 q.flush( polylineXY );
235 q.flush( polylineXY );
241 template <
class Polygon,
class Po
int>
255 if ( orientation == Qt::Horizontal )
290 const QRgb rgb = command.
rgb;
291 QRgb *bits =
reinterpret_cast<QRgb *
>( image->bits() );
293 const int w = image->width();
294 const int h = image->height();
296 const int x0 = pos.x();
297 const int y0 = pos.y();
299 for (
int i = command.
from;
i <= command.
to;
i++ )
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;
306 if ( x >= 0 && x < w && y >= 0 && y < h )
307 bits[ y * w + x ] = rgb;
339 template<
class Polygon,
class Po
int,
class Round>
341 const QRectF &boundingRect,
344 int from,
int to, Round round )
346 Polygon polyline( to - from + 1 );
347 Point *points = polyline.data();
351 if ( boundingRect.isValid() )
357 for (
int i = from;
i <= to;
i++ )
359 const QPointF sample = series->
sample(
i );
361 const double x = xMap.
transform( sample.x() );
362 const double y = yMap.
transform( sample.y() );
364 if ( boundingRect.contains( x, y ) )
366 points[ numPoints ].rx() = round( x );
367 points[ numPoints ].ry() = round( y );
373 polyline.resize( numPoints );
380 for (
int i = from;
i <= to;
i++ )
382 const QPointF sample = series->
sample(
i );
384 const double x = xMap.
transform( sample.x() );
385 const double y = yMap.
transform( sample.y() );
387 points[ numPoints ].rx() = round( x );
388 points[ numPoints ].ry() = round( y );
398 const QRectF &boundingRect,
403 return qwtToPoints<QPolygon, QPoint>(
404 boundingRect, xMap, yMap, series, from, to,
QwtRoundI() );
407 template<
class Round>
409 const QRectF &boundingRect,
412 int from,
int to, Round round )
414 return qwtToPoints<QPolygonF, QPointF>(
415 boundingRect, xMap, yMap, series, from, to, round );
421 template<
class Polygon,
class Po
int,
class Round>
425 int from,
int to, Round round )
432 Polygon polyline( to - from + 1 );
433 Point *points = polyline.data();
435 const QPointF sample0 = series->
sample( from );
437 points[0].rx() = round( xMap.
transform( sample0.x() ) );
438 points[0].ry() = round( yMap.
transform( sample0.y() ) );
441 for (
int i = from + 1;
i <= to;
i++ )
443 const QPointF sample = series->
sample(
i );
448 if ( points[pos] != p )
452 polyline.resize( pos + 1 );
461 return qwtToPolylineFiltered<QPolygon, QPoint>(
462 xMap, yMap, series, from, to,
QwtRoundI() );
465 template<
class Round>
469 int from,
int to, Round round )
471 return qwtToPolylineFiltered<QPolygonF, QPointF>(
472 xMap, yMap, series, from, to, round );
475 template<
class Polygon,
class Po
int>
477 const QRectF &boundingRect,
484 Polygon polygon( to - from + 1 );
485 Point *points = polygon.data();
490 for (
int i = from;
i <= to;
i++ )
492 const QPointF sample = series->
sample(
i );
497 if ( pixelMatrix.testAndSetPixel( x, y,
true ) == false )
499 points[ numPoints ].rx() = x;
500 points[ numPoints ].ry() = y;
506 polygon.resize( numPoints );
511 const QRectF &boundingRect,
515 return qwtToPointsFiltered<QPolygon, QPoint>(
516 boundingRect, xMap, yMap, series, from, to );
520 const QRectF &boundingRect,
524 return qwtToPointsFiltered<QPolygonF, QPointF>(
525 boundingRect, xMap, yMap, series, from, to );
560 d_data->flags = flags;
569 return d_data->flags;
583 d_data->flags |= flag;
585 d_data->flags &= ~flag;
595 return d_data->flags & flag;
608 d_data->boundingRect = rect;
617 return d_data->boundingRect;
647 if ( d_data->flags & RoundPoints )
649 if ( d_data->flags & WeedOutIntermediatePoints )
651 polyline = qwtMapPointsQuad<QPolygonF, QPointF>(
652 xMap, yMap, series, from, to );
654 else if ( d_data->flags & WeedOutPoints )
657 xMap, yMap, series, from, to,
QwtRoundF() );
662 xMap, yMap, series, from, to,
QwtRoundF() );
667 if ( d_data->flags & WeedOutPoints )
702 if ( d_data->flags & WeedOutIntermediatePoints )
705 polyline = qwtMapPointsQuad<QPolygon, QPoint>(
706 xMap, yMap, series, from, to );
708 else if ( d_data->flags & WeedOutPoints )
711 xMap, yMap, series, from, to );
759 if ( d_data->flags & WeedOutPoints )
761 if ( d_data->flags & RoundPoints )
763 if ( d_data->boundingRect.isValid() )
766 xMap, yMap, series, from, to );
775 xMap, yMap, series, from, to,
QwtRoundF() );
789 if ( d_data->flags & RoundPoints )
792 xMap, yMap, series, from, to,
QwtRoundF() );
833 if ( d_data->flags & WeedOutPoints )
835 if ( d_data->boundingRect.isValid() )
838 xMap, yMap, series, from, to );
846 xMap, yMap, series, from, to );
852 d_data->boundingRect, xMap, yMap, series, from, to );
880 const QPen &pen,
bool antialiased, uint numThreads )
const 882 Q_UNUSED( antialiased )
885 if ( numThreads == 0 )
886 numThreads = QThread::idealThreadCount();
888 if ( numThreads <= 0 )
891 Q_UNUSED( numThreads )
897 const QRect rect = d_data->boundingRect.toAlignedRect();
899 QImage image( rect.size(), QImage::Format_ARGB32 );
900 image.fill( Qt::transparent );
902 if ( pen.width() <= 1 && pen.color().alpha() == 255 )
906 command.
rgb = pen.color().rgba();
909 const int numPoints = ( to - from + 1 ) / numThreads;
911 QList< QFuture<void> > futures;
912 for ( uint
i = 0;
i < numThreads;
i++ )
914 const QPoint pos = rect.topLeft();
916 const int index0 = from +
i * numPoints;
917 if (
i == numThreads - 1 )
919 command.
from = index0;
926 command.
from = index0;
927 command.
to = index0 + numPoints - 1;
930 xMap, yMap, command, pos, &image );
933 for (
int i = 0;
i < futures.size();
i++ )
934 futures[
i].waitForFinished();
939 qwtRenderDots( xMap, yMap, command, rect.topLeft(), &image );
947 QPainter painter( &image );
948 painter.setPen( pen );
949 painter.setRenderHint( QPainter::Antialiasing, antialiased );
951 const int chunkSize = 1000;
952 for (
int i = from;
i <= to;
i += chunkSize )
954 const int indexTo = qMin(
i + chunkSize - 1, to );
955 const QPolygon points = toPoints(
956 xMap, yMap, series,
i, indexTo );
958 painter.drawPoints( points );
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 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)
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
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
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