270 lines
6.5 KiB
C++
270 lines
6.5 KiB
C++
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
|
|
* Qwt Widget Library
|
|
* Copyright (C) 1997 Josef Wilgen
|
|
* Copyright (C) 2002 Uwe Rathmann
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the Qwt License, Version 1.0
|
|
*****************************************************************************/
|
|
|
|
#include "qwt_compass_rose.h"
|
|
#include "qwt_point_polar.h"
|
|
#include "qwt_painter.h"
|
|
#include <qpainter.h>
|
|
|
|
static QPointF qwtIntersection(
|
|
QPointF p11, QPointF p12, QPointF p21, QPointF p22 )
|
|
{
|
|
const QLineF line1( p11, p12 );
|
|
const QLineF line2( p21, p22 );
|
|
|
|
QPointF pos;
|
|
if ( line1.intersect( line2, &pos ) == QLineF::NoIntersection )
|
|
return QPointF();
|
|
|
|
return pos;
|
|
}
|
|
|
|
class QwtSimpleCompassRose::PrivateData
|
|
{
|
|
public:
|
|
PrivateData():
|
|
width( 0.2 ),
|
|
numThorns( 8 ),
|
|
numThornLevels( -1 ),
|
|
shrinkFactor( 0.9 )
|
|
{
|
|
}
|
|
|
|
double width;
|
|
int numThorns;
|
|
int numThornLevels;
|
|
double shrinkFactor;
|
|
};
|
|
|
|
/*!
|
|
Constructor
|
|
|
|
\param numThorns Number of thorns
|
|
\param numThornLevels Number of thorn levels
|
|
*/
|
|
QwtSimpleCompassRose::QwtSimpleCompassRose(
|
|
int numThorns, int numThornLevels )
|
|
{
|
|
d_data = new PrivateData();
|
|
d_data->numThorns = numThorns;
|
|
d_data->numThornLevels = numThornLevels;
|
|
|
|
const QColor dark( 128, 128, 255 );
|
|
const QColor light( 192, 255, 255 );
|
|
|
|
QPalette palette;
|
|
palette.setColor( QPalette::Dark, dark );
|
|
palette.setColor( QPalette::Light, light );
|
|
|
|
setPalette( palette );
|
|
}
|
|
|
|
//! Destructor
|
|
QwtSimpleCompassRose::~QwtSimpleCompassRose()
|
|
{
|
|
delete d_data;
|
|
}
|
|
|
|
/*!
|
|
Set the Factor how to shrink the thorns with each level
|
|
The default value is 0.9.
|
|
|
|
\param factor Shrink factor
|
|
\sa shrinkFactor()
|
|
*/
|
|
void QwtSimpleCompassRose::setShrinkFactor( double factor )
|
|
{
|
|
d_data->shrinkFactor = factor;
|
|
}
|
|
|
|
/*!
|
|
\return Factor how to shrink the thorns with each level
|
|
\sa setShrinkFactor()
|
|
*/
|
|
double QwtSimpleCompassRose::shrinkFactor() const
|
|
{
|
|
return d_data->shrinkFactor;
|
|
}
|
|
|
|
/*!
|
|
Draw the rose
|
|
|
|
\param painter Painter
|
|
\param center Center point
|
|
\param radius Radius of the rose
|
|
\param north Position
|
|
\param cg Color group
|
|
*/
|
|
void QwtSimpleCompassRose::draw( QPainter *painter, const QPointF ¢er,
|
|
double radius, double north, QPalette::ColorGroup cg ) const
|
|
{
|
|
QPalette pal = palette();
|
|
pal.setCurrentColorGroup( cg );
|
|
|
|
drawRose( painter, pal, center, radius, north, d_data->width,
|
|
d_data->numThorns, d_data->numThornLevels, d_data->shrinkFactor );
|
|
}
|
|
|
|
/*!
|
|
Draw the rose
|
|
|
|
\param painter Painter
|
|
\param palette Palette
|
|
\param center Center of the rose
|
|
\param radius Radius of the rose
|
|
\param north Position pointing to north
|
|
\param width Width of the rose
|
|
\param numThorns Number of thorns
|
|
\param numThornLevels Number of thorn levels
|
|
\param shrinkFactor Factor to shrink the thorns with each level
|
|
*/
|
|
void QwtSimpleCompassRose::drawRose(
|
|
QPainter *painter,
|
|
const QPalette &palette,
|
|
const QPointF ¢er, double radius, double north, double width,
|
|
int numThorns, int numThornLevels, double shrinkFactor )
|
|
{
|
|
if ( numThorns < 4 )
|
|
numThorns = 4;
|
|
|
|
if ( numThorns % 4 )
|
|
numThorns += 4 - numThorns % 4;
|
|
|
|
if ( numThornLevels <= 0 )
|
|
numThornLevels = numThorns / 4;
|
|
|
|
if ( shrinkFactor >= 1.0 )
|
|
shrinkFactor = 1.0;
|
|
|
|
if ( shrinkFactor <= 0.5 )
|
|
shrinkFactor = 0.5;
|
|
|
|
painter->save();
|
|
|
|
painter->setPen( Qt::NoPen );
|
|
|
|
for ( int j = 1; j <= numThornLevels; j++ )
|
|
{
|
|
double step = qPow( 2.0, j ) * M_PI / numThorns;
|
|
if ( step > M_PI_2 )
|
|
break;
|
|
|
|
double r = radius;
|
|
for ( int k = 0; k < 3; k++ )
|
|
{
|
|
if ( j + k < numThornLevels )
|
|
r *= shrinkFactor;
|
|
}
|
|
|
|
double leafWidth = r * width;
|
|
if ( 2.0 * M_PI / step > 32 )
|
|
leafWidth = 16;
|
|
|
|
const double origin = qwtRadians( north );
|
|
for ( double angle = origin;
|
|
angle < 2.0 * M_PI + origin; angle += step )
|
|
{
|
|
const QPointF p = qwtPolar2Pos( center, r, angle );
|
|
const QPointF p1 = qwtPolar2Pos( center, leafWidth, angle + M_PI_2 );
|
|
const QPointF p2 = qwtPolar2Pos( center, leafWidth, angle - M_PI_2 );
|
|
const QPointF p3 = qwtPolar2Pos( center, r, angle + step / 2.0 );
|
|
const QPointF p4 = qwtPolar2Pos( center, r, angle - step / 2.0 );
|
|
|
|
QPainterPath darkPath;
|
|
darkPath.moveTo( center );
|
|
darkPath.lineTo( p );
|
|
darkPath.lineTo( qwtIntersection( center, p3, p1, p ) );
|
|
|
|
painter->setBrush( palette.brush( QPalette::Dark ) );
|
|
painter->drawPath( darkPath );
|
|
|
|
QPainterPath lightPath;
|
|
lightPath.moveTo( center );
|
|
lightPath.lineTo( p );
|
|
lightPath.lineTo( qwtIntersection( center, p4, p2, p ) );
|
|
|
|
painter->setBrush( palette.brush( QPalette::Light ) );
|
|
painter->drawPath( lightPath );
|
|
}
|
|
}
|
|
painter->restore();
|
|
}
|
|
|
|
/*!
|
|
Set the width of the rose heads. Lower value make thinner heads.
|
|
The range is limited from 0.03 to 0.4.
|
|
|
|
\param width Width
|
|
*/
|
|
void QwtSimpleCompassRose::setWidth( double width )
|
|
{
|
|
d_data->width = width;
|
|
if ( d_data->width < 0.03 )
|
|
d_data->width = 0.03;
|
|
|
|
if ( d_data->width > 0.4 )
|
|
d_data->width = 0.4;
|
|
}
|
|
|
|
/*!
|
|
\return Width of the rose
|
|
\sa setWidth()
|
|
*/
|
|
double QwtSimpleCompassRose::width() const
|
|
{
|
|
return d_data->width;
|
|
}
|
|
|
|
/*!
|
|
Set the number of thorns on one level
|
|
The number is aligned to a multiple of 4, with a minimum of 4
|
|
|
|
\param numThorns Number of thorns
|
|
\sa numThorns(), setNumThornLevels()
|
|
*/
|
|
void QwtSimpleCompassRose::setNumThorns( int numThorns )
|
|
{
|
|
if ( numThorns < 4 )
|
|
numThorns = 4;
|
|
|
|
if ( numThorns % 4 )
|
|
numThorns += 4 - numThorns % 4;
|
|
|
|
d_data->numThorns = numThorns;
|
|
}
|
|
|
|
/*!
|
|
\return Number of thorns
|
|
\sa setNumThorns(), setNumThornLevels()
|
|
*/
|
|
int QwtSimpleCompassRose::numThorns() const
|
|
{
|
|
return d_data->numThorns;
|
|
}
|
|
|
|
/*!
|
|
Set the of thorns levels
|
|
|
|
\param numThornLevels Number of thorns levels
|
|
\sa setNumThorns(), numThornLevels()
|
|
*/
|
|
void QwtSimpleCompassRose::setNumThornLevels( int numThornLevels )
|
|
{
|
|
d_data->numThornLevels = numThornLevels;
|
|
}
|
|
|
|
/*!
|
|
\return Number of thorn levels
|
|
\sa setNumThorns(), setNumThornLevels()
|
|
*/
|
|
int QwtSimpleCompassRose::numThornLevels() const
|
|
{
|
|
return d_data->numThornLevels;
|
|
}
|