qwt_compass_rose.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
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 &center, 
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 &center, 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 }

Generated on Mon Feb 26 21:22:36 2007 for Qwt User's Guide by  doxygen 1.4.6