00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <math.h>
00011 #include <qpainter.h>
00012 #include "qwt_math.h"
00013 #include "qwt_painter.h"
00014 #include "qwt_compass_rose.h"
00015
00016 static QPoint cutPoint(QPoint p11, QPoint p12, QPoint p21, QPoint p22)
00017 {
00018 double dx1 = p12.x() - p11.x();
00019 double dy1 = p12.y() - p11.y();
00020 double dx2 = p22.x() - p21.x();
00021 double dy2 = p22.y() - p21.y();
00022
00023 if ( dx1 == 0.0 && dx2 == 0.0 )
00024 return QPoint();
00025
00026 if ( dx1 == 0.0 )
00027 {
00028 const double m = dy2 / dx2;
00029 const double t = p21.y() - m * p21.x();
00030 return QPoint(p11.x(), qRound(m * p11.x() + t));
00031 }
00032
00033 if ( dx2 == 0 )
00034 {
00035 const double m = dy1 / dx1;
00036 const double t = p11.y() - m * p11.x();
00037 return QPoint(p21.x(), qRound(m * p21.x() + t));
00038 }
00039
00040 const double m1 = dy1 / dx1;
00041 const double t1 = p11.y() - m1 * p11.x();
00042
00043 const double m2 = dy2 / dx2;
00044 const double t2 = p21.y() - m2 * p21.x();
00045
00046 if ( m1 == m2 )
00047 return QPoint();
00048
00049 const double x = ( t2 - t1 ) / ( m1 - m2 );
00050 const double y = t1 + m1 * x;
00051
00052 return QPoint(qRound(x), qRound(y));
00053 }
00054
00061 QwtSimpleCompassRose::QwtSimpleCompassRose(int numThorns, int numThornLevels):
00062 d_width(0.2),
00063 d_numThorns(numThorns),
00064 d_numThornLevels(numThornLevels),
00065 d_shrinkFactor(0.9)
00066 {
00067 const QColor dark(128,128,255);
00068 const QColor light(192,255,255);
00069
00070 QPalette palette;
00071 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00072 {
00073 #if QT_VERSION < 0x040000
00074 palette.setColor((QPalette::ColorGroup)i,
00075 QColorGroup::Dark, dark);
00076 palette.setColor((QPalette::ColorGroup)i,
00077 QColorGroup::Light, light);
00078 #else
00079 palette.setColor((QPalette::ColorGroup)i,
00080 QPalette::Dark, dark);
00081 palette.setColor((QPalette::ColorGroup)i,
00082 QPalette::Light, light);
00083 #endif
00084 }
00085
00086 setPalette(palette);
00087 }
00088
00098 void QwtSimpleCompassRose::draw(QPainter *painter, const QPoint ¢er,
00099 int radius, double north, QPalette::ColorGroup cg) const
00100 {
00101 #if QT_VERSION < 0x040000
00102 QColorGroup colorGroup;
00103 switch(cg)
00104 {
00105 case QPalette::Disabled:
00106 colorGroup = palette().disabled();
00107 case QPalette::Inactive:
00108 colorGroup = palette().inactive();
00109 default:
00110 colorGroup = palette().active();
00111 }
00112
00113 drawRose(painter, colorGroup, center, radius, north, d_width,
00114 d_numThorns, d_numThornLevels, d_shrinkFactor);
00115 #else
00116 QPalette pal = palette();
00117 pal.setCurrentColorGroup(cg);
00118 drawRose(painter, pal, center, radius, north, d_width,
00119 d_numThorns, d_numThornLevels, d_shrinkFactor);
00120 #endif
00121 }
00122
00136 void QwtSimpleCompassRose::drawRose(
00137 QPainter *painter,
00138 #if QT_VERSION < 0x040000
00139 const QColorGroup &cg,
00140 #else
00141 const QPalette &palette,
00142 #endif
00143 const QPoint ¢er, int radius, double north, double width,
00144 int numThorns, int numThornLevels, double shrinkFactor)
00145 {
00146 if ( numThorns < 4 )
00147 numThorns = 4;
00148
00149 if ( numThorns % 4 )
00150 numThorns += 4 - numThorns % 4;
00151
00152 if ( numThornLevels <= 0 )
00153 numThornLevels = numThorns / 4;
00154
00155 if ( shrinkFactor >= 1.0 )
00156 shrinkFactor = 1.0;
00157
00158 if ( shrinkFactor <= 0.5 )
00159 shrinkFactor = 0.5;
00160
00161 painter->save();
00162
00163 painter->setPen(Qt::NoPen);
00164
00165 for ( int j = 1; j <= numThornLevels; j++ )
00166 {
00167 double step = pow(2.0, j) * M_PI / (double)numThorns;
00168 if ( step > M_PI_2 )
00169 break;
00170
00171 double r = radius;
00172 for ( int k = 0; k < 3; k++ )
00173 {
00174 if ( j + k < numThornLevels )
00175 r *= shrinkFactor;
00176 }
00177
00178 double leafWidth = r * width;
00179 if ( 2.0 * M_PI / step > 32 )
00180 leafWidth = 16;
00181
00182 const double origin = north / 180.0 * M_PI;
00183 for ( double angle = origin;
00184 angle < 2.0 * M_PI + origin; angle += step)
00185 {
00186 const QPoint p = qwtPolar2Pos(center, r, angle);
00187 QPoint p1 = qwtPolar2Pos(center, leafWidth, angle + M_PI_2);
00188 QPoint p2 = qwtPolar2Pos(center, leafWidth, angle - M_PI_2);
00189
00190 QwtPolygon pa(3);
00191 pa.setPoint(0, center);
00192 pa.setPoint(1, p);
00193
00194 QPoint p3 = qwtPolar2Pos(center, r, angle + step / 2.0);
00195 p1 = cutPoint(center, p3, p1, p);
00196 pa.setPoint(2, p1);
00197 #if QT_VERSION < 0x040000
00198 painter->setBrush(cg.brush(QColorGroup::Dark));
00199 #else
00200 painter->setBrush(palette.brush(QPalette::Dark));
00201 #endif
00202 painter->drawPolygon(pa);
00203
00204 QPoint p4 = qwtPolar2Pos(center, r, angle - step / 2.0);
00205 p2 = cutPoint(center, p4, p2, p);
00206
00207 pa.setPoint(2, p2);
00208 #if QT_VERSION < 0x040000
00209 painter->setBrush(cg.brush(QColorGroup::Light));
00210 #else
00211 painter->setBrush(palette.brush(QPalette::Light));
00212 #endif
00213 painter->drawPolygon(pa);
00214 }
00215 }
00216 painter->restore();
00217 }
00218
00226 void QwtSimpleCompassRose::setWidth(double width)
00227 {
00228 d_width = width;
00229 if (d_width < 0.03)
00230 d_width = 0.03;
00231
00232 if (d_width > 0.4)
00233 d_width = 0.4;
00234 }
00235
00243 void QwtSimpleCompassRose::setNumThorns(int numThorns)
00244 {
00245 if ( numThorns < 4 )
00246 numThorns = 4;
00247
00248 if ( numThorns % 4 )
00249 numThorns += 4 - numThorns % 4;
00250
00251 d_numThorns = numThorns;
00252 }
00253
00258 int QwtSimpleCompassRose::numThorns() const
00259 {
00260 return d_numThorns;
00261 }
00262
00269 void QwtSimpleCompassRose::setNumThornLevels(int numThornLevels)
00270 {
00271 d_numThornLevels = numThornLevels;
00272 }
00273
00278 int QwtSimpleCompassRose::numThornLevels() const
00279 {
00280 return d_numThornLevels;
00281 }