Example #1
0
/*!
  \brief No docs

  Description
  \param x ???
  \param align
  \todo Documentation
*/
void QwtDoubleRange::setNewValue(double x, bool align)
{
    double vmin,vmax;

    d_prevValue = d_value;

    vmin = qwtMin(d_minValue, d_maxValue);
    vmax = qwtMax(d_minValue, d_maxValue);

    //
    // Range check
    //
    if (x < vmin)
    {
        if ((d_periodic) && (vmin != vmax))
            d_value = x + ::ceil( (vmin - x) / (vmax - vmin ) )
                      * (vmax - vmin);
        else
            d_value = vmin;
    }
    else if (x > vmax)
    {
        if ((d_periodic) && (vmin != vmax))
            d_value = x - ::ceil( ( x - vmax) / (vmax - vmin ))
                      * (vmax - vmin);
        else
            d_value = vmax;
    }
    else
        d_value = x;

    d_exactPrevValue = d_exactValue;
    d_exactValue = d_value;

    // align to grid
    if (align)
    {
        if (d_step != 0.0)
        {
            d_value = d_minValue +
                      qwtRound((d_value - d_minValue) / d_step) * d_step;
        }
        else
            d_value = d_minValue;

        // correct rounding error at the border
        if (fabs(d_value - d_maxValue) < MinEps * qwtAbs(d_step))
            d_value = d_maxValue;

        // correct rounding error if value = 0
        if (::fabs(d_value) < MinEps * qwtAbs(d_step))
            d_value = 0.0;
    }

    if (!d_isValid || d_prevValue != d_value)
    {
        d_isValid = true;
        valueChange();
    }
}
int ScalePicker::maxLabelWidth(const QwtScale *scale) const
{
	QFontMetrics fm(scale->font());
	const QwtScaleDraw * scaleDraw=scale->scaleDraw ();
	const QwtScaleDiv 	scaleDiv=scaleDraw->scaleDiv();
	const double step_eps = 1.0e-6;
    int maxWidth = 0;

    for (uint i = 0; i < scaleDiv.majCnt(); i++)
    {
        double val = scaleDiv.majMark(i);

        // correct rounding errors if val = 0
        if ((!scaleDiv.logScale()) 
            && (qwtAbs(val) < step_eps * qwtAbs(scaleDiv.majStep())))
        {
            val = 0.0;
        }

        const int w = fm.boundingRect(scaleDraw->label(val)).width();
        if ( w > maxWidth )
            maxWidth = w;
    }

    return maxWidth;
}
QList<QwtDoublePoint> QwtCircleClipper::cuttingPoints(
    Edge edge, const QwtDoublePoint &pos, double radius) const
{
    QList<QwtDoublePoint> points;

    if ( edge == Left || edge == Right )
    {
        const double x = (edge == Left) ? left() : right();
        if ( qwtAbs(pos.x() - x) < radius )
        {
            const double off = ::sqrt(qwtSqr(radius) - qwtSqr(pos.x() - x));
            const double y1 = pos.y() + off;
            if ( y1 >= top() && y1 <= bottom() )
                points += QwtDoublePoint(x, y1);
            const double y2 = pos.y() - off;
            if ( y2 >= top() && y2 <= bottom() )
                points += QwtDoublePoint(x, y2);
        }
    }
    else
    {
        const double y = (edge == Top) ? top() : bottom();
        if ( qwtAbs(pos.y() - y) < radius )
        {
            const double off = ::sqrt(qwtSqr(radius) - qwtSqr(pos.y() - y));
            const double x1 = pos.x() + off;
            if ( x1 >= left() && x1 <= right() )
                points += QwtDoublePoint(x1, y);
            const double x2 = pos.x() - off;
            if ( x2 >= left() && x2 <= right() )
                points += QwtDoublePoint(x2, y);
        }
    }
    return points;
}
Example #4
0
bool QwtPlotPicker::end(bool ok)
{
    ok = QwtPicker::end(ok);
    if ( !ok )
        return false;

    QwtPlot *plot = QwtPlotPicker::plot();
    if ( !plot )
        return false;

    const QwtPolygon &pa = selection();
    if ( pa.count() == 0 )
        return false;

    if ( selectionFlags() & PointSelection )
    {
        const QwtDoublePoint pos = invTransform(pa[0]);
        emit selected(pos);
    }
    else if ( (selectionFlags() & RectSelection) && pa.count() >= 2 )
    {
        QPoint p1 = pa[0];
        QPoint p2 = pa[int(pa.count() - 1)];

        if ( selectionFlags() & CenterToCorner )
        {
            p1.setX(p1.x() - (p2.x() - p1.x()));
            p1.setY(p1.y() - (p2.y() - p1.y()));
        }
        else if ( selectionFlags() & CenterToRadius )
        {
            const int radius = qwtMax(qwtAbs(p2.x() - p1.x()),
                qwtAbs(p2.y() - p1.y()));
            p2.setX(p1.x() + radius);
            p2.setY(p1.y() + radius);
            p1.setX(p1.x() - radius);
            p1.setY(p1.y() - radius);
        }

        emit selected(invTransform(QRect(p1, p2)).normalized());
    }
    else 
    {
        QwtArray<QwtDoublePoint> dpa(pa.count());
        for ( int i = 0; i < int(pa.count()); i++ )
            dpa[i] = invTransform(pa[i]);

        emit selected(dpa);
    }

    return true;
}
/*! 
   Zoom in/out the axes scales
   \param factor A value < 1.0 zooms in, a value > 1.0 zooms out.
*/
void QwtPlotMagnifier::rescale(double factor)
{
    factor = qwtAbs(factor);
    if ( factor == 1.0 || factor == 0.0 )
        return;

    bool doReplot = false;
    QwtPlot* plt = plot();

    const bool autoReplot = plt->autoReplot();
    plt->setAutoReplot(false);

    for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
    {
        const QwtScaleDiv *scaleDiv = plt->axisScaleDiv(axisId);
        if ( isAxisEnabled(axisId) && scaleDiv->isValid() )
        {
            const double center =
                scaleDiv->lowerBound() + scaleDiv->range() / 2;
            const double width_2 = scaleDiv->range() / 2 * factor;

            plt->setAxisScale(axisId, center - width_2, center + width_2);
            doReplot = true;
        }
    }

    plt->setAutoReplot(autoReplot);

    if ( doReplot )
        plt->replot();
}
Example #6
0
/*!
   Zoom in/out the zoomed area
   \param factor A value < 1.0 zooms in, a value > 1.0 zooms out.
*/
void QwtPolarMagnifier::rescale( double factor )
{
  factor = qwtAbs( factor );
  if ( factor == 1.0 || factor == 0.0 )
    return;

  QwtPolarPlot* plt = plot();
  if ( plt == NULL )
    return;

  QwtPolarPoint zoomPos;
  double newZoomFactor = plt->zoomFactor() * factor;

  if ( newZoomFactor >= 1.0 )
    newZoomFactor = 1.0;
  else
    zoomPos = plt->zoomPos();

  const bool autoReplot = plt->autoReplot();
  plt->setAutoReplot( false );

  plt->zoom( zoomPos, newZoomFactor );

  plt->setAutoReplot( autoReplot );
  plt->replot();
}
Example #7
0
/*!
   \brief Calculate a scale division

   \param x1 First interval limit 
   \param x2 Second interval limit 
   \param maxMajSteps Maximum for the number of major steps
   \param maxMinSteps Maximum number of minor steps
   \param stepSize Step size. If stepSize == 0, the scaleEngine
                   calculates one.

   \sa QwtScaleEngine::stepSize(), QwtScaleEngine::subDivide()
*/
QwtScaleDiv QwtLinearScaleEngine::divideScale(double x1, double x2,
    int maxMajSteps, int maxMinSteps, double stepSize) const
{
    QwtDoubleInterval interval = QwtDoubleInterval(x1, x2).normalized();
    if (interval.width() <= 0 )
        return QwtScaleDiv();

    stepSize = qwtAbs(stepSize);
    if ( stepSize == 0.0 )
    {
        if ( maxMajSteps < 1 )
            maxMajSteps = 1;

        stepSize = divideInterval(interval.width(), maxMajSteps);
    }

    QwtScaleDiv scaleDiv;

    if ( stepSize != 0.0 )
    {
        QwtValueList ticks[QwtScaleDiv::NTickTypes];
        buildTicks(interval, stepSize, maxMinSteps, ticks);

        scaleDiv = QwtScaleDiv(interval, ticks);
    }

    if ( x1 > x2 )
        scaleDiv.invert();

    return scaleDiv;
}
void QwtPlotMagnifier::widgetWheelEvent(QWheelEvent *we)
{
#if QT_VERSION < 0x040000
    if ( (we->state() & Qt::KeyButtonMask) !=
        (d_data->wheelButtonState & Qt::KeyButtonMask) )
#else
    if ( (we->modifiers() & Qt::KeyboardModifierMask) !=
        (int)(d_data->wheelButtonState & Qt::KeyboardModifierMask) )
#endif
    {
        return;
    }

    if ( d_data->wheelFactor != 0.0 )
    {
       /*
           A positive delta indicates that the wheel was 
           rotated forwards away from the user; a negative 
           value indicates that the wheel was rotated 
           backwards toward the user.
           Most mouse types work in steps of 15 degrees, 
           in which case the delta value is a multiple 
           of 120 (== 15 * 8).
        */
        double f = ::pow(d_data->wheelFactor, 
            qwtAbs(we->delta() / 120));
        if ( we->delta() > 0 )
            f = 1 / f;

        rescale(f);
    }
}
Example #9
0
/*!
  \brief Specify  range and step size

  \param vmin   lower boundary of the interval
  \param vmax   higher boundary of the interval
  \param vstep  step width
  \param pageSize  page size in steps
  \warning
  \li A change of the range changes the value if it lies outside the
      new range. The current value
      will *not* be adjusted to the new step raster.
  \li vmax < vmin is allowed.
  \li If the step size is left out or set to zero, it will be
      set to 1/100 of the interval length.
  \li If the step size has an absurd value, it will be corrected
      to a better one.
*/
void QwtDoubleRange::setRange(double vmin, double vmax, double vstep, int pageSize)
{
    bool rchg = ((d_maxValue != vmax) || (d_minValue != vmin));

    if (rchg)
    {
        d_minValue = vmin;
        d_maxValue = vmax;
    }

    //
    // look if the step width has an acceptable
    // value or otherwise change it.
    //
    setStep(vstep);

    //
    // limit page size
    //
    d_pageSize = qwtLim(pageSize,0,
                        int(qwtAbs((d_maxValue - d_minValue) / d_step)));

    //
    // If the value lies out of the range, it
    // will be changed. Note that it will not be adjusted to
    // the new step width.
    setNewValue(d_value, false);

    // call notifier after the step width has been
    // adjusted.
    if (rchg)
        rangeChange();
}
Example #10
0
void QwtLinearColorMap::ColorStops::insert(double pos, const QColor &color)
{
    // Lookups need to be very fast, insertions are not so important.
    // Anyway, a balanced tree is what we need here. TODO ...

    if ( pos < 0.0 || pos > 1.0 )
        return;

    int index;
    if ( _stops.size() == 0 ) {
        index = 0;
#if QT_VERSION < 0x040000
        _stops.resize(1, QGArray::SpeedOptim);
#else
        _stops.resize(1);
#endif
    } else {
        index = findUpper(pos);
        if ( index == (int)_stops.size() ||
                qwtAbs(_stops[index].pos - pos) >= 0.001 ) {
#if QT_VERSION < 0x040000
            _stops.resize(_stops.size() + 1, QGArray::SpeedOptim);
#else
            _stops.resize(_stops.size() + 1);
#endif
            for ( int i = _stops.size() - 1; i > index; i-- )
                _stops[i] = _stops[i-1];
        }
    }

    _stops[index] = ColorStop(pos, color);
}
Example #11
0
void QwtLinearScaleEngine::buildMinorTicks(
    const QwtValueList& majorTicks,
    int maxMinSteps, double stepSize,
    QwtValueList &minorTicks, 
    QwtValueList &mediumTicks) const
{   
    double minStep = divideInterval(stepSize, maxMinSteps);
    if (minStep == 0.0)  
        return; 
        
    // # ticks per interval
    int numTicks = (int)::ceil(qwtAbs(stepSize / minStep)) - 1;
    
    // Do the minor steps fit into the interval?
    if ( QwtScaleArithmetic::compareEps((numTicks +  1) * qwtAbs(minStep), 
        qwtAbs(stepSize), stepSize) > 0)
    {   
        numTicks = 1;
        minStep = stepSize * 0.5;
    }

    int medIndex = -1;
    if ( numTicks % 2 )
        medIndex = numTicks / 2;

    // calculate minor ticks

    for (int i = 0; i < (int)majorTicks.count(); i++)
    {
        double val = majorTicks[i];
        for (int k = 0; k < numTicks; k++)
        {
            val += minStep;

            double alignedValue = val;
            if (QwtScaleArithmetic::compareEps(val, 0.0, stepSize) == 0) 
                alignedValue = 0.0;

            if ( k == medIndex )
                mediumTicks += alignedValue;
            else
                minorTicks += alignedValue;
        }
    }
}
Example #12
0
/*!
  \brief Determine the minimum border distance

  This member function returns the minimum space
  needed to draw the mark labels at the scale's endpoints.

  \param font Font
  \param start Start border distance
  \param end End border distance
*/
void QwtScaleDraw::getBorderDistHint(const QFont &font,
    int &start, int &end ) const
{
    start = 0;
    end = 0;
    
    if ( !hasComponent(QwtAbstractScaleDraw::Labels) )
        return;

    const QwtValueList &ticks = scaleDiv().ticks(QwtScaleDiv::MajorTick);
    if ( ticks.count() == 0 ) 
        return;

    QRect lr = labelRect(font, ticks[0]);

    // find the distance between tick and border
    int off = qwtAbs(map().transform(ticks[0]) - qRound(map().p1()));

    if ( orientation() == Qt::Vertical )
        end = lr.bottom() + 1 - off;
    else
        start = -lr.left() - off;

    const int lastTick = ticks.count() - 1;
    lr = labelRect(font, ticks[lastTick]);

    // find the distance between tick and border
    off = qwtAbs(map().transform(ticks[lastTick]) - qRound(map().p2()));

    if ( orientation() == Qt::Vertical )
        start = -lr.top() - off;
    else
        end = lr.right() + 1 - off;

    // if the distance between tick and border is larger
    // than half of the label width/height, we set to 0

    if ( start < 0 )
        start = 0;
    if ( end < 0 )
        end = 0;
}
QwtDoubleInterval QwtScaleEngine::buildInterval(double v) const
{
#if 1
    const double delta = (v == 0.0) ? 0.5 : qwtAbs(0.5 * v);
    return QwtDoubleInterval(v - delta, v + delta);
#else
    if ( v == 0.0 )
        return QwtDoubleInterval(-0.5, 0.5);

    return QwtDoubleInterval(0.5 * v, 1.5 * v);
#endif
}
/*!
   \brief Calculate a scale division

   \param x1 First interval limit 
   \param x2 Second interval limit 
   \param maxMajSteps Maximum for the number of major steps
   \param maxMinSteps Maximum number of minor steps
   \param stepSize Step size. If stepSize == 0, the scaleEngine
                   calculates one.

   \sa QwtScaleEngine::stepSize, LogTimeScaleEngine::subDivide
*/
QwtScaleDiv LogTimeScaleEngine::divideScale(double x1, double x2,
    int maxMajSteps, int maxMinSteps, double stepSize) const
{
    QwtDoubleInterval interval = QwtDoubleInterval(x1, x2).normalized();
    interval = interval.limited(LOG_MIN, LOG_MAX);

    if (interval.width() <= 0 )
        return QwtScaleDiv();

    if (interval.maxValue() / interval.minValue() < 10.0)
    {
        // scale width is less than one decade -> build linear scale
    
        QwtLinearScaleEngine linearScaler;
        linearScaler.setAttributes(attributes());
        linearScaler.setReference(reference());
        linearScaler.setMargins(
                                #if (QWT_VERSION >= 0x050200)
				lowerMargin(), upperMargin()
				#else
				loMargin(), hiMargin()
				#endif
				);

        return linearScaler.divideScale(x1, x2, 
            maxMajSteps, maxMinSteps, stepSize);
    }

    stepSize = qwtAbs(stepSize);
    if ( stepSize == 0.0 )
    {
        if ( maxMajSteps < 1 )
            maxMajSteps = 1;

        stepSize = divideInterval(log10(interval).width(), maxMajSteps);
        if ( stepSize < 1.0 )
            stepSize = 1.0; // major step must be >= 1 decade
    }

    QwtScaleDiv scaleDiv;
    if ( stepSize != 0.0 )
    {
        QwtValueList ticks[QwtScaleDiv::NTickTypes];
        buildTicks(interval, stepSize, maxMinSteps, ticks);

        scaleDiv = QwtScaleDiv(interval, ticks);
    }

    if ( x1 > x2 )
        scaleDiv.invert();

    return scaleDiv;
}
Example #15
0
/*!
  \brief Compare 2 values, relative to an interval

  Values are "equal", when :
  \f$\cdot value2 - value1 <= abs(intervalSize * 10e^{-6})\f$

  \param value1 First value to compare
  \param value2 Second value to compare
  \param intervalSize interval size

  \return 0: if equal, -1: if value2 > value1, 1: if value1 > value2
*/
int QwtScaleArithmetic::compareEps(double value1, double value2, 
    double intervalSize) 
{
    const double eps = qwtAbs(_eps * intervalSize);

    if ( value2 - value1 > eps )
        return -1;

    if ( value1 - value2 > eps )
        return 1;

    return 0;
}
Example #16
0
static bool limRange(double &val, double v1, double v2, double eps_rel = 0.0,
		double eps_abs = 0.0)
{

	bool rv = true;
	double vmin = qwtMin(v1, v2);
	double vmax = qwtMax(v1, v2);
	double delta_min = qwtMax(qwtAbs(eps_rel * vmin), qwtAbs(eps_abs));
	double delta_max = qwtMax(qwtAbs(eps_rel * vmax), qwtAbs(eps_abs));

	if (val < vmin)
	{
		if (val < vmin - delta_min) rv = false;
		val = vmin;
	}
	else if (val > vmax)
	{
		if (val > vmax + delta_max) rv = false;
		val = vmax;
	}
	return rv;

}
Example #17
0
/*!
   \brief Translate and in/decrease the zoom factor

   In zoom mode the zoom position is in the center of the
   canvas. The radius of the circle depends on the size of the plot canvas,
   that is divided by the zoom factor. Thus a factor < 1.0 zoom in.

   Setting an invalid zoom position disables zooming.

   \param zoomPos Center of the translation
   \param zoomFactor Zoom factor

   \sa unzoom(), zoomPos(), zoomFactor()
*/
void QwtPolarPlot::zoom( const QwtPolarPoint &zoomPos, double zoomFactor )
{
  zoomFactor = qwtAbs( zoomFactor );
  if ( zoomPos != d_data->zoomPos ||
       zoomFactor != d_data->zoomFactor )
  {
    d_data->zoomPos = zoomPos;
    d_data->zoomFactor = zoomFactor;
#if 1
    updateLayout();
#endif
    autoRefresh();
  }
}
/*!
   \brief Calculate a scale division

   \param x1 First interval limit
   \param x2 Second interval limit
   \param maxMajSteps Maximum for the number of major steps
   \param maxMinSteps Maximum number of minor steps
   \param stepSize Step size. If stepSize == 0, the scaleEngine
                   calculates one.
*/
QwtScaleDiv Log2ScaleEngine::divideScale(double x1, double x2,
    int maxMajSteps, int maxMinSteps, double stepSize) const
{
    QwtDoubleInterval interval = QwtDoubleInterval(x1, x2).normalized();
    interval = interval.limited(LOG_MIN, LOG_MAX);

    if (interval.width() <= 0 )
        return QwtScaleDiv();

    if (interval.maxValue() / interval.minValue() < 2){
        // scale width is less than 2 -> build linear scale
        QwtLinearScaleEngine linearScaler;
        linearScaler.setAttributes(attributes());
        linearScaler.setReference(reference());
        linearScaler.setMargins(lowerMargin(), upperMargin());

        return linearScaler.divideScale(x1, x2,
            maxMajSteps, maxMinSteps, stepSize);
    }

    stepSize = qwtAbs(stepSize);
    if ( stepSize == 0.0 ){
        if ( maxMajSteps < 1 )
            maxMajSteps = 1;

		stepSize = ceil(log2(interval).width()/double(maxMajSteps));
    }

    QwtScaleDiv scaleDiv;
    if ( stepSize != 0.0 ){
        QwtValueList ticks[QwtScaleDiv::NTickTypes];
		buildTicks(interval, stepSize, maxMinSteps, ticks);
        scaleDiv = QwtScaleDiv(interval, ticks);
    }

    if ( x1 > x2 )
        scaleDiv.invert();

    return scaleDiv;
}
Example #19
0
QPoint QwtRect::intersectEdge(const QPoint &p1, 
    const QPoint &p2, Edge edge ) const
{
    int x=0, y=0;
    double m = 0;

    const double dy = p2.y() - p1.y();
    const double dx = p2.x() - p1.x();

    switch ( edge ) 
    {
        case Left:
            x = left();
            m = double(qwtAbs(p1.x() - x)) / qwtAbs(dx);
            y = p1.y() + int(dy * m);
            break;
        case Top:
            y = top();
            m = double(qwtAbs(p1.y() - y)) / qwtAbs(dy);
            x = p1.x() + int(dx * m);
            break;
        case Right:
            x = right();
            m = double(qwtAbs(p1.x() - x)) / qwtAbs(dx);
            y = p1.y() + int(dy * m);
            break;
        case Bottom:
            y = bottom();
            m = double(qwtAbs(p1.y() - y)) / qwtAbs(dy);
            x = p1.x() + int(dx * m);
            break;
        default:
            break;
    }

    return QPoint(x,y);
}
double QwtCircleClipper::toAngle(
    const QwtDoublePoint &from, const QwtDoublePoint &to) const
{
    if ( from.x() == to.x() )
        return from.y() <= to.y() ? M_PI / 2.0 : 3 * M_PI / 2.0;

    const double m = qwtAbs((to.y() - from.y()) / (to.x() - from.x()) );

    double angle = ::atan(m);
    if ( to.x() > from.x() )
    {   
        if ( to.y() > from.y() )
            angle = 2 * M_PI - angle;
    }
    else
    {
        if ( to.y() > from.y() )
            angle = M_PI + angle;
        else
            angle = M_PI - angle;
    }

    return angle;
}
Example #21
0
/*!
  \brief build a logarithmic scale
*/
void QwtAutoScale::buildLogScale ()
{
    if (!d_autoScale) 
        return;

    double minval = d_minValue; // the calculation of scale divisions 
    double maxval = d_maxValue; // is based on the input data.

    if (d_loMargin > 0.0)
        minval /= pow(10.0, d_loMargin);
    if (d_hiMargin > 0.0)
        maxval *= pow(10.0, d_hiMargin);

    if (d_scaleOpt & Symmetric)
    {
        const double delta = qwtMax(maxval / d_lref,  d_lref / minval); 
        maxval = d_lref * delta;
        minval = d_lref / delta;    
    }
    else if (d_scaleOpt & IncludeRef)
    {
        if (maxval < d_lref) 
            maxval = d_lref;
        else if (minval > d_lref) 
            minval = d_lref;
    }

	const double ticks = (d_maxMajor > 0) ? double(d_maxMajor) : 1;

    setRange(minval, maxval);

    // decades included in the interval
    const double decades = qwtAbs(log10 (d_scaleMax / d_scaleMin));

    // calculate step size in decades

    double step;
    if ((decades > 1.0) && (decades > ticks))
    {
		double ipart;
        // One interval contains more than one decade.
        // The number of decades in an interval is adjusted
        // to be a multiple of 2,3,5, or 10.
        double fpart = modf (log10 (ceil (decades * 0.999999 / ticks)), &ipart);
        if (fpart < MinEps)
           fpart = 1.0;
        else if ((fpart - LOG10_2) < MinEps)
           fpart = 2.0;
        else if ((fpart - LOG10_3) < MinEps)
           fpart = 3.0;
        else if ((fpart - LOG10_5) < MinEps)
           fpart = 5.0;
        else
           fpart = 10.0;

		step = pow (10.0, ipart) * fpart;

    }
    else                // The minimal step size is one decade.
    {
        step = 1.0;
    }
    
    if (!(d_scaleOpt & Floating))
    {
        d_scaleMin = pow (10.0, step * 
            floor ((log10(d_scaleMin) + MinEps * step) / step));
        d_scaleMax = pow (10.0, step * 
            ceil ((log10(d_scaleMax) - MinEps * step) / step));
    }

    if (d_scaleOpt & Inverted)
    {
        step = -step;
        d_scldiv.rebuild(d_scaleMax, d_scaleMin, d_maxMajor, d_maxMinor, TRUE,
             step, FALSE);
    }
    else
    {
        d_scldiv.rebuild(d_scaleMin, d_scaleMax, d_maxMajor, d_maxMinor,
             TRUE, step, TRUE);
    }
}
Example #22
0
/*! 
   Draw the Wheel's background gradient

   \param painter Painter
   \param r Bounding rectangle
*/
void QwtWheel::drawWheelBackground(QPainter *painter, const QRect &r )
{
    painter->save();

    //
    // initialize pens
    //
#if QT_VERSION < 0x040000
    const QColor light = colorGroup().light();
    const QColor dark = colorGroup().dark();
#else
    const QColor light = palette().color(QPalette::Light);
    const QColor dark = palette().color(QPalette::Dark);
#endif

    QPen lightPen;
    lightPen.setColor(light);
    lightPen.setWidth(d_data->intBorder);

    QPen darkPen;
    darkPen.setColor(dark);
    darkPen.setWidth(d_data->intBorder);

    setColorArray();

    //
    // initialize auxiliary variables
    //

    const int nFields = NUM_COLORS * 13 / 10;
    const int hiPos = nFields - NUM_COLORS + 1;

    if ( orientation() == Qt::Horizontal )
    {
        const int rx = r.x();
        int ry = r.y() + d_data->intBorder;
        const int rh = r.height() - 2* d_data->intBorder;
        const int rw = r.width();
        //
        //  draw shaded background
        //
        int x1 = rx;
        for (int i = 1; i < nFields; i++ )
        {
            const int x2 = rx + (rw * i) / nFields;
            painter->fillRect(x1, ry, x2-x1 + 1 ,rh, 
                d_data->colors[qwtAbs(i-hiPos)]);
            x1 = x2 + 1;
        }
        painter->fillRect(x1, ry, rw - (x1 - rx), rh, 
            d_data->colors[NUM_COLORS - 1]);

        //
        // draw internal border
        //
        painter->setPen(lightPen);
        ry = r.y() + d_data->intBorder / 2;
        painter->drawLine(r.x(), ry, r.x() + r.width() , ry);

        painter->setPen(darkPen);
        ry = r.y() + r.height() - (d_data->intBorder - d_data->intBorder / 2);
        painter->drawLine(r.x(), ry , r.x() + r.width(), ry);
    }
    else // Qt::Vertical
    {
        int rx = r.x() + d_data->intBorder;
        const int ry = r.y();
        const int rh = r.height();
        const int rw = r.width() - 2 * d_data->intBorder;

        //
        // draw shaded background
        //
        int y1 = ry;
        for ( int i = 1; i < nFields; i++ )
        {
            const int y2 = ry + (rh * i) / nFields;
            painter->fillRect(rx, y1, rw, y2-y1 + 1, 
                d_data->colors[qwtAbs(i-hiPos)]);
            y1 = y2 + 1;
        }
        painter->fillRect(rx, y1, rw, rh - (y1 - ry), 
            d_data->colors[NUM_COLORS - 1]);

        //
        //  draw internal borders
        //
        painter->setPen(lightPen);
        rx = r.x() + d_data->intBorder / 2;
        painter->drawLine(rx, r.y(), rx, r.y() + r.height());

        painter->setPen(darkPen);
        rx = r.x() + r.width() - (d_data->intBorder - d_data->intBorder / 2);
        painter->drawLine(rx, r.y(), rx , r.y() + r.height());
    }

    painter->restore();
}
Example #23
0
/*!
  \brief Build a linear scale
*/
void QwtAutoScale::buildLinScale ()
{
    double delta;
    const double ticks = double (d_maxMajor);

    //
    // If in Autoscale Mode, adjust minval and maxval according to
    // the active scale options, and add the margins
    //
    if (!d_autoScale) 
        return;
    
    double minval = d_minValue;    // scale boundaries are based on the
    double maxval = d_maxValue;    // data.

    //
    // add / subtract margins
    //
    if (d_loMargin > 0.0)
       minval -= d_loMargin;
    if (d_hiMargin > 0.0)
       maxval += d_hiMargin;

    //
    //  Correct minval / maxval according to the scale options
    //
    if (d_scaleOpt & Symmetric)
    {
        delta = qwtMax(qwtAbs(d_ref - maxval), qwtAbs(d_ref - minval));
        maxval = d_ref + delta;
        minval = d_ref - delta; 
    }
    else if (d_scaleOpt & IncludeRef)
    {
        if (maxval < d_ref) 
           maxval = d_ref;
        else if (minval > d_ref) 
           minval = d_ref;
    }
    
    //
    // first approximation of d_scaleMin and d_scaleMax
    //
    setRange(minval, maxval);
    delta = d_scaleMax - d_scaleMin;


    // dec := maximal power of ten which fits into the interval
    //   [d_scaleMin,d_scaleMax]
    const double dec = pow (10.0, floor (log10 (delta)));

    //
    //  The following magic line calculates the step size such that
    //      - The number of subintervals will not exceed the maximum
    //        as specified by the user
    //      - The step size fits {1,2,5}*10^n with a natural number n  
    // 
    double step = qwtCeil125(delta * 0.999999 / dec / ticks) * dec;

    //
    //  determine he final values of scaleMin and scaleMax
    //
    if (! (d_scaleOpt & Floating) )
    {
       // adjust of d_scaleMin and d_scaleMax such that both are integer
       // multiples of the step size.
       d_scaleMin = step * floor ((d_scaleMin + MinEps * step) / step);
       d_scaleMax = step * ceil ((d_scaleMax - MinEps * step) / step);
    }

    if (d_scaleOpt & Inverted)
    {
        step = -step;
        d_scldiv.rebuild(d_scaleMax, d_scaleMin, d_maxMajor, d_maxMinor,
             FALSE, step, FALSE);
    }
    else
    {
        d_scldiv.rebuild(d_scaleMin, d_scaleMax, d_maxMajor, d_maxMinor,
             FALSE, step, TRUE);
    }
}
Example #24
0
/*!
  \return the step size
  \sa setStep(), setRange()
*/
double QwtDoubleRange::step() const
{
    return qwtAbs(d_step);
}
Example #25
0
/*!
  \brief Redraw the wheel
  \param painter painter
  \param r contents rectangle
*/
void QwtWheel::drawWheel( QPainter *painter, const QRect &r )
{
    //
    // draw background gradient
    //
    drawWheelBackground( painter, r );

    if ( maxValue() == minValue() || d_data->totalAngle == 0.0 )
        return;

#if QT_VERSION < 0x040000
    const QColor light = colorGroup().light();
    const QColor dark = colorGroup().dark();
#else
    const QColor light = palette().color(QPalette::Light);
    const QColor dark = palette().color(QPalette::Dark);
#endif

    const double sign = (minValue() < maxValue()) ? 1.0 : -1.0;
    double cnvFactor = qwtAbs(d_data->totalAngle / (maxValue() - minValue()));
    const double halfIntv = 0.5 * d_data->viewAngle / cnvFactor;
    const double loValue = value() - halfIntv;
    const double hiValue = value() + halfIntv;
    const double tickWidth = 360.0 / double(d_data->tickCnt) / cnvFactor;
    const double sinArc = sin(d_data->viewAngle * M_PI / 360.0);
    cnvFactor *= M_PI / 180.0;


    //
    // draw grooves
    //
    if ( orientation() == Qt::Horizontal )
    {
        const double halfSize = double(r.width()) * 0.5;

        int l1 = r.y() + d_data->intBorder;
        int l2 = r.y() + r.height() - d_data->intBorder - 1;

        // draw one point over the border if border > 1
        if ( d_data->intBorder > 1 )
        {
            l1 --;
            l2 ++;
        }

        const int maxpos = r.x() + r.width() - 2;
        const int minpos = r.x() + 2;

        //
        // draw tick marks
        //
        for ( double tickValue = ceil(loValue / tickWidth) * tickWidth;
            tickValue < hiValue; tickValue += tickWidth )
        {
            //
            //  calculate position
            //
            const int tickPos = r.x() + r.width()
                - int( halfSize
                    * (sinArc + sign *  sin((tickValue - value()) * cnvFactor))
                    / sinArc);
            //
            // draw vertical line
            //
            if ( (tickPos <= maxpos) && (tickPos > minpos) )
            {
                painter->setPen(dark);
                painter->drawLine(tickPos -1 , l1, tickPos - 1,  l2 );  
                painter->setPen(light);
                painter->drawLine(tickPos, l1, tickPos, l2);  
            }
        }
    }
    else if ( orientation() == Qt::Vertical )
    {
        const double halfSize = double(r.height()) * 0.5;

        int l1 = r.x() + d_data->intBorder;
        int l2 = r.x() + r.width() - d_data->intBorder - 1;

        if ( d_data->intBorder > 1 )
        {
            l1--;
            l2++;
        }

        const int maxpos = r.y() + r.height() - 2;
        const int minpos = r.y() + 2;

        //
        // draw tick marks
        //
        for ( double tickValue = ceil(loValue / tickWidth) * tickWidth;
            tickValue < hiValue; tickValue += tickWidth )
        {

            //
            // calculate position
            //
            const int tickPos = r.y() + int( halfSize *
                (sinArc + sign * sin((tickValue - value()) * cnvFactor))
                / sinArc);

            //
            //  draw horizontal line
            //
            if ( (tickPos <= maxpos) && (tickPos > minpos) )
            {
                painter->setPen(dark);
                painter->drawLine(l1, tickPos - 1 ,l2, tickPos - 1);  
                painter->setPen(light);
                painter->drawLine(l1, tickPos, l2, tickPos);  
            }
        }
    }
}
Example #26
0
void QwtPicker::drawRubberBand(QPainter *painter) const
{
    if ( !isActive() || rubberBand() == NoRubberBand || 
        rubberBandPen().style() == Qt::NoPen )
    {
        return;
    }

    const QRect &pRect = pickRect();
    const SelectedPoints &pa = d_data->selection;

    if ( selectionFlags() & PointSelection )
    {
        if ( pa.count() < 1 )
            return;

        const QPoint pos = pa[0];

        switch(rubberBand())
        {
            case VLineRubberBand:
                QwtPainter::drawLine(painter, pos.x(),
                    pRect.top(), pos.x(), pRect.bottom());
                break;

            case HLineRubberBand:
                QwtPainter::drawLine(painter, pRect.left(), 
                    pos.y(), pRect.right(), pos.y());
                break;

            case CrossRubberBand:
                QwtPainter::drawLine(painter, pos.x(),
                    pRect.top(), pos.x(), pRect.bottom());
                QwtPainter::drawLine(painter, pRect.left(), 
                    pos.y(), pRect.right(), pos.y());
                break;
            default:
                break;
        }
    }

    else if ( selectionFlags() & RectSelection )
    {
        if ( pa.count() < 2 )
            return;

        QPoint p1 = pa[0];
        QPoint p2 = pa[int(pa.count() - 1)];

        if ( selectionFlags() & CenterToCorner )
        {
            p1.setX(p1.x() - (p2.x() - p1.x()));
            p1.setY(p1.y() - (p2.y() - p1.y()));
        }
        else if ( selectionFlags() & CenterToRadius )
        {
            const int radius = qwtMax(qwtAbs(p2.x() - p1.x()), 
                qwtAbs(p2.y() - p1.y()));
            p2.setX(p1.x() + radius);
            p2.setY(p1.y() + radius);
            p1.setX(p1.x() - radius);
            p1.setY(p1.y() - radius);
        }

#if QT_VERSION < 0x040000
        const QRect rect = QRect(p1, p2).normalize();
#else
        const QRect rect = QRect(p1, p2).normalized();
#endif
        switch(rubberBand())
        {
            case EllipseRubberBand:
                QwtPainter::drawEllipse(painter, rect);
                break;
            case RectRubberBand:
                QwtPainter::drawRect(painter, rect);
                break;
            default:
                break;
        }
    }
    else if ( selectionFlags() & PolygonSelection )
    {
        if ( rubberBand() == PolygonRubberBand )
            painter->drawPolyline(pa);
    }
}
Example #27
0
static inline bool isClose( double value1, double value2 )
{
  return qwtAbs( value1 - value2 ) < DBL_EPSILON;
}
Example #28
0
QwtDoubleInterval QwtScaleEngine::buildInterval(double v) const
{
    const double delta = (v == 0.0) ? 0.5 : qwtAbs(0.5 * v);
    return QwtDoubleInterval(v - delta, v + delta);
}
Example #29
0
QwtValueList QwtLog10ScaleEngine::buildMinorTicks(
    const QwtValueList &majorTicks, 
    int maxMinSteps, double stepSize) const
{   
    if (stepSize < 1.1)            // major step width is one decade
    {
        if ( maxMinSteps < 1 )
            return QwtValueList();
            
        int k0, kstep, kmax;
        
        if (maxMinSteps >= 8)
        {
            k0 = 2;
            kmax = 9;
            kstep = 1;
        }   
        else if (maxMinSteps >= 4)
        {
            k0 = 2;
            kmax = 8;
            kstep = 2;
        }   
        else if (maxMinSteps >= 2)
        {
            k0 = 2;
            kmax = 5;
            kstep = 3;
        }
        else
        {
            k0 = 5;
            kmax = 5;
            kstep = 1;
        }

        QwtValueList minorTicks;

        for (int i = 0; i < (int)majorTicks.count(); i++)
        {
            const double v = majorTicks[i];
            for (int k = k0; k<= kmax; k+=kstep)
                minorTicks += v * double(k);
        }

        return minorTicks;
    }
    else  // major step > one decade
    {
        double minStep = divideInterval(stepSize, maxMinSteps);
        if ( minStep == 0.0 )
            return QwtValueList();

        if ( minStep < 1.0 )
            minStep = 1.0;

        // # subticks per interval
        int nMin = qRound(stepSize / minStep) - 1;

        // Do the minor steps fit into the interval?

        if ( QwtScaleArithmetic::compareEps((nMin +  1) * minStep, 
            qwtAbs(stepSize), stepSize) > 0)
        {
            nMin = 0;
        }

        if (nMin < 1)
            return QwtValueList();      // no subticks

        // substep factor = 10^substeps
        const double minFactor = qwtMax(pow(10.0, minStep), 10.0);

        QwtValueList minorTicks;
        for (int i = 0; i < (int)majorTicks.count(); i++)
        {
            double val = majorTicks[i];
            for (int k=0; k< nMin; k++)
            {
                val *= minFactor;
                minorTicks += val;
            }
        }
        return minorTicks;
    }
}
Example #30
0
bool ScaleDiv::buildLogDiv(int maxMajSteps, int maxMinSteps, double majStep)
{
	double firstTick, lastTick;
	double lFirst, lLast;
	double val, sval, minStep, minFactor;
	int nMaj, nMin, minSize, i, k, k0, kstep, kmax, i0;
	int rv = true;
	double width;

	QVector<double> buffer;


	// Parameter range check
	maxMajSteps = qwtMax(1, qwtAbs(maxMajSteps));
	maxMinSteps = qwtMax(0, qwtAbs(maxMinSteps));
	majStep = qwtAbs(majStep);

	// boundary check
	limRange(d_hBound, LOG_MIN, LOG_MAX);
	limRange(d_lBound, LOG_MIN, LOG_MAX);

	// reset vectors
	d_minMarks.resize(0);
	d_majMarks.resize(0);

	if (d_lBound == d_hBound) return true;

	// scale width in decades
	width = log10(d_hBound) - log10(d_lBound);

	// scale width is less than one decade -> build linear scale
	if (width < 1.0)
	{
		rv = buildLinDiv(maxMajSteps, maxMinSteps, 0.0);
		// convert step width to decades
		if (d_majStep > 0)
			d_majStep = log10(d_majStep);

		return rv;
	}

	//
	//  Set up major scale divisions
	//
	if (majStep == 0.0)
		d_majStep = qwtCeil125(width * 0.999999 / double(maxMajSteps));
	else
		d_majStep = majStep;

	// major step must be >= 1 decade
	d_majStep = qwtMax(d_majStep, 1.0);


	lFirst = ceil((log10(d_lBound) - step_eps * d_majStep) / d_majStep) * d_majStep;
	lLast = floor((log10(d_hBound) + step_eps * d_majStep) / d_majStep) * d_majStep;

	firstTick = pow(10.0, lFirst);
	lastTick = pow(10.0, lLast);

	nMaj = qwtMin(10000, int(rint(qwtAbs(lLast - lFirst) / d_majStep)) + 1);

	d_majMarks.resize(nMaj);
	qwtLogSpace(d_majMarks.data(), d_majMarks.size(), firstTick, lastTick);


	//
	// Set up minor scale divisions
	//

	if ((d_majMarks.size() < 1) || (maxMinSteps < 1)) return true; // no minor marks

	if (d_majStep < 1.1) // major step width is one decade
	{
		if (maxMinSteps >= 8)
		{
			k0 = 2;
			kmax = 9;
			kstep = 1;
			minSize = (d_majMarks.size() + 1) * 8;
		}
		else if (maxMinSteps >= 4)
		{
			k0 = 2;
			kmax = 8;
			kstep = 2;
			minSize = (d_majMarks.size() + 1) * 4;
		}
		else if (maxMinSteps >= 2)
		{
			k0 = 2;
			kmax = 5;
			kstep = 3;
			minSize = (d_majMarks.size() + 1) * 2;
		}
		else
		{
			k0 = 5;
			kmax = 5;
			kstep = 1;
			minSize = (d_majMarks.size() + 1);
		}

		// resize buffer to the max. possible number of minor marks
		buffer.resize(minSize);

		// Are there minor ticks below the first major tick?
		if (d_lBound < firstTick)
			i0 = -1;
		else
			i0 = 0;

		minSize = 0;
		for (i = i0; i < (int) d_majMarks.size(); i++)
		{
			if (i >= 0)
				val = d_majMarks[i];
			else
				val = d_majMarks[0] / pow(10.0, d_majStep);

			for (k = k0; k <= kmax; k += kstep)
			{
				sval = val * double(k);
				if (limRange(sval, d_lBound, d_hBound, border_eps))
				{
					buffer[minSize] = sval;
					minSize++;
				}
			}
		}

		// copy values into the minMarks array
		//d_minMarks.duplicate(buffer.data(), minSize);
		d_minMarks.resize(minSize);
		qCopy(buffer.data(), buffer.data() + minSize, d_minMarks.begin());


	}
	else // major step > one decade
	{

		// substep width in decades, at least one decade
		minStep = qwtCeil125((d_majStep - step_eps * (d_majStep / double(maxMinSteps)))
				/ double(maxMinSteps));
		minStep = qwtMax(1.0, minStep);

		// # subticks per interval
		nMin = int(rint(d_majStep / minStep)) - 1;

		// Do the minor steps fit into the interval?
		if (qwtAbs(double(nMin + 1) * minStep - d_majStep) > step_eps * d_majStep)
			nMin = 0;

		if (nMin < 1) return true; // no subticks

		// resize buffer to max. possible number of subticks
		buffer.resize((d_majMarks.size() + 1) * nMin);

		// substep factor = 10^substeps
		minFactor = qwtMax(pow(10, minStep), 10.0);

		// Are there minor ticks below the first major tick?
		if (d_lBound < firstTick)
			i0 = -1;
		else
			i0 = 0;

		minSize = 0;
		for (i = i0; i < (int) d_majMarks.size(); i++)
		{
			if (i >= 0)
				val = d_majMarks[i];
			else
				val = firstTick / pow(10.0, d_majStep);

			for (k = 0; k < nMin; k++)
			{
				sval = (val *= minFactor);
				if (limRange(sval, d_lBound, d_hBound, border_eps))
				{
					buffer[minSize] = sval;
					minSize++;
				}
			}
		}
		//d_minMarks.duplicate(buffer.data(), minSize);
		d_minMarks.resize(minSize);
		qCopy(buffer.data(), buffer.data() + minSize, d_minMarks.begin());

	}

	return rv;
}