Sophie

Sophie

distrib > Fedora > 14 > x86_64 > by-pkgid > d9e51bfaa0475c88e86a4c5026a65fa0 > files > 28

qwtpolar-devel-0.1.0-5.fc14.i686.rpm

#include <qpen.h>
#include <qwt_data.h>
#include <qwt_symbol.h>
#include <qwt_legend.h>
#include <qwt_polar_grid.h>
#include <qwt_polar_curve.h>
#include <qwt_polar_marker.h>
#include <qwt_scale_engine.h>
#include "plot.h"

const QwtDoubleInterval radialInterval(0.0, 10.0);
const QwtDoubleInterval azimuthInterval(0.0, 360.0);

class Data: public QwtData
{
public:
    Data(const QwtDoubleInterval &radialInterval, 
            const QwtDoubleInterval &azimuthInterval, size_t size):
        d_radialInterval(radialInterval),
        d_azimuthInterval(azimuthInterval),
        d_size(size)
    {
    }

    virtual size_t size() const
    {
        return d_size;
    }

protected:
    QwtDoubleInterval d_radialInterval;
    QwtDoubleInterval d_azimuthInterval;
    size_t d_size;
};

class SpiralData: public Data
{
public:
    SpiralData(const QwtDoubleInterval &radialInterval, 
            const QwtDoubleInterval &azimuthInterval, size_t size):
        Data(radialInterval, azimuthInterval, size)
    {
    }

    virtual QwtData *copy() const
    {
        return new SpiralData(d_radialInterval, d_azimuthInterval, d_size);
    }

    virtual double x(size_t i) const
    {
        const double step = 4 * d_azimuthInterval.width() / d_size;
        return d_azimuthInterval.minValue() + i * step;
    }

    virtual double y(size_t i) const
    {
        const double step = d_radialInterval.width() / d_size;
        return d_radialInterval.minValue() + i * step;
    }
};

class RoseData: public Data
{
public:
    RoseData(const QwtDoubleInterval &radialInterval, 
            const QwtDoubleInterval &azimuthInterval, size_t size):
        Data(radialInterval, azimuthInterval, size)
    {
    }

    virtual QwtData *copy() const
    {
        return new RoseData(d_radialInterval, d_azimuthInterval, d_size);
    }

    virtual double x(size_t i) const
    {
        const double step = d_azimuthInterval.width() / d_size;
        return d_azimuthInterval.minValue() + i * step;
    }

    virtual double y(size_t i) const
    {
        const double a = x(i) / 360.0 * M_PI;
        return d_radialInterval.maxValue() * qwtAbs(::sin(4 * a));
    }
};


Plot::Plot(QWidget *parent):
    QwtPolarPlot(QwtText("Polar Plot Demo"), parent)
{
    setAutoReplot(false);
    setPlotBackground(Qt::darkBlue);

    // scales 
    setScale(QwtPolar::Azimuth, 
        azimuthInterval.minValue(), azimuthInterval.maxValue(), 
        azimuthInterval.width() / 12 );

    setScaleMaxMinor(QwtPolar::Azimuth, 2);
    setScale(QwtPolar::Radius, 
        radialInterval.minValue(), radialInterval.maxValue());

    // grids, axes 

    d_grid = new QwtPolarGrid();
    d_grid->setPen(QPen(Qt::white));
    for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
    {
        d_grid->showGrid(scaleId);
        d_grid->showMinorGrid(scaleId);

        QPen minorPen(Qt::gray);
#if 0
        minorPen.setStyle(Qt::DotLine);
#endif
        d_grid->setMinorGridPen(scaleId, minorPen);
    }
    d_grid->setAxisPen(QwtPolar::AxisAzimuth, QPen(Qt::black));

    d_grid->showAxis(QwtPolar::AxisAzimuth, true);
    d_grid->showAxis(QwtPolar::AxisLeft, false);
    d_grid->showAxis(QwtPolar::AxisRight, true);
    d_grid->showAxis(QwtPolar::AxisTop, true);
    d_grid->showAxis(QwtPolar::AxisBottom, false);
    d_grid->showGrid(QwtPolar::Azimuth, true);
    d_grid->showGrid(QwtPolar::Radius, true);
    d_grid->attach(this);

    // curves

    for ( int curveId = 0; curveId < PlotSettings::NumCurves; curveId++ )
    {
        d_curve[curveId] = createCurve(curveId);
        d_curve[curveId]->attach(this);
    }

    // markers
    QwtPolarMarker *marker = new QwtPolarMarker();
    marker->setPosition(QwtPolarPoint(57.3, 4.72));
    marker->setSymbol( QwtSymbol(QwtSymbol::Ellipse,
        QBrush(Qt::white), QPen(Qt::green), QSize(9, 9)) );
    marker->setLabelAlignment(Qt::AlignHCenter | Qt::AlignTop);

    QwtText text("Marker");
    text.setColor(Qt::black);
    QColor bg(Qt::white);
#if QT_VERSION >= 0x040300
    bg.setAlpha(200);
#endif
    text.setBackgroundBrush( QBrush( bg ));

    marker->setLabel(text);
    marker->attach(this);

    QwtLegend *legend = new QwtLegend;
    insertLegend(legend,  QwtPolarPlot::BottomLegend);
}

PlotSettings Plot::settings() const
{
    PlotSettings s;
    for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
    {
        s.flags[PlotSettings::MajorGridBegin + scaleId] =
            d_grid->isGridVisible(scaleId);
        s.flags[PlotSettings::MinorGridBegin + scaleId] =
            d_grid->isMinorGridVisible(scaleId);
    }
    for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
    {
        s.flags[PlotSettings::AxisBegin + axisId] = 
            d_grid->isAxisVisible(axisId);
    }

    s.flags[PlotSettings::AutoScaling] = 
        d_grid->testGridAttribute(QwtPolarGrid::AutoScaling);

    const QwtScaleTransformation *transform =
        scaleEngine(QwtPolar::Radius)->transformation();
    s.flags[PlotSettings::Logarithmic] = 
        (transform->type() == QwtScaleTransformation::Log10);
    delete transform;

    const QwtScaleDiv *sd = scaleDiv(QwtPolar::Radius);
    s.flags[PlotSettings::Inverted] = sd->lowerBound() > sd->upperBound();

#if QT_VERSION >= 0x040000
    s.flags[PlotSettings::Antialiasing] = d_grid->testRenderHint(
        QwtPolarItem::RenderAntialiased );
#endif

    for ( int curveId = 0; curveId < PlotSettings::NumCurves; curveId++ )
    {
        s.flags[PlotSettings::CurveBegin + curveId] =
            d_curve[curveId]->isVisible();
    }
    
    return s;
}

void Plot::applySettings(const PlotSettings& s)
{
    for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
    {
        d_grid->showGrid(scaleId, 
            s.flags[PlotSettings::MajorGridBegin + scaleId]);
        d_grid->showMinorGrid(scaleId, 
            s.flags[PlotSettings::MinorGridBegin + scaleId]);
    }

    for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
    {
        d_grid->showAxis(axisId, 
            s.flags[PlotSettings::AxisBegin + axisId]);
    }

    d_grid->setGridAttribute(QwtPolarGrid::AutoScaling,
        s.flags[PlotSettings::AutoScaling]);

    const QwtDoubleInterval interval = 
        scaleDiv(QwtPolar::Radius)->interval().normalized();
    if ( s.flags[PlotSettings::Inverted] )
    {
        setScale(QwtPolar::Radius,
            interval.maxValue(), interval.minValue());
    }
    else
    {
        setScale(QwtPolar::Radius,
            interval.minValue(), interval.maxValue());
    }

    const QwtScaleTransformation *transform = 
        scaleEngine(QwtPolar::Radius)->transformation();
    if ( s.flags[PlotSettings::Logarithmic] )
    {
        if ( transform->type() != QwtScaleTransformation::Log10 )
            setScaleEngine(QwtPolar::Radius, new QwtLog10ScaleEngine());
    }
    else
    {
        if ( transform->type() != QwtScaleTransformation::Linear )
            setScaleEngine(QwtPolar::Radius, new QwtLinearScaleEngine());
    }
    delete transform;

#if QT_VERSION >= 0x040000
    d_grid->setRenderHint( QwtPolarItem::RenderAntialiased, 
        s.flags[PlotSettings::Antialiasing] );
#endif

    for ( int curveId = 0; curveId < PlotSettings::NumCurves; curveId++ )
    {
#if QT_VERSION >= 0x040000
        d_curve[curveId]->setRenderHint(QwtPolarItem::RenderAntialiased,
            s.flags[PlotSettings::Antialiasing] );
#endif
        d_curve[curveId]->setVisible(
            s.flags[PlotSettings::CurveBegin + curveId]);
    }

    replot();
}

QwtPolarCurve *Plot::createCurve(int id) const
{
    const int numPoints = 200;

    QwtPolarCurve *curve = new QwtPolarCurve();
    curve->setStyle(QwtPolarCurve::Lines);
    switch(id)
    {
        case PlotSettings::Spiral:
        {
            curve->setTitle("Spiral");
            curve->setPen(QPen(Qt::yellow, 2));
            curve->setSymbol( QwtSymbol(QwtSymbol::Rect, 
                QBrush(Qt::yellow), QPen(Qt::white), QSize(3, 3)) );
            curve->setData(
                SpiralData(radialInterval, azimuthInterval, numPoints));
            break;
        }
        case PlotSettings::Rose:
        {
            curve->setTitle("Rose");
            curve->setPen(QPen(Qt::red, 2)); 
            curve->setSymbol( QwtSymbol(QwtSymbol::Rect,
                QBrush(Qt::cyan), QPen(Qt::white), QSize(3, 3)) );
            curve->setData(
                RoseData(radialInterval, azimuthInterval, numPoints));
            break;
        }
    }
    return curve;
}