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(), qwtInt(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(), qwtInt(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(qwtInt(x), qwtInt(y));
00053 }
00054
00055 QwtSimpleCompassRose::QwtSimpleCompassRose(
int numThorns,
int numThornLevels):
00056 d_width(0.2),
00057 d_numThorns(numThorns),
00058 d_numThornLevels(numThornLevels),
00059 d_shrinkFactor(0.9)
00060 {
00061
const QColor dark(128,128,255);
00062
const QColor light(192,255,255);
00063
00064 QPalette palette;
00065
for (
int i = 0; i < QPalette::NColorGroups; i++ )
00066 {
00067 palette.setColor((QPalette::ColorGroup)i,
00068 QColorGroup::Dark, dark);
00069 palette.setColor((QPalette::ColorGroup)i,
00070 QColorGroup::Light, light);
00071 }
00072
00073 setPalette(palette);
00074 }
00075
00076
void QwtSimpleCompassRose::draw(QPainter *painter,
const QPoint ¢er,
00077
int radius,
double north, QPalette::ColorGroup cg)
const
00078
{
00079 QColorGroup colorGroup;
00080
switch(cg)
00081 {
00082
case QPalette::Disabled:
00083 colorGroup = palette().disabled();
00084
case QPalette::Inactive:
00085 colorGroup = palette().inactive();
00086
default:
00087 colorGroup = palette().active();
00088 }
00089
00090
drawRose(painter, colorGroup, center, radius, north, d_width,
00091 d_numThorns, d_numThornLevels, d_shrinkFactor);
00092 }
00093
00094
void QwtSimpleCompassRose::drawRose(
00095 QPainter *painter,
const QColorGroup &cg,
00096
const QPoint ¢er,
int radius,
double north,
double width,
00097
int numThorns,
int numThornLevels,
double shrinkFactor)
00098 {
00099
if ( numThorns < 4 )
00100 numThorns = 4;
00101
00102
if ( numThorns % 4 )
00103 numThorns += 4 - numThorns % 4;
00104
00105
if ( numThornLevels <= 0 )
00106 numThornLevels = numThorns / 4;
00107
00108
if ( shrinkFactor >= 1.0 )
00109 shrinkFactor = 1.0;
00110
00111
if ( shrinkFactor <= 0.5 )
00112 shrinkFactor = 0.5;
00113
00114 painter->save();
00115
00116 painter->setPen(Qt::NoPen);
00117
00118
for (
int j = 1; j <= numThornLevels; j++ )
00119 {
00120
double step = pow(2.0, j) * M_PI / (
double)numThorns;
00121
if ( step > M_PI_2 )
00122
break;
00123
00124
double r = radius;
00125
for (
int k = 0; k < 3; k++ )
00126 {
00127
if ( j + k < numThornLevels )
00128 r *= shrinkFactor;
00129 }
00130
00131
double leafWidth = r * width;
00132
if ( 2.0 * M_PI / step > 32 )
00133 leafWidth = 16;
00134
00135
const double origin = north / 180.0 * M_PI;
00136
for (
double angle = origin;
00137 angle < 2.0 * M_PI + origin; angle += step)
00138 {
00139
const QPoint p = qwtPolar2Pos(center, r, angle);
00140 QPoint p1 = qwtPolar2Pos(center, leafWidth, angle + M_PI_2);
00141 QPoint p2 = qwtPolar2Pos(center, leafWidth, angle - M_PI_2);
00142
00143 QPointArray pa(3);
00144 pa.setPoint(0, center);
00145 pa.setPoint(1, p);
00146
00147 QPoint p3 = qwtPolar2Pos(center, r, angle + step / 2.0);
00148 p1 = cutPoint(center, p3, p1, p);
00149 pa.setPoint(2, p1);
00150 painter->setBrush(cg.brush(QColorGroup::Dark));
00151 painter->drawPolygon(pa);
00152
00153 QPoint p4 = qwtPolar2Pos(center, r, angle - step / 2.0);
00154 p2 = cutPoint(center, p4, p2, p);
00155
00156 pa.setPoint(2, p2);
00157 painter->setBrush(cg.brush(QColorGroup::Light));
00158 painter->drawPolygon(pa);
00159 }
00160 }
00161 painter->restore();
00162 }
00163
00169
void QwtSimpleCompassRose::setWidth(
double w)
00170 {
00171 d_width = w;
00172
if (d_width < 0.03)
00173 d_width = 0.03;
00174
00175
if (d_width > 0.4)
00176 d_width = 0.4;
00177 }
00178
00179
void QwtSimpleCompassRose::setNumThorns(
int numThorns)
00180 {
00181
if ( numThorns < 4 )
00182 numThorns = 4;
00183
00184
if ( numThorns % 4 )
00185 numThorns += 4 - numThorns % 4;
00186
00187 d_numThorns = numThorns;
00188 }
00189
00190
int QwtSimpleCompassRose::numThorns()
const
00191
{
00192
return d_numThorns;
00193 }
00194
00195
void QwtSimpleCompassRose::setNumThornLevels(
int numThornLevels)
00196 {
00197 d_numThornLevels = numThornLevels;
00198 }
00199
00200
int QwtSimpleCompassRose::numThornLevels()
const
00201
{
00202
return d_numThornLevels;
00203 }