Newer
Older
/* -*- 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 <qalgorithms.h>
#include <qmath.h>
#include <float.h>
#if QT_VERSION < 0x040601
#define qFabs(x) ::fabs(x)
#define qExp(x) ::exp(x)
#endif
static inline double qwtLog( double base, double value )
{
return log( value ) / log( base );
}
static inline QwtInterval qwtLogInterval( double base, const QwtInterval &interval )
{
return QwtInterval( qwtLog( base, interval.minValue() ),
qwtLog( base, interval.maxValue() ) );
}
static inline QwtInterval qwtPowInterval( double base, const QwtInterval &interval )
{
return QwtInterval( qPow( base, interval.minValue() ),
qPow( base, interval.maxValue() ) );
}
// this version often doesn't find the best ticks: f.e for 15: 5, 10
static double qwtStepSize( double intervalSize, int maxSteps, uint base )
const double minStep =
QwtScaleArithmetic::divideInterval( intervalSize, maxSteps, base );
if ( minStep != 0.0 )
{
// # ticks per interval
const int numTicks = qCeil( qAbs( intervalSize / minStep ) ) - 1;
// Do the minor steps fit into the interval?
if ( qwtFuzzyCompare( ( numTicks + 1 ) * qAbs( minStep ),
qAbs( intervalSize ), intervalSize ) > 0 )
{
// The minor steps doesn't fit into the interval
return 0.5 * intervalSize;
}
}
return minStep;
}
static double qwtStepSize( double intervalSize, int maxSteps, uint base )
{
if ( maxSteps <= 0 )
return 0.0;
if ( maxSteps > 2 )
{
for ( int numSteps = maxSteps; numSteps > 1; numSteps-- )
{
const double stepSize = intervalSize / numSteps;
const double p = ::floor( ::log( stepSize ) / ::log( base ) );
const double fraction = qPow( base, p );
for ( uint n = base; n > 1; n /= 2 )
{
if ( qFuzzyCompare( stepSize, n * fraction ) )
return stepSize;
if ( n == 3 && ( base % 2 ) == 0 )
{
if ( qFuzzyCompare( stepSize, 2 * fraction ) )
return stepSize;
}
}
}
}
double QwtScaleArithmetic::ceilEps( double value,
double intervalSize )
value = ( value - eps ) / intervalSize;
return ::ceil( value ) * intervalSize;
double QwtScaleArithmetic::floorEps( double value, double intervalSize )
value = ( value + eps ) / intervalSize;
return ::floor( value ) * intervalSize;
\brief Divide an interval into steps
\f$stepSize = (intervalSize - intervalSize * 10e^{-6}) / numSteps\f$
\param intervalSize Interval size
\param numSteps Number of steps
\return Step size
*/
double QwtScaleArithmetic::divideEps( double intervalSize, double numSteps )
{
if ( numSteps == 0.0 || intervalSize == 0.0 )
return 0.0;
return ( intervalSize - ( _eps * intervalSize ) ) / numSteps;
\param intervalSize Interval size
\param numSteps Number of steps
\param base Base for the division ( usually 10 )
\return Calculated step size
*/
double QwtScaleArithmetic::divideInterval(
double intervalSize, int numSteps, uint base )
const double v = QwtScaleArithmetic::divideEps( intervalSize, numSteps );
if ( v == 0.0 )
return 0.0;
const double lx = qwtLog( base, qFabs( v ) );
const double p = ::floor( lx );
uint n = base;
while ( ( n > 1 ) && ( fraction <= n / 2 ) )
n /= 2;
double stepSize = n * qPow( base, p );
if ( v < 0 )
stepSize = -stepSize;
}
class QwtScaleEngine::PrivateData
{
public:
PrivateData():
Loading
Loading full blame...