int Plot::closestCurve(int xpos, int ypos, int &dist, int &point) { QwtScaleMap map[QwtPlot::axisCnt]; for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) map[axis] = canvasMap(axis); double dmin = 1.0e10; int key = -1; for (QMapIterator<int, QwtPlotCurve *> it = d_curves.begin(); it != d_curves.end(); ++it ) { QwtPlotCurve *c = (QwtPlotCurve *)it.data(); if (!c) continue; for (int i=0; i<c->dataSize(); i++) { double cx = map[c->xAxis()].xTransform(c->x(i)) - double(xpos); double cy = map[c->yAxis()].xTransform(c->y(i)) - double(ypos); double f = qwtSqr(cx) + qwtSqr(cy); if (f < dmin) { dmin = f; key = it.key(); point = i; } } } dist = int(sqrt(dmin)); return key; }
/*! 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 closest 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 { const size_t numSamples = dataSize(); if ( plot() == NULL || numSamples <= 0 ) return -1; const QwtSeriesData<QPointF> *series = data(); const QwtScaleMap xMap = plot()->canvasMap( xAxis() ); const QwtScaleMap yMap = plot()->canvasMap( yAxis() ); int index = -1; double dmin = 1.0e10; for ( uint i = 0; i < numSamples; i++ ) { const QPointF sample = series->sample( i ); const double cx = xMap.transform( sample.x() ) - pos.x(); const double cy = yMap.transform( sample.y() ) - pos.y(); const double f = qwtSqr( cx ) + qwtSqr( cy ); if ( f < dmin ) { index = i; dmin = f; } } if ( dist ) *dist = qSqrt( dmin ); return index; }
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; }
/*! 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; }
/*! \brief Set the scrolling mode and direction Called by QwtAbstractSlider \param pos Point in question \param scrollMode Scrolling mode \param direction Direction */ void QwtKnob::getScrollMode( const QPoint &pos, QwtAbstractSlider::ScrollMode &scrollMode, int &direction ) const { const double r = 0.5 * d_data->knobRect.width(); const double dx = d_data->knobRect.x() + r - pos.x(); const double dy = d_data->knobRect.y() + r - pos.y(); if ( qwtSqr( dx ) + qwtSqr( dy ) <= qwtSqr( r ) ) { // point is inside the knob scrollMode = QwtAbstractSlider::ScrMouse; direction = 0; } else // point lies outside { scrollMode = QwtAbstractSlider::ScrTimer; double arc = qAtan2( double( -dx ), double( dy ) ) * 180.0 / M_PI; if ( arc < d_data->angle ) direction = -1; else if ( arc > d_data->angle ) direction = 1; else direction = 0; } }
QPolygonF QwtSplineCurveFitter::fitParametric( const QPolygonF &points ) const { int i; const int size = points.size(); QPolygonF fittedPoints( d_data->splineSize ); QPolygonF splinePointsX( size ); QPolygonF splinePointsY( size ); const QPointF *p = points.data(); QPointF *spX = splinePointsX.data(); QPointF *spY = splinePointsY.data(); double param = 0.0; for ( i = 0; i < size; i++ ) { const double x = p[i].x(); const double y = p[i].y(); if ( i > 0 ) { const double delta = qSqrt( qwtSqr( x - spX[i-1].y() ) + qwtSqr( y - spY[i-1].y() ) ); param += qMax( delta, 1.0 ); } spX[i].setX( param ); spX[i].setY( x ); spY[i].setX( param ); spY[i].setY( y ); } d_data->spline.setPoints( splinePointsX ); if ( !d_data->spline.isValid() ) return points; const double deltaX = splinePointsX[size - 1].x() / ( d_data->splineSize - 1 ); for ( i = 0; i < d_data->splineSize; i++ ) { const double dtmp = i * deltaX; fittedPoints[i].setX( qRound( d_data->spline.value( dtmp ) ) ); } d_data->spline.setPoints( splinePointsY ); if ( !d_data->spline.isValid() ) return points; const double deltaY = splinePointsY[size - 1].x() / ( d_data->splineSize - 1 ); for ( i = 0; i < d_data->splineSize; i++ ) { const double dtmp = i * deltaY; fittedPoints[i].setY( qRound( d_data->spline.value( dtmp ) ) ); } return fittedPoints; }
/** * Returns the index of the closest curve to a point on the canvas. * Also returns index of the nearest data point on that curve. * @param xpos :: x coordinate of a point on the canvas in pixels. * @param ypos :: y coordinate of a point on the canvas in pixels. * @param dist :: ? * @param point :: Output index of the nearest data point to the point with coordinates (xpos,ypos) */ int Plot::closestCurve(int xpos, int ypos, int &dist, int &point) { QwtScaleMap map[QwtPlot::axisCnt]; for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) map[axis] = canvasMap(axis); double dmin = std::numeric_limits<double>::max(); int key = -1; for (QMap<int, QwtPlotItem *>::iterator iter = d_curves.begin(); iter != d_curves.end(); ++iter ) { QwtPlotItem *item = (QwtPlotItem *)iter.data(); if (!item) continue; if(item->rtti() != QwtPlotItem::Rtti_PlotSpectrogram) { PlotCurve *c = (PlotCurve *)item; DataCurve *dc = dynamic_cast<DataCurve *>(item); if (dc) { if (c->type() != Graph::Function && dc->hasLabels() && dc->selectedLabels(QPoint(xpos, ypos))){ dist = 0; return iter.key(); } else dc->setLabelsSelected(false); } for (int i=0; i<c->dataSize(); i++) { double cx = map[c->xAxis()].xTransform(c->x(i)) - double(xpos); double cy = map[c->yAxis()].xTransform(c->y(i)) - double(ypos); double f = qwtSqr(cx) + qwtSqr(cy); if (f < dmin && c->type() != Graph::ErrorBars) { dmin = f; key = iter.key(); point = i; } } } } dist = static_cast<int>(sqrt(dmin)); return key; }
void AmpFrame::timerEvent( QTimerEvent * ) { static double phs = 0; // // This amplifier generates its own input signal... // const double sig_bass = ( 1.0 + 0.1 * d_knbBass->value() ) * qFastSin( 13.0 * phs ); const double sig_mid_l = qFastSin( 17.0 * phs ); const double sig_mid_r = qFastCos( 17.5 * phs ); const double sig_trbl_l = 0.5 * ( 1.0 + 0.1 * d_knbTreble->value() ) * qFastSin( 35.0 * phs ); const double sig_trbl_r = 0.5 * ( 1.0 + 0.1 * d_knbTreble->value() ) * qFastSin( 34.0 * phs ); double sig_l = 0.05 * d_master * d_knbVolume->value() * qwtSqr( sig_bass + sig_mid_l + sig_trbl_l ); double sig_r = 0.05 * d_master * d_knbVolume->value() * qwtSqr( sig_bass + sig_mid_r + sig_trbl_r ); double balance = 0.1 * d_knbBalance->value(); if ( balance > 0 ) sig_l *= ( 1.0 - balance ); else sig_r *= ( 1.0 + balance ); if ( sig_l > 0.01 ) sig_l = 20.0 * log10( sig_l ); else sig_l = -40.0; if ( sig_r > 0.01 ) sig_r = 20.0 * log10( sig_r ); else sig_r = - 40.0; d_thmLeft->setValue( sig_l ); d_thmRight->setValue( sig_r ); phs += M_PI / 100; if ( phs > M_PI ) phs = 0; }
/*! \brief Find the marker which is closest to a given point. \param xpos \param ypos coordinates of a point in the plotting region \retval dist Distance in points between the marker and the specified point. \return Key of the closest marker or 0 if no marker was found */ long QwtPlot::closestMarker(int xpos, int ypos, int &dist) const { QwtDiMap map[axisCnt]; for ( int axis = 0; axis < axisCnt; axis++ ) map[axis] = canvasMap(axis); long rv = 0; double dmin = 1.0e10; QwtPlotMarkerIterator itm = markerIterator(); for (QwtPlotMarker *m = itm.toFirst(); m != 0; m = ++itm ) { double cx = map[m->xAxis()].xTransform(m->xValue()); double cy = map[m->yAxis()].xTransform(m->yValue()); if (m->lineStyle() == QwtMarker::HLine) { if (m->symbol().style() == QwtSymbol::None) cx = double(xpos); } else if (m->lineStyle() == QwtMarker::VLine) { if (m->symbol().style() == QwtSymbol::None) cy = double(ypos); } double f = qwtSqr(cx - double(xpos)) + qwtSqr(cy - double(ypos)); if (f < dmin) { dmin = f; rv = itm.currentKey(); } } dist = int(sqrt(dmin)); return rv; }
void TunerFrame::adjustFreq( double frq ) { const double factor = 13.0 / ( 108 - 87.5 ); const double x = ( frq - 87.5 ) * factor; const double field = qwtSqr( qFastSin( x ) * qFastCos( 4.0 * x ) ); d_thermoTune->setValue( field ); if ( d_sliderFrequency->value() != frq ) d_sliderFrequency->setValue( frq ); if ( d_wheelFrequency->value() != frq ) d_wheelFrequency->setValue( frq ); Q_EMIT fieldChanged( field ); }
void TunerFrame::adjustFreq(double frq) { const double factor = 13.0 / (108 - 87.5); const double x = (frq - 87.5) * factor; const double field = qwtSqr(sin(x) * cos(4.0 * x)); d_thmTune->setValue(field); if (d_sldFreq->value() != frq) d_sldFreq->setValue(frq); if (d_whlFreq->value() != frq) d_whlFreq->setValue(frq); emit fieldChanged(field); }
void CanvasPicker::select( const QPoint &pos, Qt::KeyboardModifiers modifiers ) { m_selectionPoint = pos; m_previousPoint = pos; double minDistanceMarkers = 10e10; double minDistanceKnots = 10e10; MarkerItem* markerWithMinDistance = 0; KnotItem* knotWithMinDistance = 0; int selectionType = -1; PlotWidget* plotWidget = dynamic_cast<PlotWidget*>( plot() ); const QwtScaleMap xMap = plot()->canvasMap( QwtPlot::xBottom ); const QwtScaleMap yMap = plot()->canvasMap( QwtPlot::yLeft ); const QwtPlotItemList& itemList = plot()->itemList(); for ( QwtPlotItemIterator it = itemList.begin(); it != itemList.end(); ++it ) { if ( ( *it )->rtti() == Globals::Rtti_PlotMarker ) { MarkerItem* marker = static_cast<MarkerItem*>( *it ); const double deltaX = xMap.transform( marker->xValue() ) - pos.x(); const double deltaY = yMap.transform( marker->yValue() ) - pos.y(); const double distance = qSqrt( qwtSqr( deltaX ) + qwtSqr( deltaY ) ); if ( distance < minDistanceMarkers ) { minDistanceMarkers = distance; markerWithMinDistance = marker; } } else if ( ( *it )->rtti() == Globals::Rtti_PlotKnot ) { KnotItem* knot = static_cast<KnotItem*>( *it ); const double distance = qAbs( xMap.transform( knot->coordinate() ) - pos.x() ); if( distance < minDistanceKnots ) { minDistanceKnots = distance; knotWithMinDistance = knot; } } } // Give a priority to the markers if( minDistanceMarkers < Globals::SELECTION_PIXEL_TOLERANCE && markerWithMinDistance != 0 ) { m_itemToPick = markerWithMinDistance; selectionType = Globals::Rtti_PlotMarker; } else if( minDistanceKnots < Globals::SELECTION_PIXEL_TOLERANCE && knotWithMinDistance != 0 ) { m_itemToPick = knotWithMinDistance; selectionType = Globals::Rtti_PlotKnot; } if( selectionType == -1 ) { emit picked( modifiers, 0 ); return; } QList<QwtPlotItem*>& listOfSelectedItems = plotWidget->listOfSelectedItems( selectionType ); if( listOfSelectedItems.count() == 0 ) { // Select and allow the user to drag and drop. emit picked( modifiers, m_itemToPick ); m_typeOfItemsToDrag = selectionType; m_dragAndDropInProgress = true; m_itemToPick = 0; } else { if( listOfSelectedItems.contains( m_itemToPick ) ) { // We don't know yet whether the user wants to do a selection or a drag and drop operation. // The picking operation will be detected in CanvasPicker::release(). m_typeOfItemsToDrag = selectionType; m_dragAndDropInProgress = true; } else { emit picked( modifiers, m_itemToPick ); m_itemToPick = 0; if( listOfSelectedItems.count() == 1 ) { m_typeOfItemsToDrag = selectionType; m_dragAndDropInProgress = true; } } } }
/*! \brief Draw a spline \param painter Painter \param xMap x map \param yMap y map \sa QwtCurve::draw, QwtCurve::drawCurve, QwtCurve::drawDots, QwtCurve::drawLines, QwtCurve::drawSteps, QwtCurve::drawSticks */ void QwtCurve::drawSpline(QPainter *painter, const QwtDiMap &xMap, const QwtDiMap &yMap) { register int i; int size = dataSize(); double *txval = new double[size]; double *tyval = new double[size]; if ( !txval || !tyval ) { if (txval) delete[] txval; if (tyval) delete[] tyval; return; } QPointArray polyline(d_splineSize); // // Transform x and y values to window coordinates // to avoid a distinction between linear and // logarithmic scales. // for (i=0;i<size;i++) { txval[i] = xMap.xTransform(x(i)); tyval[i] = yMap.xTransform(y(i)); } int stype; if (! (d_options & (Yfx|Xfy|Parametric))) { if (qwtChkMono(txval, size)) { stype = Yfx; } else { if(qwtChkMono(tyval, size)) { stype = Xfy; } else { stype = Parametric; if ( (d_options & Periodic) || ( (x(0) == x(size-1)) && (y(0) == y(size-1)))) { stype |= Periodic; } } } } else { stype = d_options; } if (stype & Parametric) { double *param = new double[size]; if (param) { // // setup parameter vector // param[0] = 0.0; for (i=1; i<size; i++) { double delta = sqrt( qwtSqr(txval[i] - txval[i-1]) + qwtSqr( tyval[i] - tyval[i-1])); param[i] = param[i-1] + qwtMax(delta, 1.0); } // // setup splines int rc = d_spx.recalc(param, txval, size, stype & Periodic); if (!rc) rc = d_spy.recalc(param, tyval, size, stype & Periodic); if (rc) { drawLines(painter, xMap, yMap, 0, size - 1); } else { // fill point array double delta = param[size - 1] / double(d_splineSize-1); for (i=0;i<d_splineSize;i++) { double dtmp = delta * double(i); polyline.setPoint(i, int(floor (d_spx.value(dtmp) + 0.5)), int(floor (d_spy.value(dtmp) + 0.5))); } } delete[] param; } } else if (stype & Xfy) { if (tyval[size-1] < tyval[0]) { qwtTwistArray(txval, size); qwtTwistArray(tyval, size); } // 1. Calculate spline coefficients int rc = d_spx.recalc(tyval, txval, size, stype & Periodic); if (rc) // an error occurred { drawLines(painter, xMap, yMap, 0, size - 1); } else // Spline OK { double ymin = qwtGetMin(tyval, size); double ymax = qwtGetMax(tyval, size); double delta = (ymax - ymin) / double(d_splineSize - 1); for (i=0;i<d_splineSize;i++) { double dtmp = ymin + delta * double(i); polyline.setPoint(i, int(floor(d_spx.value(dtmp) + 0.5)), int(floor(dtmp + 0.5))); } } } else { if (txval[size-1] < txval[0]) { qwtTwistArray(tyval, size); qwtTwistArray(txval, size); } // 1. Calculate spline coefficients int rc = d_spy.recalc(txval, tyval, size, stype & Periodic); if (rc) // error { drawLines(painter, xMap, yMap, 0, size - 1); } else // Spline OK { double xmin = qwtGetMin(txval, size); double xmax = qwtGetMax(txval, size); double delta = (xmax - xmin) / double(d_splineSize - 1); for (i=0;i<d_splineSize;i++) { double dtmp = xmin + delta * double(i); polyline.setPoint(i, int(floor (dtmp + 0.5)), int(floor(d_spy.value(dtmp) + 0.5))); } } } delete[] txval; delete[] tyval; QwtPainter::drawPolyline(painter, polyline); if ( painter->brush().style() != Qt::NoBrush ) { closePolyline(xMap, yMap, polyline); painter->setPen(QPen(Qt::NoPen)); QwtPainter::drawPolygon(painter, polyline); } }
/*! \brief Render a sub-rectangle of an image renderTile() is called by renderImage() to render different parts of the image by concurrent threads. \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 imagePos Top/left position of the image in painter coordinates \param tile Sub-rectangle of the tile in painter coordinates \param image Image to be rendered \sa setRenderThreadCount() \note renderTile needs to be reentrant */ void QwtPolarSpectrogram::renderTile( const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, const QPointF &pole, const QPoint &imagePos, const QRect &tile, QImage *image ) const { const QwtInterval intensityRange = d_data->data->interval( Qt::ZAxis ); if ( !intensityRange.isValid() ) return; const bool doFastAtan = testPaintAttribute( ApproximatedAtan ); const int y0 = imagePos.y(); const int y1 = tile.top(); const int y2 = tile.bottom(); const int x0 = imagePos.x(); const int x1 = tile.left(); const int x2 = tile.right(); if ( d_data->colorMap->format() == QwtColorMap::RGB ) { for ( int y = y1; y <= y2; y++ ) { const double dy = pole.y() - y; const double dy2 = qwtSqr( dy ); QRgb *line = reinterpret_cast<QRgb *>( image->scanLine( y - y0 ) ); line += x1 - x0; for ( int x = x1; x <= x2; x++ ) { const double dx = x - pole.x(); double a = doFastAtan ? qwtFastAtan2( dy, dx ) : qAtan2( dy, dx ); if ( a < 0.0 ) a += 2 * M_PI; if ( a < azimuthMap.p1() ) a += 2 * M_PI; const double r = qSqrt( qwtSqr( dx ) + dy2 ); const double azimuth = azimuthMap.invTransform( a ); const double radius = radialMap.invTransform( r ); const double value = d_data->data->value( azimuth, radius ); *line++ = d_data->colorMap->rgb( intensityRange, value ); } } } else if ( d_data->colorMap->format() == QwtColorMap::Indexed ) { for ( int y = y1; y <= y2; y++ ) { const double dy = pole.y() - y; const double dy2 = qwtSqr( dy ); unsigned char *line = image->scanLine( y - y0 ); line += x1 - x0; for ( int x = x1; x <= x2; x++ ) { const double dx = x - pole.x(); double a = doFastAtan ? qwtFastAtan2( dy, dx ) : qAtan2( dy, dx ); if ( a < 0.0 ) a += 2 * M_PI; if ( a < azimuthMap.p1() ) a += 2 * M_PI; const double r = qSqrt( qwtSqr( dx ) + dy2 ); const double azimuth = azimuthMap.invTransform( a ); const double radius = radialMap.invTransform( r ); const double value = d_data->data->value( azimuth, radius ); *line++ = d_data->colorMap->colorIndex( intensityRange, value ); } } } }
/*! Convert and assign values from a point in Cartesian coordinates \param p Point in Cartesian coordinates */ void QwtPointPolar::setPoint( const QPointF &p ) { d_radius = qSqrt( qwtSqr( p.x() ) + qwtSqr( p.y() ) ); d_azimuth = qAtan2( p.y(), p.x() ); }