summaryrefslogtreecommitdiff
path: root/src/libpcp_qwt/src/qwt_compass_rose.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libpcp_qwt/src/qwt_compass_rose.cpp')
-rw-r--r--src/libpcp_qwt/src/qwt_compass_rose.cpp265
1 files changed, 265 insertions, 0 deletions
diff --git a/src/libpcp_qwt/src/qwt_compass_rose.cpp b/src/libpcp_qwt/src/qwt_compass_rose.cpp
new file mode 100644
index 0000000..375a5bd
--- /dev/null
+++ b/src/libpcp_qwt/src/qwt_compass_rose.cpp
@@ -0,0 +1,265 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997 Josef Wilgen
+ * Copyright (C) 2002 Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_compass_rose.h"
+#include "qwt_point_polar.h"
+#include "qwt_painter.h"
+#include <qpainter.h>
+
+static QPointF qwtIntersection(
+ QPointF p11, QPointF p12, QPointF p21, QPointF p22 )
+{
+ const QLineF line1( p11, p12 );
+ const QLineF line2( p21, p22 );
+
+ QPointF pos;
+ if ( line1.intersect( line2, &pos ) == QLineF::NoIntersection )
+ return QPointF();
+
+ return pos;
+}
+
+class QwtSimpleCompassRose::PrivateData
+{
+public:
+ PrivateData():
+ width( 0.2 ),
+ numThorns( 8 ),
+ numThornLevels( -1 ),
+ shrinkFactor( 0.9 )
+ {
+ }
+
+ double width;
+ int numThorns;
+ int numThornLevels;
+ double shrinkFactor;
+};
+
+/*!
+ Constructor
+
+ \param numThorns Number of thorns
+ \param numThornLevels Number of thorn levels
+*/
+QwtSimpleCompassRose::QwtSimpleCompassRose(
+ int numThorns, int numThornLevels )
+{
+ d_data = new PrivateData();
+ d_data->numThorns = numThorns;
+ d_data->numThornLevels = numThornLevels;
+
+ const QColor dark( 128, 128, 255 );
+ const QColor light( 192, 255, 255 );
+
+ QPalette palette;
+ palette.setColor( QPalette::Dark, dark );
+ palette.setColor( QPalette::Light, light );
+
+ setPalette( palette );
+}
+
+//! Destructor
+QwtSimpleCompassRose::~QwtSimpleCompassRose()
+{
+ delete d_data;
+}
+
+/*!
+ Set the Factor how to shrink the thorns with each level
+ The default value is 0.9.
+
+ \sa shrinkFactor()
+*/
+void QwtSimpleCompassRose::setShrinkFactor( double factor )
+{
+ d_data->shrinkFactor = factor;
+}
+
+/*!
+ \return Factor how to shrink the thorns with each level
+ \sa setShrinkFactor()
+*/
+double QwtSimpleCompassRose::shrinkFactor() const
+{
+ return d_data->shrinkFactor;
+}
+
+/*!
+ Draw the rose
+
+ \param painter Painter
+ \param center Center point
+ \param radius Radius of the rose
+ \param north Position
+ \param cg Color group
+*/
+void QwtSimpleCompassRose::draw( QPainter *painter, const QPointF &center,
+ double radius, double north, QPalette::ColorGroup cg ) const
+{
+ QPalette pal = palette();
+ pal.setCurrentColorGroup( cg );
+
+ drawRose( painter, pal, center, radius, north, d_data->width,
+ d_data->numThorns, d_data->numThornLevels, d_data->shrinkFactor );
+}
+
+/*!
+ Draw the rose
+
+ \param painter Painter
+ \param palette Palette
+ \param center Center of the rose
+ \param radius Radius of the rose
+ \param north Position pointing to north
+ \param width Width of the rose
+ \param numThorns Number of thorns
+ \param numThornLevels Number of thorn levels
+ \param shrinkFactor Factor to shrink the thorns with each level
+*/
+void QwtSimpleCompassRose::drawRose(
+ QPainter *painter,
+ const QPalette &palette,
+ const QPointF &center, double radius, double north, double width,
+ int numThorns, int numThornLevels, double shrinkFactor )
+{
+ if ( numThorns < 4 )
+ numThorns = 4;
+
+ if ( numThorns % 4 )
+ numThorns += 4 - numThorns % 4;
+
+ if ( numThornLevels <= 0 )
+ numThornLevels = numThorns / 4;
+
+ if ( shrinkFactor >= 1.0 )
+ shrinkFactor = 1.0;
+
+ if ( shrinkFactor <= 0.5 )
+ shrinkFactor = 0.5;
+
+ painter->save();
+
+ painter->setPen( Qt::NoPen );
+
+ for ( int j = 1; j <= numThornLevels; j++ )
+ {
+ double step = qPow( 2.0, j ) * M_PI / numThorns;
+ if ( step > M_PI_2 )
+ break;
+
+ double r = radius;
+ for ( int k = 0; k < 3; k++ )
+ {
+ if ( j + k < numThornLevels )
+ r *= shrinkFactor;
+ }
+
+ double leafWidth = r * width;
+ if ( 2.0 * M_PI / step > 32 )
+ leafWidth = 16;
+
+ const double origin = north / 180.0 * M_PI;
+ for ( double angle = origin;
+ angle < 2.0 * M_PI + origin; angle += step )
+ {
+ const QPointF p = qwtPolar2Pos( center, r, angle );
+ const QPointF p1 = qwtPolar2Pos( center, leafWidth, angle + M_PI_2 );
+ const QPointF p2 = qwtPolar2Pos( center, leafWidth, angle - M_PI_2 );
+ const QPointF p3 = qwtPolar2Pos( center, r, angle + step / 2.0 );
+ const QPointF p4 = qwtPolar2Pos( center, r, angle - step / 2.0 );
+
+ QPainterPath darkPath;
+ darkPath.moveTo( center );
+ darkPath.lineTo( p );
+ darkPath.lineTo( qwtIntersection( center, p3, p1, p ) );
+
+ painter->setBrush( palette.brush( QPalette::Dark ) );
+ painter->drawPath( darkPath );
+
+ QPainterPath lightPath;
+ lightPath.moveTo( center );
+ lightPath.lineTo( p );
+ lightPath.lineTo( qwtIntersection( center, p4, p2, p ) );
+
+ painter->setBrush( palette.brush( QPalette::Light ) );
+ painter->drawPath( lightPath );
+ }
+ }
+ painter->restore();
+}
+
+/*!
+ Set the width of the rose heads. Lower value make thinner heads.
+ The range is limited from 0.03 to 0.4.
+
+ \param width Width
+*/
+void QwtSimpleCompassRose::setWidth( double width )
+{
+ d_data->width = width;
+ if ( d_data->width < 0.03 )
+ d_data->width = 0.03;
+
+ if ( d_data->width > 0.4 )
+ d_data->width = 0.4;
+}
+
+//! \sa setWidth()
+double QwtSimpleCompassRose::width() const
+{
+ return d_data->width;
+}
+
+/*!
+ Set the number of thorns on one level
+ The number is aligned to a multiple of 4, with a minimum of 4
+
+ \param numThorns Number of thorns
+ \sa numThorns(), setNumThornLevels()
+*/
+void QwtSimpleCompassRose::setNumThorns( int numThorns )
+{
+ if ( numThorns < 4 )
+ numThorns = 4;
+
+ if ( numThorns % 4 )
+ numThorns += 4 - numThorns % 4;
+
+ d_data->numThorns = numThorns;
+}
+
+/*!
+ \return Number of thorns
+ \sa setNumThorns(), setNumThornLevels()
+*/
+int QwtSimpleCompassRose::numThorns() const
+{
+ return d_data->numThorns;
+}
+
+/*!
+ Set the of thorns levels
+
+ \param numThornLevels Number of thorns levels
+ \sa setNumThorns(), numThornLevels()
+*/
+void QwtSimpleCompassRose::setNumThornLevels( int numThornLevels )
+{
+ d_data->numThornLevels = numThornLevels;
+}
+
+/*!
+ \return Number of thorn levels
+ \sa setNumThorns(), setNumThornLevels()
+*/
+int QwtSimpleCompassRose::numThornLevels() const
+{
+ return d_data->numThornLevels;
+}