210 lines
5.6 KiB
C++
210 lines
5.6 KiB
C++
/*****************************************************************************
|
|
* Qwt Polar Examples - Copyright (C) 2008 Uwe Rathmann
|
|
* This file may be used under the terms of the 3-clause BSD License
|
|
*****************************************************************************/
|
|
|
|
#include "Plot.h"
|
|
|
|
#include <QwtRasterData>
|
|
#include <QwtPolarPanner>
|
|
#include <QwtPolarMagnifier>
|
|
#include <QwtPolarGrid>
|
|
#include <QwtPolarSpectrogram>
|
|
#include <QwtPolarRenderer>
|
|
#include <QwtPolarPicker>
|
|
#include <QwtPickerMachine>
|
|
#include <QwtScaleDiv>
|
|
#include <QwtRoundScaleDraw>
|
|
|
|
#include <QFileDialog>
|
|
#include <QPen>
|
|
#include <QLocale>
|
|
|
|
namespace
|
|
{
|
|
class Picker : public QwtPolarPicker
|
|
{
|
|
public:
|
|
Picker( QwtPolarCanvas* canvas )
|
|
: QwtPolarPicker( canvas )
|
|
{
|
|
setStateMachine( new QwtPickerDragPointMachine() );
|
|
setRubberBand( QwtPicker::NoRubberBand );
|
|
setTrackerMode( ActiveOnly );
|
|
}
|
|
|
|
virtual QwtText trackerTextPolar( const QwtPointPolar& pos ) const QWT_OVERRIDE
|
|
{
|
|
QColor bg( Qt::white );
|
|
bg.setAlpha( 200 );
|
|
|
|
QwtText text = QwtPolarPicker::trackerTextPolar( pos );
|
|
text.setBackgroundBrush( QBrush( bg ) );
|
|
return text;
|
|
}
|
|
};
|
|
|
|
// Pointless synthetic data, showing something nice
|
|
|
|
class SpectrogramData : public QwtRasterData
|
|
{
|
|
public:
|
|
SpectrogramData()
|
|
{
|
|
m_interval[Qt::ZAxis].setInterval( 0.0, 10.0 );
|
|
}
|
|
|
|
virtual double value( double azimuth, double radius ) const QWT_OVERRIDE
|
|
{
|
|
const double c = 0.842;
|
|
const double x = radius / 10.0 * 3.0 - 1.5;
|
|
const double y = azimuth / ( 2 * M_PI ) * 3.0 - 1.5;
|
|
|
|
const double v1 = qwtSqr( x ) + ( y - c ) * ( y + c );
|
|
const double v2 = 2 * x * ( y + c );
|
|
|
|
const double v = 1.0 / ( qwtSqr( v1 ) + qwtSqr( v2 ) );
|
|
return v;
|
|
}
|
|
|
|
virtual QwtInterval interval( Qt::Axis axis ) const QWT_OVERRIDE
|
|
{
|
|
return m_interval[ axis ];
|
|
}
|
|
|
|
private:
|
|
QwtInterval m_interval[3];
|
|
};
|
|
|
|
class AzimuthScaleDraw : public QwtRoundScaleDraw
|
|
{
|
|
public:
|
|
virtual QwtText label( double value ) const QWT_OVERRIDE
|
|
{
|
|
if ( qFuzzyCompare( fmod( value, 2 * M_PI ), 0.0 ) )
|
|
{
|
|
return QString( "0" );
|
|
}
|
|
|
|
if ( qFuzzyCompare( fmod( value, M_PI_4 ), 0.0 ) )
|
|
{
|
|
QString text;
|
|
if ( !qFuzzyCompare( value, M_PI ) )
|
|
{
|
|
text += QLocale().toString( value / M_PI );
|
|
text += " ";
|
|
}
|
|
text += "<FONT face=Symbol size=4>p</FONT>";
|
|
return text;
|
|
}
|
|
|
|
return QwtRoundScaleDraw::label( value );
|
|
}
|
|
};
|
|
|
|
class Grid : public QwtPolarGrid
|
|
{
|
|
public:
|
|
Grid()
|
|
{
|
|
setPen( QPen( Qt::white ) );
|
|
|
|
for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
|
|
{
|
|
showGrid( scaleId );
|
|
showMinorGrid( scaleId );
|
|
|
|
QPen minorPen( Qt::gray );
|
|
setMinorGridPen( scaleId, minorPen );
|
|
}
|
|
|
|
setAxisPen( QwtPolar::AxisAzimuth, QPen( Qt::black ) );
|
|
setAzimuthScaleDraw( new AzimuthScaleDraw() );
|
|
showAxis( QwtPolar::AxisAzimuth, true );
|
|
showAxis( QwtPolar::AxisLeft, false );
|
|
showAxis( QwtPolar::AxisRight, true );
|
|
showAxis( QwtPolar::AxisTop, false );
|
|
showAxis( QwtPolar::AxisBottom, false );
|
|
showGrid( QwtPolar::Azimuth, true );
|
|
showGrid( QwtPolar::Radius, true );
|
|
}
|
|
};
|
|
}
|
|
|
|
Plot::Plot( QWidget* parent )
|
|
: QwtPolarPlot( parent )
|
|
{
|
|
setAutoReplot( false );
|
|
setPlotBackground( Qt::darkBlue );
|
|
|
|
// scales
|
|
setScale( QwtPolar::Azimuth, 0.0, 2 * M_PI, M_PI_4 );
|
|
setScaleMaxMinor( QwtPolar::Azimuth, 2 );
|
|
|
|
setScale( QwtPolar::Radius, 0.0, 10.0 );
|
|
setScaleMaxMinor( QwtPolar::Radius, 2 );
|
|
|
|
// grids
|
|
m_grid = new Grid();
|
|
m_grid->attach( this );
|
|
|
|
// spectrogram
|
|
|
|
m_spectrogram = new QwtPolarSpectrogram();
|
|
m_spectrogram->setPaintAttribute(
|
|
QwtPolarSpectrogram::ApproximatedAtan, true );
|
|
m_spectrogram->setRenderThreadCount( 0 ); // use multi threading
|
|
m_spectrogram->setData( new SpectrogramData() );
|
|
m_spectrogram->attach( this );
|
|
|
|
m_spectrogram->setZ( 1.0 );
|
|
m_grid->setZ( 2.0 );
|
|
|
|
Picker* picker = new Picker( canvas() );
|
|
picker->setMousePattern( QwtEventPattern::MouseSelect1, Qt::RightButton );
|
|
|
|
QwtPolarMagnifier* magnifier = new QwtPolarMagnifier( canvas() );
|
|
magnifier->setMouseButton( Qt::RightButton, Qt::ShiftModifier );
|
|
|
|
new QwtPolarPanner( canvas() );
|
|
}
|
|
|
|
QwtPolarSpectrogram* Plot::spectrogram()
|
|
{
|
|
return m_spectrogram;
|
|
}
|
|
|
|
void Plot::rotate()
|
|
{
|
|
const double interval = 15.0; // degrees
|
|
|
|
double origin = azimuthOrigin() / M_PI * 180.0;
|
|
origin = qRound( origin / interval ) * interval + interval;
|
|
|
|
setAzimuthOrigin( origin / 180.0 * M_PI );
|
|
replot();
|
|
}
|
|
|
|
void Plot::mirror()
|
|
{
|
|
const double a1 = scaleDiv( QwtPolar::Azimuth )->upperBound();
|
|
const double a2 = scaleDiv( QwtPolar::Azimuth )->lowerBound();
|
|
|
|
setScale( QwtPolar::Azimuth, a1, a2, qAbs( a2 - a1 ) / 8.0 );
|
|
replot();
|
|
}
|
|
|
|
void Plot::exportDocument()
|
|
{
|
|
QwtPolarRenderer renderer;
|
|
renderer.exportTo( this, "spectrogram.pdf", QSizeF( 200, 200 ), 300 );
|
|
}
|
|
|
|
void Plot::showGrid( bool on )
|
|
{
|
|
m_grid->setVisible( on );
|
|
replot();
|
|
}
|
|
|
|
#include "moc_Plot.cpp"
|