Skip to content
qwt_scale_engine.cpp 27.5 KiB
Newer Older
Bryant's avatar
Bryant committed
   \param mediumTicks Array to be filled with the calculated medium ticks
*/
void QwtLogScaleEngine::buildMinorTicks(
    const QList<double> &majorTicks,
    int maxMinorSteps, double stepSize,
    QList<double> &minorTicks,
    QList<double> &mediumTicks ) const
{
    const double logBase = base();
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    if ( stepSize < 1.1 )          // major step width is one base
    {
        double minStep = divideInterval( stepSize, maxMinorSteps + 1 );
        if ( minStep == 0.0 )
            return;
        
        const int numSteps = qRound( stepSize / minStep ); 

        int mediumTickIndex = -1;
        if ( ( numSteps > 2 ) && ( numSteps % 2 == 0 ) )
            mediumTickIndex = numSteps / 2;

        for ( int i = 0; i < majorTicks.count() - 1; i++ )
        {
pixhawk's avatar
pixhawk committed
            const double v = majorTicks[i];
Bryant's avatar
Bryant committed
            const double s = logBase / numSteps;

            if ( s >= 1.0 )
            {
                for ( int j = 2; j < numSteps; j++ )
                {
                    minorTicks += v * j * s;
                }
            }
            else
            {
                for ( int j = 1; j < numSteps; j++ )
                {
                    const double tick = v + j * v * ( logBase - 1 ) / numSteps;
                    if ( j == mediumTickIndex )
                        mediumTicks += tick;
                    else
                        minorTicks += tick;
                }
            }
pixhawk's avatar
pixhawk committed
        }
Bryant's avatar
Bryant committed
    }
    else
    {
        double minStep = divideInterval( stepSize, maxMinorSteps );
pixhawk's avatar
pixhawk committed
        if ( minStep == 0.0 )
Bryant's avatar
Bryant committed
            return;
pixhawk's avatar
pixhawk committed

        if ( minStep < 1.0 )
            minStep = 1.0;

        // # subticks per interval
Bryant's avatar
Bryant committed
        int numTicks = qRound( stepSize / minStep ) - 1;
pixhawk's avatar
pixhawk committed

        // Do the minor steps fit into the interval?
Bryant's avatar
Bryant committed
        if ( qwtFuzzyCompare( ( numTicks +  1 ) * minStep,
            stepSize, stepSize ) > 0 )
        {
            numTicks = 0;
pixhawk's avatar
pixhawk committed
        }

Bryant's avatar
Bryant committed
        if ( numTicks < 1 )
            return; 

        int mediumTickIndex = -1;
        if ( ( numTicks > 2 ) && ( numTicks % 2 ) )
            mediumTickIndex = numTicks / 2;

        // substep factor = base^substeps
        const qreal minFactor = qMax( qPow( logBase, minStep ), qreal( logBase ) );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
        for ( int i = 0; i < majorTicks.count(); i++ )
        {
            double tick = majorTicks[i];
            for ( int j = 0; j < numTicks; j++ )
            {
                tick *= minFactor;
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
                if ( j == mediumTickIndex )
                    mediumTicks += tick;
                else
                    minorTicks += tick;
pixhawk's avatar
pixhawk committed
            }
        }
    }
}

/*!
  \brief Align an interval to a step size

  The limits of an interval are aligned that both are integer
  multiples of the step size.

  \param interval Interval
  \param stepSize Step size

  \return Aligned interval
*/
Bryant's avatar
Bryant committed
QwtInterval QwtLogScaleEngine::align(
    const QwtInterval &interval, double stepSize ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    const QwtInterval intv = qwtLogInterval( base(), interval );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    double x1 = QwtScaleArithmetic::floorEps( intv.minValue(), stepSize );
    if ( qwtFuzzyCompare( interval.minValue(), x1, stepSize ) == 0 )
        x1 = interval.minValue();
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    double x2 = QwtScaleArithmetic::ceilEps( intv.maxValue(), stepSize );
    if ( qwtFuzzyCompare( interval.maxValue(), x2, stepSize ) == 0 )
        x2 = interval.maxValue();
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    return qwtPowInterval( base(), QwtInterval( x1, x2 ) );
pixhawk's avatar
pixhawk committed
}