/*!
  Find the closest curve point for a specific position

  \param pos Position, where to look for the closest curve point
  \param dist If dist != NULL, closestPoint() returns the distance between
              the position and the clostest curve point
  \return Index of the closest curve point, or -1 if none can be found 
          ( f.e when the curve has no points )
  \note closestPoint() implements a dumb algorithm, that iterates 
        over all points
*/
int QwtPlotCurve::closestPoint(const QPoint &pos, double *dist) const
{
    if ( plot() == NULL || dataSize() <= 0 )
        return -1;

    const QwtScaleMap xMap = plot()->canvasMap(xAxis());
    const QwtScaleMap yMap = plot()->canvasMap(yAxis());

    int index = -1;
    double dmin = 1.0e10;

    for (int i=0; i < dataSize(); i++)
    {
        const double cx = xMap.xTransform(x(i)) - pos.x();
        const double cy = yMap.xTransform(y(i)) - pos.y();

        const double f = qwtSqr(cx) + qwtSqr(cy);
        if (f < dmin)
        {
            index = i;
            dmin = f;
        }
    }
    if ( dist )
        *dist = sqrt(dmin);

    return index;
}
Beispiel #2
0
void PlotCurve::drawSideLines(QPainter *p, const QwtScaleMap &xMap,
                              const QwtScaleMap &yMap, int from, int to) const {
  if (!p || dataSize() <= 0)
    return;

  if (to < 0)
    to = dataSize() - 1;

  p->save();
  QPen pen = p->pen();
  pen.setCapStyle(Qt::FlatCap);
  pen.setJoinStyle(Qt::MiterJoin);
  p->setPen(pen);

  double lw = 0.5 * pen.widthF();
  const double xl = xMap.xTransform(x(from)) - lw;
  const double xr = xMap.xTransform(x(to)) + lw;
  const double yl = yMap.xTransform(y(from)) - lw;
  const double yr = yMap.xTransform(y(to)) - lw;
  const double base = yMap.xTransform(baseline());

  p->drawLine(QPointF(xl, yl), QPointF(xl, base));
  p->drawLine(QPointF(xr, yr), QPointF(xr, base));

  p->restore();
}
/*!
  Calculate the viewBox from an rect and boundingRect().

  \param rect Rectangle in scale coordinates
  \return viewBox View Box, see QSvgRenderer::viewBox
*/
QwtDoubleRect QwtPlotSvgItem::viewBox(const QwtDoubleRect &rect) const
{
#if QT_VERSION >= 0x040100
    const QSize sz = d_data->renderer.defaultSize();
#else
#if QT_VERSION > 0x040000
    const QSize sz(d_data->picture.width(),
        d_data->picture.height());
#else
    QPaintDeviceMetrics metrics(&d_data->picture);
    const QSize sz(metrics.width(), metrics.height());
#endif
#endif
    const QwtDoubleRect br = boundingRect();

    if ( !rect.isValid() || !br.isValid() || sz.isNull() )
        return QwtDoubleRect();

    QwtScaleMap xMap;
    xMap.setScaleInterval(br.left(), br.right());
    xMap.setPaintInterval(0, sz.width());

    QwtScaleMap yMap;
    yMap.setScaleInterval(br.top(), br.bottom());
    yMap.setPaintInterval(sz.height(), 0);

    const double x1 = xMap.xTransform(rect.left());
    const double x2 = xMap.xTransform(rect.right());
    const double y1 = yMap.xTransform(rect.bottom());
    const double y2 = yMap.xTransform(rect.top());

    return QwtDoubleRect(x1, y1, x2 - x1, y2 - y1);
}
void Spectrogram::drawContourLines (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtRasterData::ContourLines &contourLines) const
{
	//QwtPlotSpectrogram::drawContourLines(p, xMap, yMap, contourLines);

	QwtValueList levels = contourLevels();
    const int numLevels = (int)levels.size();
    for (int l = 0; l < numLevels; l++){
        const double level = levels[l];

        QPen pen = defaultContourPen();
        if ( pen.style() == Qt::NoPen )
            pen = contourPen(level);

        if ( pen.style() == Qt::NoPen )
            continue;

        p->setPen(QwtPainter::scaledPen(pen));

        const QPolygonF &lines = contourLines[level];
        for ( int i = 0; i < (int)lines.size(); i += 2 ){
            const QPointF p1( xMap.xTransform(lines[i].x()),
                yMap.transform(lines[i].y()) );
            const QPointF p2( xMap.xTransform(lines[i + 1].x()),
                yMap.transform(lines[i + 1].y()) );

            p->drawLine(p1, p2);
        }
    }

	if (d_show_labels)
		updateLabels(p, xMap, yMap, contourLines);
}
/*!
  Draw step function

  The direction of the steps depends on Inverted attribute.

  \param painter Painter
  \param xMap x map
  \param yMap y map
  \param from index of the first point to be painted
  \param to index of the last point to be painted

  \sa CurveAttribute, setCurveAttribute(),
      draw(), drawCurve(), drawDots(), drawLines(), drawSticks()
*/
void QwtPlotCurve::drawSteps(QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    int from, int to) const
{
    QwtPolygonF polyline(2 * (to - from) + 1);

    bool inverted = d_data->curveType == Yfx;
    if ( d_data->attributes & Inverted )
        inverted = !inverted;

    int i,ip;
    for (i = from, ip = 0; i <= to; i++, ip += 2)
    {
        const double xi = xMap.xTransform(x(i));
        const double yi = yMap.xTransform(y(i));

        if ( ip > 0 )
        {
            if (inverted)
                polyline[ip - 1] = QPointF(polyline[ip-2].x(), yi);
            else
                polyline[ip - 1] = QPointF(xi, polyline[ip-2].y());
        }

        polyline[ip] = QPointF(xi, yi);
    }

    if ( d_data->paintAttributes & ClipPolygons )
        polyline = QwtClipper::clipPolygonF(painter->window(), polyline);

    QwtPainter::drawPolyline(painter, polyline);

    if ( d_data->brush.style() != Qt::NoBrush )
        fillCurve(painter, xMap, yMap, polyline);
}
Beispiel #6
0
/*!
  Draw lines

  \param painter Painter
  \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI
  \param radialMap Maps radius values into painter coordinates.
  \param pole Position of the pole in painter coordinates
  \param from index of the first point to be painted
  \param to index of the last point to be painted.
  \sa draw(), drawLines(), setCurveFitter()
*/
void QwtPolarCurve::drawLines( QPainter *painter,
                               const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap,
                               const QwtDoublePoint &pole, int from, int to ) const
{
  int size = to - from + 1;
  if ( size <= 0 )
    return;

  QwtPolygon polyline;
  if ( d_data->curveFitter )
  {
#if QT_VERSION < 0x040000
    QwtArray<QwtDoublePoint> points( size );
#else
    QwtPolygonF points( size );
#endif
    for ( int j = from; j <= to; j++ )
      points[j - from] = QwtDoublePoint( azimuth( j ), radius( j ) );

    points = d_data->curveFitter->fitCurve( points );

    polyline.resize( points.size() );
    for ( int i = 0; i < ( int )points.size(); i++ )
    {
      const QwtPolarPoint point( points[i].x(), points[i].y() );

      double r = radialMap.xTransform( point.radius() );
      const double a = azimuthMap.xTransform( point.azimuth() );
      polyline.setPoint( i, qwtPolar2Pos( pole, r, a ).toPoint() );
    }
  }
  else
  {
    polyline.resize( size );

    for ( int i = from; i <= to; i++ )
    {
      const QwtPolarPoint point = sample( i );

      double r = radialMap.xTransform( point.radius() );
      const double a = azimuthMap.xTransform( point.azimuth() );
      polyline.setPoint( i - from, qwtPolar2Pos( pole, r, a ).toPoint() );
    }
  }

  QRect clipRect = painter->window();
  clipRect.setRect( clipRect.x() - 1, clipRect.y() - 1,
                    clipRect.width() + 2, clipRect.height() + 2 );

  polyline = QwtClipper::clipPolygon( clipRect, polyline );

  QwtPainter::drawPolyline( painter, polyline );
}
/*!
  Draw lines from the pole

  \param painter Painter
  \param canvasRect Contents rect of the canvas in painter coordinates
  \param pole Position of the pole in painter coordinates
  \param radius Length of the lines in painter coordinates
  \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI
  \param values Azimuth values, indicating the direction of the lines
*/
void QwtPolarGrid::drawRays(
  QPainter *painter, const QwtDoubleRect &canvasRect,
  const QwtDoublePoint &pole, double radius,
  const QwtScaleMap &azimuthMap, const QwtValueList &values ) const
{
  for ( int i = 0; i < int( values.size() ); i++ )
  {
    double azimuth = azimuthMap.xTransform( values[i] );
    azimuth = ::fmod( azimuth, 2 * M_PI );

    bool skipLine = false;
    if ( testDisplayFlag( SmartScaleDraw ) )
    {
      const QwtAbstractScaleDraw::ScaleComponent bone =
        QwtAbstractScaleDraw::Backbone;
      if ( isClose( azimuth, 0.0 ) )
      {
        const AxisData &axis = d_data->axisData[QwtPolar::AxisRight];
        if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
          skipLine = true;
      }
      else if ( isClose( azimuth, M_PI / 2 ) )
      {
        const AxisData &axis = d_data->axisData[QwtPolar::AxisTop];
        if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
          skipLine = true;
      }
      else if ( isClose( azimuth, M_PI ) )
      {
        const AxisData &axis = d_data->axisData[QwtPolar::AxisLeft];
        if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
          skipLine = true;
      }
      else if ( isClose( azimuth, 3 * M_PI / 2.0 ) )
      {
        const AxisData &axis = d_data->axisData[QwtPolar::AxisBottom];
        if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
          skipLine = true;
      }
    }
    if ( !skipLine )
    {
      const QwtDoublePoint pos = qwtPolar2Pos( pole, radius, azimuth );

      /*
          Qt4 is horrible slow, when painting primitives,
          with coordinates far outside the visible area.
       */

      QwtPolygon pa( 2 );
      pa.setPoint( 0, pole.toPoint() );
      pa.setPoint( 1, pos.toPoint() );

      if ( testDisplayFlag( ClipGridLines ) )
        pa = QwtClipper::clipPolygon( canvasRect.toRect(), pa );

      QwtPainter::drawPolyline( painter, pa );
    }
  }
}
Beispiel #8
0
/*!
  Draw symbols

  \param painter Painter
  \param symbol Curve symbol
  \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI
  \param radialMap Maps radius values into painter coordinates.
  \param pole Position of the pole in painter coordinates
  \param from index of the first point to be painted
  \param to index of the last point to be painted.
  \sa setSymbol(), draw(), drawCurve()
*/
void QwtPolarCurve::drawSymbols( QPainter *painter, const QwtSymbol &symbol,
                                 const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap,
                                 const QwtDoublePoint &pole, int from, int to ) const
{
  painter->setBrush( symbol.brush() );
  painter->setPen( symbol.pen() );

  QRect rect;
  rect.setSize( QwtPainter::metricsMap().screenToLayout( symbol.size() ) );

  for ( int i = from; i <= to; i++ )
  {
    const QwtPolarPoint point = sample( i );
    const double r = radialMap.xTransform( point.radius() );
    const double a = azimuthMap.xTransform( point.azimuth() );

    const QPoint pos = qwtPolar2Pos( pole, r, a ).toPoint();

    rect.moveCenter( pos );
    symbol.draw( painter, rect );
  }
}
Beispiel #9
0
/*!
   \brief Calculate the bounding rect of the plot area

   The plot area depends on the zoom parameters.

   \param canvasRect Rectangle of the canvas
   \return Rectangle for displaying 100% of the plot
*/
QwtDoubleRect QwtPolarPlot::plotRect( const QRect &canvasRect ) const
{
  const QwtScaleDiv *sd = scaleDiv( QwtPolar::Radius );
  const QwtScaleEngine *se = scaleEngine( QwtPolar::Radius );

  const int margin = plotMarginHint();
  const QRect cr = canvasRect;
  const int radius = qwtMin( cr.width(), cr.height() ) / 2 - margin;

  QwtScaleMap map;
  map.setTransformation( se->transformation() );
  map.setPaintXInterval( 0.0, radius / d_data->zoomFactor );
#if QWT_VERSION < 0x050200
  map.setScaleInterval( sd->lBound(), sd->hBound() );
#else
  map.setScaleInterval( sd->lowerBound(), sd->upperBound() );
#endif

  double v = map.s1();
  if ( map.s1() <= map.s2() )
    v += d_data->zoomPos.radius();
  else
    v -= d_data->zoomPos.radius();
  v = map.xTransform( v );

  const QwtDoublePoint off =
    QwtPolarPoint( d_data->zoomPos.azimuth(), v ).toPoint();

  QwtDoublePoint center( cr.center().x(), cr.top() + margin + radius );
  center -= QwtDoublePoint( off.x(), -off.y() );

  QwtDoubleRect rect( 0, 0, 2 * map.p2(), 2 * map.p2() );
  rect.moveCenter( center );

  return rect;
}
/*!
  \brief Draw lines

  If the CurveAttribute Fitted is enabled a QwtCurveFitter tries
  to interpolate/smooth the curve, before it is painted.

  \param painter Painter
  \param xMap x map
  \param yMap y map
  \param from index of the first point to be painted
  \param to index of the last point to be painted

  \sa setCurveAttribute(), setCurveFitter(), draw(), 
      drawLines(), drawDots(), drawSteps(), drawSticks()
*/
void QwtPlotCurve::drawLines(QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap, 
    int from, int to) const
{
    int size = to - from + 1;
    if ( size <= 0 )
        return;

    QwtPolygon polyline;
    if ( ( d_data->attributes & Fitted ) && d_data->curveFitter )
    {
        // Transform x and y values to window coordinates
        // to avoid a distinction between linear and
        // logarithmic scales.

#if QT_VERSION < 0x040000
        QwtArray<QwtDoublePoint> points(size);
#else
        QPolygonF points(size);
#endif
        for (int i = from; i <= to; i++)
        {
            QwtDoublePoint &p = points[i];
            p.setX( xMap.xTransform(x(i)) );
            p.setY( yMap.xTransform(y(i)) );
        }

        points = d_data->curveFitter->fitCurve(points);
        size = points.size();

        if ( size == 0 )
            return;

        // Round QwtDoublePoints to QPoints
        // When Qwt support for Qt3 has been dropped (Qwt 6.x)
        // we will use a doubles for painting and the following
        // step will be obsolete.

        polyline.resize(size);

        const QwtDoublePoint *p = points.data();
        QPoint *pl = polyline.data();
        if ( d_data->paintAttributes & PaintFiltered )
        {

            QPoint pp(qRound(p[0].x()), qRound(p[0].y()));
            pl[0] = pp;

            int count = 1;
            for (int i = 1; i < size; i++)
            {
                const QPoint pi(qRound(p[i].x()), qRound(p[i].y()));
                if ( pi != pp )
                {
                    pl[count++] = pi;
                    pp = pi;
                }
            }
            if ( count != size )
                polyline.resize(count);
        }
        else
        {
            for ( int i = 0; i < size; i++ )
            {
                pl[i].setX( qRound(p[i].x()) );
                pl[i].setY( qRound(p[i].y()) );
            }
        }
    }
    else
    {
        polyline.resize(size);

        if ( d_data->paintAttributes & PaintFiltered )
        {
            QPoint pp( xMap.transform(x(from)), yMap.transform(y(from)) );
            polyline.setPoint(0, pp);

            int count = 1;
            for (int i = from + 1; i <= to; i++)
            {
                const QPoint pi(xMap.transform(x(i)), yMap.transform(y(i)));
                if ( pi != pp )
                {
                    polyline.setPoint(count, pi);
                    count++;

                    pp = pi;
                }
            }
            if ( count != size )
                polyline.resize(count);
        }
        else
        {
            for (int i = from; i <= to; i++)
            {
                int xi = xMap.transform(x(i));
                int yi = yMap.transform(y(i));

                polyline.setPoint(i - from, xi, yi);
            }
        }
    }

    if ( d_data->paintAttributes & ClipPolygons )
        polyline = QwtClipper::clipPolygon(painter->window(), polyline);

    QwtPainter::drawPolyline(painter, polyline);

    if ( d_data->brush.style() != Qt::NoBrush )
        fillCurve(painter, xMap, yMap, polyline);
}
/*!
  Draw dots

  \param painter Painter
  \param xMap x map
  \param yMap y map
  \param from index of the first point to be painted
  \param to index of the last point to be painted

  \sa draw(), drawCurve(), drawSticks(), drawLines(), drawSteps()
*/
void QwtPlotCurve::drawDots(QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    int from, int to) const
{
    const QRect window = painter->window();
    if ( window.isEmpty() )
        return;

    const bool doFill = d_data->brush.style() != Qt::NoBrush;

    QwtPolygonF polyline;
    if ( doFill )
        polyline.resize(to - from + 1);

    if ( to > from && d_data->paintAttributes & PaintFiltered )
    {
        if ( doFill )
        {
            QPointF pp( xMap.xTransform(x(from)), yMap.xTransform(y(from)) );

            QwtPainter::drawPoint(painter, pp.x(), pp.y());
            polyline[0] = pp;

            int count = 1;
            for (int i = from + 1; i <= to; i++)
            {
                const QPointF pi(xMap.xTransform(x(i)), yMap.xTransform(y(i)));
                if ( pi != pp )
                {
                    QwtPainter::drawPoint(painter, pi.x(), pi.y());

                    polyline[count] = pi;
                    count++;

                    pp = pi;
                }
            }
            if ( int(polyline.size()) != count )
                polyline.resize(count);
        }
        else
        {
            // if we don't need to fill, we can sort out
            // duplicates independent from the order

            PrivateData::PixelMatrix pixelMatrix(window);

            for (int i = from; i <= to; i++)
            {
                const QPointF p( xMap.xTransform(x(i)), yMap.xTransform(y(i)) );

                if ( pixelMatrix.testPixel(p.toPoint()) )
                    QwtPainter::drawPoint(painter, p.x(), p.y());
            }
        }
    }
    else
    {
        for (int i = from; i <= to; i++)
        {
            const double xi = xMap.xTransform(x(i));
            const double yi = yMap.xTransform(y(i));
            QwtPainter::drawPoint(painter, xi, yi);

            if ( doFill )
                polyline[i - from] = QPointF(xi, yi);
        }
    }

    if ( doFill )
    {
        if ( d_data->paintAttributes & ClipPolygons )
            polyline = QwtClipper::clipPolygonF(painter->window(), polyline);

        fillCurve(painter, xMap, yMap, polyline);
    }
}