20 #include <qpainterpath.h> 24 #define DEBUG_RENDER 0 27 #include <qelapsedtimer.h> 36 return std::atan2( vy, vx );
41 return sqrt( vx * vx + vy * vy );
47 if ( series->
size() == 0 )
55 for ( uint i = 1; i < series->
size(); i++ )
58 const double l = s.
vx * s.
vx + s.
vy * s.
vy;
67 min = std::sqrt( min );
68 max = std::sqrt( max );
77 const QTransform& oldTransform,
double x,
double y,
78 double vx,
double vy,
double magnitude )
80 QTransform transform = oldTransform;
82 if ( !transform.isIdentity() )
84 transform.translate( x, y );
87 transform.rotateRadians( radians );
98 if ( magnitude == 0.0 )
106 sin = vy / magnitude;
107 cos = vx / magnitude;
110 transform.setMatrix( cos, sin, 0.0, -sin, cos, 0.0, x, y, 1.0 );
124 inline void addSample(
double sx,
double sy,
125 double svx,
double svy )
145 FilterMatrix(
const QRectF& dataRect,
146 const QRectF& canvasRect,
const QSizeF& cellSize )
148 d_dx = cellSize.width();
149 d_dy = cellSize.height();
152 if ( d_x0 < canvasRect.x() )
153 d_x0 +=
int ( ( canvasRect.x() - d_x0 ) / d_dx ) * d_dx;
156 if ( d_y0 < canvasRect.y() )
157 d_y0 +=
int ( ( canvasRect.y() - d_y0 ) / d_dy ) * d_dy;
159 d_numColumns = canvasRect.width() / d_dx + 1;
160 d_numRows = canvasRect.height() / d_dy + 1;
167 if ( d_numColumns > 1000 )
169 d_dx = canvasRect.width() / 1000;
170 d_numColumns = canvasRect.width() / d_dx + 1;
173 if ( d_numRows > 1000 )
175 d_dy = canvasRect.height() / 1000;
176 d_numRows = canvasRect.height() / d_dx + 1;
180 d_x1 = d_x0 + d_numColumns * d_dx;
181 d_y1 = d_y0 + d_numRows * d_dy;
183 d_entries = ( Entry* )::calloc( d_numRows * d_numColumns,
sizeof( Entry ) );
184 if ( d_entries == NULL )
186 qWarning() <<
"QwtPlotVectorField: raster for filtering too fine - running out of memory";
196 inline int numColumns()
const 201 inline int numRows()
const 206 inline void addSample(
double x,
double y,
209 if ( x >= d_x0 && x < d_x1
210 && y >= d_y0 && y < d_y1 )
212 Entry &entry = d_entries[ indexOf( x, y ) ];
213 entry.addSample( x, y, u, v );
217 const FilterMatrix::Entry* entries()
const 223 inline int indexOf( qreal x, qreal y )
const 225 const int col = ( x - d_x0 ) / d_dx;
226 const int row = ( y - d_y0 ) / d_dy;
228 return row * d_numColumns + col;
231 qreal d_x0, d_x1, d_y0, d_y1, d_dx, d_dy;
246 magnitudeScaleFactor( 1.0 ),
247 rasterSize( 20, 20 ),
248 magnitudeModes( MagnitudeAsLength )
410 attributes |= attribute;
412 attributes &= ~attribute;
527 if ( colorMap == NULL )
608 int index,
const QSizeF &size )
const 615 if ( size.isEmpty() )
618 QPainter painter( &icon );
619 painter.setRenderHint( QPainter::Antialiasing,
622 painter.translate( -size.width(), -0.5 * size.height() );
648 const QRectF &canvasRect,
int from,
int to )
const 667 drawSymbols( painter, xMap, yMap, canvasRect, from, to );
670 qDebug() << timer.elapsed();
676 const QRectF &canvasRect,
int from,
int to )
const 679 const bool doClip =
false;
715 if (xMap.
sDist() != 0)
719 if (yMap.
sDist() != 0)
723 FilterMatrix matrix( dataRect, canvasRect, canvasRasterSize );
726 for (
int i = from; i <= to; i++ )
736 const int numEntries = matrix.numRows() * matrix.numColumns();
737 const FilterMatrix::Entry* entries = matrix.entries();
739 for (
int i = 0; i < numEntries; i++ )
741 const FilterMatrix::Entry &entry = entries[i];
743 if ( entry.count == 0 )
746 double xi = entry.
x / entry.count;
747 double yi = entry.y / entry.count;
755 const double vx = entry.vx / entry.count;
756 const double vy = entry.vy / entry.count;
759 isInvertingX ? -vx : vx, isInvertingY ? -vy : vy );
764 for (
int i = from; i <= to; i++ )
783 if ( !canvasRect.contains( xi, yi ) )
788 isInvertingX ? -sample.
vx : sample.
vx,
789 isInvertingY ? -sample.
vy : sample.
vy );
795 double x,
double y,
double vx,
double vy )
const 799 const QTransform oldTransform = painter->transform();
802 x, y, vx, vy, magnitude );
817 const qreal dx = symbol->
length();
818 transform.translate( dx, 0.0 );
822 const qreal dx = symbol->
length();
823 transform.translate( 0.5 * dx, 0.0 );
843 painter->setBrush( c );
844 painter->setPen( c );
848 painter->setWorldTransform( transform,
false );
849 symbol->
paint( painter );
850 painter->setWorldTransform( oldTransform,
false );
virtual void legendChanged()
virtual QwtGraphic legendIcon(int index, const QSizeF &) const QWT_OVERRIDE
IndicatorOrigin indicatorOrigin() const
void setBrush(const QBrush &)
virtual qreal length() const =0
QwtInterval magnitudeRange
void setSamples(const QVector< QwtVectorFieldSample > &)
virtual int rtti() const QWT_OVERRIDE
QwtVectorFieldSymbol * symbol
A class representing an interval.
void init()
Initialize data members.
virtual void drawSymbols(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
void setColorMap(QwtColorMap *)
virtual QRectF dataRect() const QWT_OVERRIDE
QwtPlotVectorField(const QString &title=QString())
void setRasterSize(const QSizeF &)
virtual double arrowLength(double magnitude) const
void setData(QwtSeriesData< QwtVectorFieldSample > *series)
IndicatorOrigin indicatorOrigin
void setMagnitudeModes(MagnitudeModes)
static double qwtVector2Radians(double vx, double vy)
MagnitudeModes magnitudeModes() const
virtual QRectF boundingRect() const QWT_OVERRIDE
QwtSeriesData< QwtVectorFieldSample > * data()
void setMagnitudeScaleFactor(double factor)
static QwtInterval qwtMagnitudeRange(const QwtSeriesData< QwtVectorFieldSample > *series)
void setIndicatorOrigin(IndicatorOrigin)
void setPaintAttribute(PaintAttribute, bool on=true)
bool testPaintAttribute(PaintAttribute) const
void setSymbol(QwtVectorFieldSymbol *)
void setDefaultSize(const QSizeF &)
Set a default size.
The item is represented on the legend.
double magnitudeScaleFactor() const
static QTransform qwtSymbolTransformation(const QTransform &oldTransform, double x, double y, double vx, double vy, double magnitude)
bool testRenderHint(RenderHint) const
const QwtVectorFieldSymbol * symbol() const
virtual void drawSeries(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QWT_OVERRIDE
A class representing a text.
virtual void drawSymbol(QPainter *, double x, double y, double vx, double vy) const
void setZ(double z)
Set the z value.
PaintAttributes paintAttributes
QwtColorMap is used to map values into colors.
QFlags< PaintAttribute > PaintAttributes
Paint attributes.
A paint device for scalable graphics.
QwtVectorFieldSample sample(int index) const
virtual void itemChanged()
const QwtColorMap * colorMap() const
QSizeF rasterSize() const
bool testMagnitudeMode(MagnitudeMode) const
MagnitudeModes magnitudeModes
virtual QRgb rgb(const QwtInterval &interval, double value) const =0
virtual size_t size() const =0
virtual void paint(QPainter *) const =0
void setPen(const QPen &)
virtual T sample(size_t i) const =0
QwtInterval boundingMagnitudeRange
void setMagnitudeRange(const QwtInterval &magnitudeRange)
qreal magnitudeScaleFactor
virtual size_t dataSize() const QWT_OVERRIDE
virtual void dataChanged() QWT_OVERRIDE
dataChanged() indicates, that the series has been changed.
Base class for plot items representing a series of samples.
void setItemAttribute(ItemAttribute, bool on=true)
double transform(double s) const
QFlags< MagnitudeMode > MagnitudeModes
Paint attributes.
virtual void dataChanged() QWT_OVERRIDE
dataChanged() indicates, that the series has been changed.
virtual ~QwtPlotVectorField()
Destructor.
static double qwtVector2Magnitude(double vx, double vy)
static bool roundingAlignment()
virtual QRectF boundingRect() const QWT_OVERRIDE
virtual void setLength(qreal length)=0
void setMagnitudeMode(MagnitudeMode, bool on=true)
const QwtText & title() const