20 #include <qpainterpath.h> 25 #define DEBUG_RENDER 0 28 #include <qelapsedtimer.h> 37 return std::atan2( vy, vx );
42 return sqrt( vx * vx + vy * vy );
48 if ( series->
size() == 0 )
53 double min = s0.
vx * s0.
vx + s0.
vy * s0.
vy;
56 for ( uint i = 1; i < series->
size(); i++ )
59 const double l = s.
vx * s.
vx + s.
vy * s.
vy;
68 min = std::sqrt( min );
69 max = std::sqrt( max );
78 const QTransform& oldTransform,
double x,
double y,
79 double vx,
double vy,
double magnitude )
81 QTransform transform = oldTransform;
83 if ( !transform.isIdentity() )
85 transform.translate( x, y );
88 transform.rotateRadians( radians );
99 if ( magnitude == 0.0 )
107 sin = vy / magnitude;
108 cos = vx / magnitude;
111 transform.setMatrix( cos, sin, 0.0, -sin, cos, 0.0, x, y, 1.0 );
125 inline void addSample(
double sx,
double sy,
126 double svx,
double svy )
146 FilterMatrix(
const QRectF& dataRect,
147 const QRectF& canvasRect,
const QSizeF& cellSize )
149 m_dx = cellSize.width();
150 m_dy = cellSize.height();
153 if ( m_x0 < canvasRect.x() )
154 m_x0 +=
int( ( canvasRect.x() - m_x0 ) / m_dx ) * m_dx;
157 if ( m_y0 < canvasRect.y() )
158 m_y0 +=
int( ( canvasRect.y() - m_y0 ) / m_dy ) * m_dy;
160 m_numColumns = canvasRect.width() / m_dx + 1;
161 m_numRows = canvasRect.height() / m_dy + 1;
168 if ( m_numColumns > 1000 )
170 m_dx = canvasRect.width() / 1000;
171 m_numColumns = canvasRect.width() / m_dx + 1;
174 if ( m_numRows > 1000 )
176 m_dy = canvasRect.height() / 1000;
177 m_numRows = canvasRect.height() / m_dx + 1;
181 m_x1 = m_x0 + m_numColumns * m_dx;
182 m_y1 = m_y0 + m_numRows * m_dy;
184 m_entries = ( Entry* )::calloc( m_numRows * m_numColumns,
sizeof( Entry ) );
185 if ( m_entries == NULL )
187 qWarning() <<
"QwtPlotVectorField: raster for filtering too fine - running out of memory";
194 std::free( m_entries );
197 inline int numColumns()
const 202 inline int numRows()
const 207 inline void addSample(
double x,
double y,
210 if ( x >= m_x0 && x < m_x1
211 && y >= m_y0 && y < m_y1 )
213 Entry& entry = m_entries[ indexOf( x, y ) ];
214 entry.addSample( x, y, u, v );
218 const FilterMatrix::Entry* entries()
const 224 inline int indexOf( qreal x, qreal y )
const 226 const int col = ( x - m_x0 ) / m_dx;
227 const int row = ( y - m_y0 ) / m_dy;
229 return row * m_numColumns + col;
232 qreal m_x0, m_x1, m_y0, m_y1, m_dx, m_dy;
247 , magnitudeScaleFactor( 1.0 )
248 , rasterSize( 20, 20 )
249 , minArrowLength( 0.0 )
250 , maxArrowLength(
std::numeric_limits< short >::max() )
251 , magnitudeModes( MagnitudeAsLength )
481 attributes |= attribute;
483 attributes &= ~attribute;
573 if ( colorMap == NULL )
660 length = qMax( length, 0.0 );
690 length = qMax( length, 0.0 );
778 if ( size.isEmpty() )
781 QPainter painter( &icon );
782 painter.setRenderHint( QPainter::Antialiasing,
785 painter.translate( -size.width(), -0.5 * size.height() );
809 const QRectF& canvasRect,
int from,
int to )
const 828 drawSymbols( painter, xMap, yMap, canvasRect, from, to );
831 qDebug() << timer.elapsed();
849 const QRectF& canvasRect,
int from,
int to )
const 852 const bool doClip =
false;
888 if (xMap.
sDist() != 0)
892 if (yMap.
sDist() != 0)
896 FilterMatrix matrix( dataRect, canvasRect, canvasRasterSize );
899 for (
int i = from; i <= to; i++ )
909 const int numEntries = matrix.numRows() * matrix.numColumns();
910 const FilterMatrix::Entry* entries = matrix.entries();
912 for (
int i = 0; i < numEntries; i++ )
914 const FilterMatrix::Entry& entry = entries[i];
916 if ( entry.count == 0 )
919 double xi = entry.
x / entry.count;
920 double yi = entry.y / entry.count;
928 const double vx = entry.vx / entry.count;
929 const double vy = entry.vy / entry.count;
932 isInvertingX ? -vx : vx, isInvertingY ? -vy : vy );
937 for (
int i = from; i <= to; i++ )
956 if ( !canvasRect.contains( xi, yi ) )
961 isInvertingX ? -sample.
vx : sample.
vx,
962 isInvertingY ? -sample.
vy : sample.
vy );
976 double x,
double y,
double vx,
double vy )
const 980 const QTransform oldTransform = painter->transform();
983 x, y, vx, vy, magnitude );
998 const qreal dx = symbol->
length();
999 transform.translate( dx, 0.0 );
1003 const qreal dx = symbol->
length();
1004 transform.translate( 0.5 * dx, 0.0 );
1024 painter->setBrush( c );
1025 painter->setPen( c );
1029 painter->setWorldTransform( transform,
false );
1030 symbol->
paint( painter );
1031 painter->setWorldTransform( oldTransform,
false );
virtual void legendChanged()
virtual QwtGraphic legendIcon(int index, const QSizeF &) const QWT_OVERRIDE
void setBrush(const QBrush &)
Assign a brush.
virtual qreal length() const =0
QwtInterval magnitudeRange() const
QwtInterval magnitudeRange
void setSamples(const QVector< QwtVectorFieldSample > &)
virtual int rtti() const QWT_OVERRIDE
QwtVectorFieldSymbol * symbol
const QwtText & title() const
A class representing an interval.
double minArrowLength() const
void setMaxArrowLength(double)
virtual double arrowLength(double magnitude) const
void init()
Initialize data members.
double vy
y coordinate of the vector
const QwtColorMap * colorMap() const
void setColorMap(QwtColorMap *)
virtual QRectF dataRect() const QWT_OVERRIDE
QwtPlotVectorField(const QString &title=QString())
void setRasterSize(const QSizeF &)
void setData(QwtSeriesData< QwtVectorFieldSample > *series)
QwtVectorFieldSample sample(int index) const
IndicatorOrigin indicatorOrigin
double x
x coordinate of the position
static double qwtVector2Radians(double vx, double vy)
double vx
x coordinate of the vector
virtual QRectF boundingRect() const QWT_OVERRIDE
QwtSeriesData< QwtVectorFieldSample > * data()
void setMagnitudeScaleFactor(double factor)
Set the magnitudeScaleFactor.
double transform(double s) const
static QwtInterval qwtMagnitudeRange(const QwtSeriesData< QwtVectorFieldSample > *series)
void setIndicatorOrigin(IndicatorOrigin)
void setPaintAttribute(PaintAttribute, bool on=true)
void setMagnitudeRange(const QwtInterval &)
void setSymbol(QwtVectorFieldSymbol *)
void setDefaultSize(const QSizeF &)
Set a default size.
The item is represented on the legend.
static QTransform qwtSymbolTransformation(const QTransform &oldTransform, double x, double y, double vx, double vy, double magnitude)
constexpr auto count() -> size_t
virtual void drawSeries(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QWT_OVERRIDE
Sample used in vector fields.
A class representing a text.
void setZ(double z)
Set the z value.
PaintAttributes paintAttributes
QwtColorMap is used to map values into colors.
A paint device for scalable graphics.
The arrow is centered at the sample position.
virtual void drawSymbol(QPainter *, double x, double y, double vx, double vy) const
virtual void itemChanged()
QSizeF rasterSize() const
double y
y coordinate of the position
IndicatorOrigin indicatorOrigin() const
double magnitudeScaleFactor() const
double maxArrowLength() const
A plot item, that represents a vector field.
bool testPaintAttribute(PaintAttribute) const
MagnitudeModes magnitudeModes
bool testRenderHint(RenderHint) const
virtual QRgb rgb(const QwtInterval &interval, double value) const =0
virtual size_t size() const =0
virtual void paint(QPainter *) const =0
Draw the symbol/arrow.
bool testMagnitudeMode(MagnitudeMode) const
void setPen(const QPen &)
virtual T sample(size_t i) const =0
QwtInterval boundingMagnitudeRange
void setMinArrowLength(double)
qreal magnitudeScaleFactor
span_constexpr std::size_t size(span< T, Extent > const &spn)
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.
virtual void drawSymbols(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
void setItemAttribute(ItemAttribute, bool on=true)
virtual void dataChanged() QWT_OVERRIDE
dataChanged() indicates, that the series has been changed.
Interface for iterating over an array of vector field samples.
virtual ~QwtPlotVectorField()
Destructor.
const QwtVectorFieldSymbol * symbol() const
The arrow starts at the sample position.
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)