9#include "qwt_polar_grid.h" 
   10#include "qwt_painter.h" 
   12#include "qwt_clipper.h" 
   13#include "qwt_scale_map.h" 
   14#include "qwt_scale_engine.h" 
   15#include "qwt_scale_div.h" 
   16#include "qwt_scale_draw.h" 
   17#include "qwt_round_scale_draw.h" 
   23static inline bool isClose( 
double value1, 
double value2 )
 
   25    return qAbs( value1 - value2 ) < DBL_EPSILON;
 
   55            , isMinorVisible( false )
 
   68class QwtPolarGrid::PrivateData
 
   71    GridData gridData[QwtPolar::ScaleCount];
 
   72    AxisData axisData[QwtPolar::AxesCount];
 
   87    m_data = 
new PrivateData;
 
   89    for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
   91        AxisData& axis = m_data->axisData[axisId];
 
   94            case QwtPolar::AxisAzimuth:
 
  100                axis.isVisible = 
true;
 
  103            case QwtPolar::AxisLeft:
 
  109                axis.isVisible = 
false;
 
  112            case QwtPolar::AxisRight:
 
  118                axis.isVisible = 
true;
 
  121            case QwtPolar::AxisTop:
 
  127                axis.isVisible = 
false;
 
  130            case QwtPolar::AxisBottom:
 
  136                axis.isVisible = 
true;
 
 
  176    if ( ( ( m_data->displayFlags & flag ) != 0 ) != on )
 
  179            m_data->displayFlags |= flag;
 
  181            m_data->displayFlags &= ~flag;
 
 
  193    return ( m_data->displayFlags & flag );
 
 
  207    if ( 
bool( m_data->attributes & attribute ) == on )
 
  211        m_data->attributes |= attribute;
 
  213        m_data->attributes &= ~attribute;
 
 
  224    return m_data->attributes & attribute;
 
 
  237    if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  240    AxisData& axisData = m_data->axisData[axisId];
 
  241    if ( axisData.pen != pen )
 
 
  256    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  259    GridData& grid = m_data->gridData[scaleId];
 
  260    if ( grid.isVisible != 
show )
 
  262        grid.isVisible = 
show;
 
 
  274    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  277    return m_data->gridData[scaleId].isVisible;
 
 
  292    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  295    GridData& grid = m_data->gridData[scaleId];
 
  296    if ( grid.isMinorVisible != 
show )
 
  298        grid.isMinorVisible = 
show;
 
 
  310    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  313    return m_data->gridData[scaleId].isMinorVisible;
 
 
  326    if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  329    AxisData& axisData = m_data->axisData[axisId];
 
  330    if ( axisData.isVisible != 
show )
 
  332        axisData.isVisible = 
show;
 
 
  345    if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  348    return m_data->axisData[axisId].isVisible;
 
 
  359    bool isChanged = 
false;
 
  361    for ( 
int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
 
  363        GridData& grid = m_data->gridData[scaleId];
 
  364        if ( grid.majorPen != pen || grid.minorPen != pen )
 
  371    for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
  373        AxisData& axis = m_data->axisData[axisId];
 
  374        if ( axis.pen != pen )
 
 
  392    bool isChanged = 
false;
 
  393    for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
  395        AxisData& axis = m_data->axisData[axisId];
 
  396        if ( axis.font != font )
 
 
  414    bool isChanged = 
false;
 
  416    for ( 
int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
 
  418        GridData& grid = m_data->gridData[scaleId];
 
  419        if ( grid.majorPen != pen )
 
 
  438    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  441    GridData& grid = m_data->gridData[scaleId];
 
  442    if ( grid.majorPen != pen )
 
 
  456    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  459    const GridData& grid = m_data->gridData[scaleId];
 
  460    return grid.majorPen;
 
 
  471    bool isChanged = 
false;
 
  473    for ( 
int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
 
  475        GridData& grid = m_data->gridData[scaleId];
 
  476        if ( grid.minorPen != pen )
 
 
  495    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  498    GridData& grid = m_data->gridData[scaleId];
 
  499    if ( grid.minorPen != pen )
 
 
  512    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  515    const GridData& grid = m_data->gridData[scaleId];
 
  516    return grid.minorPen;
 
 
  527    if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  530    return m_data->axisData[axisId].pen;
 
 
  541    if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  544    AxisData& axisData = m_data->axisData[axisId];
 
  545    if ( axisData.font != font )
 
  547        axisData.font = font;
 
 
  558    if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  561    return m_data->axisData[axisId].font;
 
 
  576    const QPointF& pole, 
double radius,
 
  577    const QRectF& canvasRect )
 const 
  579    updateScaleDraws( azimuthMap, radialMap, pole, radius );
 
  585        QRegion clipRegion( canvasRect.toRect() );
 
  586        for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
  588            const AxisData& axis = m_data->axisData[axisId];
 
  589            if ( axisId != QwtPolar::AxisAzimuth && axis.isVisible )
 
  596                    for ( 
int i = 0; i < int( ticks.size() ); i++ )
 
  604                        const int margin = 2;
 
  605                        labelRect.adjust( -margin, -margin, margin, margin );
 
  607                        if ( labelRect.isValid() )
 
  608                            clipRegion -= QRegion( labelRect );
 
  613        painter->setClipRegion( clipRegion );
 
  618    const GridData& radialGrid = m_data->gridData[QwtPolar::Radius];
 
  619    if ( radialGrid.isVisible && radialGrid.isMinorVisible )
 
  621        painter->setPen( radialGrid.minorPen );
 
  628    if ( radialGrid.isVisible )
 
  630        painter->setPen( radialGrid.majorPen );
 
  638    const GridData& azimuthGrid =
 
  639        m_data->gridData[QwtPolar::Azimuth];
 
  641    if ( azimuthGrid.isVisible && azimuthGrid.isMinorVisible )
 
  643        painter->setPen( azimuthGrid.minorPen );
 
  645        drawRays( painter, canvasRect, pole, radius, azimuthMap,
 
  647        drawRays( painter, canvasRect, pole, radius, azimuthMap,
 
  650    if ( azimuthGrid.isVisible )
 
  652        painter->setPen( azimuthGrid.majorPen );
 
  654        drawRays( painter, canvasRect, pole, radius, azimuthMap,
 
  659    for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
  661        const AxisData& axis = m_data->axisData[axisId];
 
  662        if ( axis.isVisible )
 
 
  682    QPainter* painter, 
const QRectF& canvasRect,
 
  683    const QPointF& pole, 
double radius,
 
  686    for ( 
int i = 0; i < int( values.size() ); i++ )
 
  688        double azimuth = azimuthMap.
transform( values[i] );
 
  689        azimuth = ::fmod( azimuth, 2 * M_PI );
 
  691        bool skipLine = 
false;
 
  696            if ( isClose( azimuth, 0.0 ) )
 
  698                const AxisData& axis = m_data->axisData[QwtPolar::AxisRight];
 
  699                if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
 
  702            else if ( isClose( azimuth, M_PI / 2 ) )
 
  704                const AxisData& axis = m_data->axisData[QwtPolar::AxisTop];
 
  705                if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
 
  708            else if ( isClose( azimuth, M_PI ) )
 
  710                const AxisData& axis = m_data->axisData[QwtPolar::AxisLeft];
 
  711                if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
 
  714            else if ( isClose( azimuth, 3 * M_PI / 2.0 ) )
 
  716                const AxisData& axis = m_data->axisData[QwtPolar::AxisBottom];
 
  717                if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
 
  723            const QPointF pos = qwtPolar2Pos( pole, radius, azimuth );
 
  730            QPolygonF polygon( 2 );
 
  731            polygon[0] = pole.toPoint();
 
  732            polygon[1] = pos.toPoint();
 
 
  752    QPainter* painter, 
const QRectF& canvasRect,
 
  756    for ( 
int i = 0; i < int( values.size() ); i++ )
 
  758        const double val = values[i];
 
  760        const GridData& gridData =
 
  761            m_data->gridData[QwtPolar::Radius];
 
  763        bool skipLine = 
false;
 
  766            const AxisData& axis = m_data->axisData[QwtPolar::AxisAzimuth];
 
  767            if ( axis.isVisible &&
 
  770                if ( isClose( val, gridData.scaleDiv.
upperBound() ) )
 
  775        if ( isClose( val, gridData.scaleDiv.
lowerBound() ) )
 
  780            const double radius = radialMap.
transform( val );
 
  782            QRectF outerRect( 0, 0, 2 * radius, 2 * radius );
 
  783            outerRect.moveCenter( pole );
 
  796                for ( 
int j = 0; j < angles.size(); j++ )
 
  806                        const double from = qwtDegrees( intv.
minValue() );
 
  807                        const double to = qwtDegrees( intv.
maxValue() );
 
  809                        double span = to - from;
 
  813                        painter->drawArc( outerRect,
 
  814                            qRound( from * 16 ), qRound( span * 16 ) );
 
 
  834    if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  837    AxisData& axis = m_data->axisData[axisId];
 
  839    painter->setPen( axis.pen );
 
  840    painter->setFont( axis.font );
 
  843    pal.setColor( QPalette::WindowText, axis.pen.color() );
 
  844    pal.setColor( QPalette::Text, axis.pen.color() );
 
  846    axis.scaleDraw->draw( painter, pal );
 
 
  859void QwtPolarGrid::updateScaleDraws(
 
  861    const QPointF& pole, 
double radius )
 const 
  863    const QPoint p = pole.toPoint();
 
  866        m_data->gridData[QwtPolar::ScaleRadius].scaleDiv.
interval();
 
  870    const int l = max - min;
 
  872    for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
  874        AxisData& axis = m_data->axisData[axisId];
 
  876        if ( axisId == QwtPolar::AxisAzimuth )
 
  881            scaleDraw->setRadius( qRound( radius ) );
 
  884            double from = ::fmod( 90.0 - qwtDegrees( azimuthMap.
p1() ), 360.0 );
 
  888            scaleDraw->setAngleRange( from, from - 360.0 );
 
  903                case QwtPolar::AxisLeft:
 
  909                case QwtPolar::AxisRight:
 
  915                case QwtPolar::AxisTop:
 
  921                case QwtPolar::AxisBottom:
 
  955    GridData& radialGrid = m_data->gridData[QwtPolar::Radius];
 
  968        if ( radialGrid.scaleDiv != radialScaleDiv )
 
  969            radialGrid.scaleDiv = radialScaleDiv;
 
  972    GridData& azimuthGrid = m_data->gridData[QwtPolar::Azimuth];
 
  973    if ( azimuthGrid.scaleDiv != azimuthScaleDiv )
 
  975        azimuthGrid.scaleDiv = azimuthScaleDiv;
 
  978    bool hasOrigin = 
false;
 
  979    for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
  981        AxisData& axis = m_data->axisData[axisId];
 
  982        if ( axis.isVisible && axis.scaleDraw )
 
  984            if ( axisId == QwtPolar::AxisAzimuth )
 
  986                axis.scaleDraw->setScaleDiv( azimuthGrid.scaleDiv );
 
  989                    axis.scaleDraw->enableComponent(
 
 1001                    bool skipOrigin = hasOrigin;
 
 1004                        if ( axisId == QwtPolar::AxisLeft
 
 1005                            || axisId == QwtPolar::AxisRight )
 
 1007                            if ( m_data->axisData[QwtPolar::AxisBottom].isVisible )
 
 1012                            if ( m_data->axisData[QwtPolar::AxisLeft].isVisible )
 
 1016                    if ( ticks.size() > 0 && ticks.first() == sd.
lowerBound() )
 
 1019                            ticks.removeFirst();
 
 1027                    if ( ticks.size() > 0 && ticks.last() == sd.
upperBound() )
 
 1032                axis.scaleDraw->setScaleDiv( sd );
 
 1036                    axis.scaleDraw->enableComponent(
 
 
 1051    const AxisData& axis = m_data->axisData[QwtPolar::AxisAzimuth];
 
 1052    if ( axis.isVisible )
 
 1054        const int extent = axis.scaleDraw->extent( axis.font );
 
 
 1070    if ( axisId >= QwtPolar::AxisLeft && axisId <= QwtPolar::AxisBottom )
 
 1071        return static_cast< QwtScaleDraw* 
>( m_data->axisData[axisId].scaleDraw );
 
 
 1085    if ( axisId >= QwtPolar::AxisLeft && axisId <= QwtPolar::AxisBottom )
 
 1086        return static_cast< QwtScaleDraw* 
>( m_data->axisData[axisId].scaleDraw );
 
 
 1101    if ( axisId < QwtPolar::AxisLeft || axisId > QwtPolar::AxisBottom )
 
 1104    AxisData& axisData = m_data->axisData[axisId];
 
 1107        delete axisData.scaleDraw;
 
 
 1120        m_data->axisData[QwtPolar::AxisAzimuth].scaleDraw );
 
 
 1130        m_data->axisData[QwtPolar::AxisAzimuth].scaleDraw );
 
 
 1141    AxisData& axisData = m_data->axisData[QwtPolar::AxisAzimuth];
 
 1144        delete axisData.scaleDraw;
 
 
A abstract base class for drawing scales.
@ Backbone
Backbone = the line where the ticks are located.
void setTransformation(QwtTransform *)
bool hasComponent(ScaleComponent) const
const QwtScaleDiv & scaleDiv() const
A class representing an interval.
static void drawEllipse(QPainter *, const QRectF &)
Wrapper for QPainter::drawEllipse()
static void drawPolyline(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolyline()
bool testDisplayFlag(DisplayFlag) const
GridAttribute
Grid attributes.
void setGridAttribute(GridAttribute, bool on=true)
Specify an attribute for the grid.
QFont axisFont(int axisId) const
QPen minorGridPen(int scaleId) const
QPen axisPen(int axisId) const
bool testGridAttribute(GridAttribute) const
void setScaleDraw(int axisId, QwtScaleDraw *)
Set a scale draw.
virtual ~QwtPolarGrid()
Destructor.
const QwtRoundScaleDraw * azimuthScaleDraw() const
virtual void updateScaleDiv(const QwtScaleDiv &azimuthMap, const QwtScaleDiv &radialMap, const QwtInterval &) override
Update the item to changes of the axes scale division.
void showMinorGrid(int scaleId, bool show=true)
void showGrid(int scaleId, bool show=true)
void setMinorGridPen(const QPen &p)
virtual int marginHint() const override
void setPen(const QPen &p)
void setAzimuthScaleDraw(QwtRoundScaleDraw *)
Set a scale draw for the azimuth scale.
void drawRays(QPainter *, const QRectF &, const QPointF &pole, double radius, const QwtScaleMap &azimuthMap, const QList< double > &) const
void drawCircles(QPainter *, const QRectF &, const QPointF &pole, const QwtScaleMap &radialMap, const QList< double > &) const
QFlags< GridAttribute > GridAttributes
bool isGridVisible(int scaleId) const
const QwtScaleDraw * scaleDraw(int axisId) const
bool isMinorGridVisible(int scaleId) const
virtual int rtti() const override
virtual void draw(QPainter *p, const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, const QPointF &pole, double radius, const QRectF &rect) const override
bool isAxisVisible(int axisId) const
QPen majorGridPen(int scaleId) const
void setAxisFont(int axisId, const QFont &p)
void setAxisPen(int axisId, const QPen &p)
void drawAxis(QPainter *, int axisId) const
void showAxis(int axisId, bool show=true)
void setFont(const QFont &)
void setMajorGridPen(const QPen &p)
QFlags< DisplayFlag > DisplayFlags
void setDisplayFlag(DisplayFlag, bool on=true)
QwtPolarGrid()
Constructor.
Base class for items on a polar plot.
virtual void itemChanged()
@ Rtti_PolarGrid
For QwtPolarGrid.
QwtPolarPlot * plot() const
@ RenderAntialiased
Enable antialiasing.
void show()
Show the item.
void setRenderHint(RenderHint, bool on=true)
void setZ(double z)
Set the z value.
A plotting widget, displaying a polar coordinate system.
int scaleMaxMajor(int scaleId) const
int scaleMaxMinor(int scaleId) const
QwtScaleEngine * scaleEngine(int scaleId)
A class for drawing round scales.
A class representing a scale division.
double lowerBound() const
QwtInterval interval() const
double upperBound() const
QList< double > ticks(int tickType) const
bool contains(double value) const
@ MediumTick
Medium ticks.
void setTicks(int tickType, const QList< double > &)
A class for drawing scales.
void setLength(double length)
QRect boundingLabelRect(const QFont &, double value) const
Find the bounding rectangle for the label.
void move(double x, double y)
void setAlignment(Alignment)
@ BottomScale
The scale is below.
@ LeftScale
The scale is left.
Base class for scale engines.
virtual QwtScaleDiv divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const =0
Calculate a scale division.
double transform(double s) const
const QwtTransform * transformation() const
Get the transformation.
A class representing a text.
QWT_EXPORT void clipPolygonF(const QRectF &, QPolygonF &, bool closePolygon=false)
QWT_EXPORT QVector< QwtInterval > clipCircle(const QRectF &, const QPointF &, double radius)