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 #if QT_VERSION < 0x040000
00017 #include <qpointarray.h>
00018 #define QwtPointArray QPointArray
00019 #else
00020 #include <qpolygon.h>
00021 #define QwtPointArray QPolygon
00022 #endif
00023
00024 static QPoint cutPoint(QPoint p11, QPoint p12, QPoint p21, QPoint p22)
00025 {
00026 double dx1 = p12.x() - p11.x();
00027 double dy1 = p12.y() - p11.y();
00028 double dx2 = p22.x() - p21.x();
00029 double dy2 = p22.y() - p21.y();
00030
00031 if ( dx1 == 0.0 && dx2 == 0.0 )
00032 return QPoint();
00033
00034 if ( dx1 == 0.0 )
00035 {
00036 const double m = dy2 / dx2;
00037 const double t = p21.y() - m * p21.x();
00038 return QPoint(p11.x(), qRound(m * p11.x() + t));
00039 }
00040
00041 if ( dx2 == 0 )
00042 {
00043 const double m = dy1 / dx1;
00044 const double t = p11.y() - m * p11.x();
00045 return QPoint(p21.x(), qRound(m * p21.x() + t));
00046 }
00047
00048 const double m1 = dy1 / dx1;
00049 const double t1 = p11.y() - m1 * p11.x();
00050
00051 const double m2 = dy2 / dx2;
00052 const double t2 = p21.y() - m2 * p21.x();
00053
00054 if ( m1 == m2 )
00055 return QPoint();
00056
00057 const double x = ( t2 - t1 ) / ( m1 - m2 );
00058 const double y = t1 + m1 * x;
00059
00060 return QPoint(qRound(x), qRound(y));
00061 }
00062
00063 QwtSimpleCompassRose::QwtSimpleCompassRose(int numThorns, int numThornLevels):
00064 d_width(0.2),
00065 d_numThorns(numThorns),
00066 d_numThornLevels(numThornLevels),
00067 d_shrinkFactor(0.9)
00068 {
00069 const QColor dark(128,128,255);
00070 const QColor light(192,255,255);
00071
00072 QPalette palette;
00073 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00074 {
00075 #if QT_VERSION < 0x040000
00076 palette.setColor((QPalette::ColorGroup)i,
00077 QColorGroup::Dark, dark);
00078 palette.setColor((QPalette::ColorGroup)i,
00079 QColorGroup::Light, light);
00080 #else
00081 palette.setColor((QPalette::ColorGroup)i,
00082 QPalette::Dark, dark);
00083 palette.setColor((QPalette::ColorGroup)i,
00084 QPalette::Light, light);
00085 #endif
00086 }
00087
00088 setPalette(palette);
00089 }
00090
00091 void QwtSimpleCompassRose::draw(QPainter *painter, const QPoint ¢er,
00092 int radius, double north, QPalette::ColorGroup cg) const
00093 {
00094 #if QT_VERSION < 0x040000
00095 QColorGroup colorGroup;
00096 switch(cg)
00097 {
00098 case QPalette::Disabled:
00099 colorGroup = palette().disabled();
00100 case QPalette::Inactive:
00101 colorGroup = palette().inactive();
00102 default:
00103 colorGroup = palette().active();
00104 }
00105
00106 drawRose(painter, colorGroup, center, radius, north, d_width,
00107 d_numThorns, d_numThornLevels, d_shrinkFactor);
00108 #else
00109 QPalette pal = palette();
00110 pal.setCurrentColorGroup(cg);
00111 drawRose(painter, pal, center, radius, north, d_width,
00112 d_numThorns, d_numThornLevels, d_shrinkFactor);
00113 #endif
00114 }
00115
00116 void QwtSimpleCompassRose::drawRose(
00117 QPainter *painter,
00118 #if QT_VERSION < 0x040000
00119 const QColorGroup &cg,
00120 #else
00121 const QPalette &palette,
00122 #endif
00123 const QPoint ¢er, int radius, double north, double width,
00124 int numThorns, int numThornLevels, double shrinkFactor)
00125 {
00126 if ( numThorns < 4 )
00127 numThorns = 4;
00128
00129 if ( numThorns % 4 )
00130 numThorns += 4 - numThorns % 4;
00131
00132 if ( numThornLevels <= 0 )
00133 numThornLevels = numThorns / 4;
00134
00135 if ( shrinkFactor >= 1.0 )
00136 shrinkFactor = 1.0;
00137
00138 if ( shrinkFactor <= 0.5 )
00139 shrinkFactor = 0.5;
00140
00141 painter->save();
00142
00143 painter->setPen(Qt::NoPen);
00144
00145 for ( int j = 1; j <= numThornLevels; j++ )
00146 {
00147 double step = pow(2.0, j) * M_PI / (double)numThorns;
00148 if ( step > M_PI_2 )
00149 break;
00150
00151 double r = radius;
00152 for ( int k = 0; k < 3; k++ )
00153 {
00154 if ( j + k < numThornLevels )
00155 r *= shrinkFactor;
00156 }
00157
00158 double leafWidth = r * width;
00159 if ( 2.0 * M_PI / step > 32 )
00160 leafWidth = 16;
00161
00162 const double origin = north / 180.0 * M_PI;
00163 for ( double angle = origin;
00164 angle < 2.0 * M_PI + origin; angle += step)
00165 {
00166 const QPoint p = qwtPolar2Pos(center, r, angle);
00167 QPoint p1 = qwtPolar2Pos(center, leafWidth, angle + M_PI_2);
00168 QPoint p2 = qwtPolar2Pos(center, leafWidth, angle - M_PI_2);
00169
00170 QwtPointArray pa(3);
00171 pa.setPoint(0, center);
00172 pa.setPoint(1, p);
00173
00174 QPoint p3 = qwtPolar2Pos(center, r, angle + step / 2.0);
00175 p1 = cutPoint(center, p3, p1, p);
00176 pa.setPoint(2, p1);
00177 #if QT_VERSION < 0x040000
00178 painter->setBrush(cg.brush(QColorGroup::Dark));
00179 #else
00180 painter->setBrush(palette.brush(QPalette::Dark));
00181 #endif
00182 painter->drawPolygon(pa);
00183
00184 QPoint p4 = qwtPolar2Pos(center, r, angle - step / 2.0);
00185 p2 = cutPoint(center, p4, p2, p);
00186
00187 pa.setPoint(2, p2);
00188 #if QT_VERSION < 0x040000
00189 painter->setBrush(cg.brush(QColorGroup::Light));
00190 #else
00191 painter->setBrush(palette.brush(QPalette::Light));
00192 #endif
00193 painter->drawPolygon(pa);
00194 }
00195 }
00196 painter->restore();
00197 }
00198
00204 void QwtSimpleCompassRose::setWidth(double w)
00205 {
00206 d_width = w;
00207 if (d_width < 0.03)
00208 d_width = 0.03;
00209
00210 if (d_width > 0.4)
00211 d_width = 0.4;
00212 }
00213
00214 void QwtSimpleCompassRose::setNumThorns(int numThorns)
00215 {
00216 if ( numThorns < 4 )
00217 numThorns = 4;
00218
00219 if ( numThorns % 4 )
00220 numThorns += 4 - numThorns % 4;
00221
00222 d_numThorns = numThorns;
00223 }
00224
00225 int QwtSimpleCompassRose::numThorns() const
00226 {
00227 return d_numThorns;
00228 }
00229
00230 void QwtSimpleCompassRose::setNumThornLevels(int numThornLevels)
00231 {
00232 d_numThornLevels = numThornLevels;
00233 }
00234
00235 int QwtSimpleCompassRose::numThornLevels() const
00236 {
00237 return d_numThornLevels;
00238 }