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;
}
Exemple #7
0
/**
 * 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;
}
Exemple #8
0
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;
}
Exemple #10
0
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() );
}