00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "qwt_compass_rose.h"
00011 #include "qwt_point_polar.h"
00012 #include "qwt_painter.h"
00013 #include <qpainter.h>
00014
00015 static QPointF qwtIntersection(
00016 QPointF p11, QPointF p12, QPointF p21, QPointF p22 )
00017 {
00018 const QLineF line1( p11, p12 );
00019 const QLineF line2( p21, p22 );
00020
00021 QPointF pos;
00022 if ( line1.intersect( line2, &pos ) == QLineF::NoIntersection )
00023 return QPointF();
00024
00025 return pos;
00026 }
00027
00029 QwtCompassRose::QwtCompassRose()
00030 {
00031 }
00032
00034 QwtCompassRose::~QwtCompassRose()
00035 {
00036 }
00037
00039 void QwtCompassRose::setPalette( const QPalette &p )
00040 {
00041 d_palette = p;
00042 }
00043
00045 const QPalette &QwtCompassRose::palette() const
00046 {
00047 return d_palette;
00048 }
00049
00050 class QwtSimpleCompassRose::PrivateData
00051 {
00052 public:
00053 PrivateData():
00054 width( 0.2 ),
00055 numThorns( 8 ),
00056 numThornLevels( -1 ),
00057 shrinkFactor( 0.9 )
00058 {
00059 }
00060
00061 double width;
00062 int numThorns;
00063 int numThornLevels;
00064 double shrinkFactor;
00065 };
00066
00073 QwtSimpleCompassRose::QwtSimpleCompassRose(
00074 int numThorns, int numThornLevels )
00075 {
00076 d_data = new PrivateData();
00077 d_data->numThorns = numThorns;
00078 d_data->numThornLevels = numThornLevels;
00079
00080 const QColor dark( 128, 128, 255 );
00081 const QColor light( 192, 255, 255 );
00082
00083 QPalette palette;
00084 palette.setColor( QPalette::Dark, dark );
00085 palette.setColor( QPalette::Light, light );
00086
00087 setPalette( palette );
00088 }
00089
00091 QwtSimpleCompassRose::~QwtSimpleCompassRose()
00092 {
00093 delete d_data;
00094 }
00095
00103 void QwtSimpleCompassRose::setShrinkFactor( double factor )
00104 {
00105 d_data->shrinkFactor = factor;
00106 }
00107
00112 double QwtSimpleCompassRose::shrinkFactor() const
00113 {
00114 return d_data->shrinkFactor;
00115 }
00116
00126 void QwtSimpleCompassRose::draw( QPainter *painter, const QPointF ¢er,
00127 double radius, double north, QPalette::ColorGroup cg ) const
00128 {
00129 QPalette pal = palette();
00130 pal.setCurrentColorGroup( cg );
00131
00132 drawRose( painter, pal, center, radius, north, d_data->width,
00133 d_data->numThorns, d_data->numThornLevels, d_data->shrinkFactor );
00134 }
00135
00149 void QwtSimpleCompassRose::drawRose(
00150 QPainter *painter,
00151 const QPalette &palette,
00152 const QPointF ¢er, double radius, double north, double width,
00153 int numThorns, int numThornLevels, double shrinkFactor )
00154 {
00155 if ( numThorns < 4 )
00156 numThorns = 4;
00157
00158 if ( numThorns % 4 )
00159 numThorns += 4 - numThorns % 4;
00160
00161 if ( numThornLevels <= 0 )
00162 numThornLevels = numThorns / 4;
00163
00164 if ( shrinkFactor >= 1.0 )
00165 shrinkFactor = 1.0;
00166
00167 if ( shrinkFactor <= 0.5 )
00168 shrinkFactor = 0.5;
00169
00170 painter->save();
00171
00172 painter->setPen( Qt::NoPen );
00173
00174 for ( int j = 1; j <= numThornLevels; j++ )
00175 {
00176 double step = qPow( 2.0, j ) * M_PI / numThorns;
00177 if ( step > M_PI_2 )
00178 break;
00179
00180 double r = radius;
00181 for ( int k = 0; k < 3; k++ )
00182 {
00183 if ( j + k < numThornLevels )
00184 r *= shrinkFactor;
00185 }
00186
00187 double leafWidth = r * width;
00188 if ( 2.0 * M_PI / step > 32 )
00189 leafWidth = 16;
00190
00191 const double origin = qwtRadians( north );
00192 for ( double angle = origin;
00193 angle < 2.0 * M_PI + origin; angle += step )
00194 {
00195 const QPointF p = qwtPolar2Pos( center, r, angle );
00196 const QPointF p1 = qwtPolar2Pos( center, leafWidth, angle + M_PI_2 );
00197 const QPointF p2 = qwtPolar2Pos( center, leafWidth, angle - M_PI_2 );
00198 const QPointF p3 = qwtPolar2Pos( center, r, angle + step / 2.0 );
00199 const QPointF p4 = qwtPolar2Pos( center, r, angle - step / 2.0 );
00200
00201 QPainterPath darkPath;
00202 darkPath.moveTo( center );
00203 darkPath.lineTo( p );
00204 darkPath.lineTo( qwtIntersection( center, p3, p1, p ) );
00205
00206 painter->setBrush( palette.brush( QPalette::Dark ) );
00207 painter->drawPath( darkPath );
00208
00209 QPainterPath lightPath;
00210 lightPath.moveTo( center );
00211 lightPath.lineTo( p );
00212 lightPath.lineTo( qwtIntersection( center, p4, p2, p ) );
00213
00214 painter->setBrush( palette.brush( QPalette::Light ) );
00215 painter->drawPath( lightPath );
00216 }
00217 }
00218 painter->restore();
00219 }
00220
00227 void QwtSimpleCompassRose::setWidth( double width )
00228 {
00229 d_data->width = width;
00230 if ( d_data->width < 0.03 )
00231 d_data->width = 0.03;
00232
00233 if ( d_data->width > 0.4 )
00234 d_data->width = 0.4;
00235 }
00236
00241 double QwtSimpleCompassRose::width() const
00242 {
00243 return d_data->width;
00244 }
00245
00253 void QwtSimpleCompassRose::setNumThorns( int numThorns )
00254 {
00255 if ( numThorns < 4 )
00256 numThorns = 4;
00257
00258 if ( numThorns % 4 )
00259 numThorns += 4 - numThorns % 4;
00260
00261 d_data->numThorns = numThorns;
00262 }
00263
00268 int QwtSimpleCompassRose::numThorns() const
00269 {
00270 return d_data->numThorns;
00271 }
00272
00279 void QwtSimpleCompassRose::setNumThornLevels( int numThornLevels )
00280 {
00281 d_data->numThornLevels = numThornLevels;
00282 }
00283
00288 int QwtSimpleCompassRose::numThornLevels() const
00289 {
00290 return d_data->numThornLevels;
00291 }