# Thread: How to pick the line of a curve? (Pt BR Como pegar a linha de uma curva?)

1. Beginner
Join Date
Jul 2013
Posts
6
Qt products
Platforms

## How to pick the line of a curve? (Pt BR Como pegar a linha de uma curva?)

I have a simple curve with only two point. I wonder if there is a way to identify the line? I need to identify when I click on the line, when a polygon touches the line and drag the line to anywhere in the graph.

(Pt BR)Possuo uma curva simples com apenas dois ponto. Gostaria de saber se existe uma maneira de identificar a reta? Preciso identificar quando clico na reta, quando algum poligono encosta na reta e arrastar essa reta para qualquer lugar do grÃ¡fico.

2. Beginner
Join Date
Jul 2013
Posts
6
Qt products
Platforms

## Re: How to pick the line of a curve? (Pt BR Como pegar a linha de uma curva?)

After some research and testing there is the answer to click on the line. Thank those who have thought about.

const bool CLASSE::checkClickOnLine(const QPoint& _pos) const
{
const QwtPlot *plot = this->plot();
if ( plot == NULL )
return false;

// translate pos into the plot coordinates
const QPointF& curvePosF = transformWindowToCanvas(_pos);

const QwtPlotItemList curves = plot->itemList( QwtPlotItem::Rtti_PlotCurve );
for ( int i = curves.size() - 1; i >= 0; --i )
{
const QLineF line = curveLineAt( static_cast<const QwtPlotCurve *>( curves[i] ), curvePosF.x());
if ( !line.isNull() )
{
/**
* Similarity of triangle - SemelhanÃ§a de triÃ¢ngulo : ((y2-y1)/(x2-x1)) = ((y3-y1)/(x3-x1))
* P3 is a clicked point
**/
const double xP1 = plot->canvasMap(QwtPlot::xBottom).transform(line.p1().x ());
const double yP1 = line.p1().y();
const double xP2 = plot->canvasMap(QwtPlot::xBottom).transform(line.p2().x ());
const double yP2 = line.p2().y();
const double xP3 = plot->canvasMap(QwtPlot::xBottom).transform(curvePosF.x ());
const double yP3 = curvePosF.y();

if ((xP2 - xP1) == 0 || ( xP3 - xP1 ) == 0)
return false;

qreal T1 = (yP2 - yP1)/(xP2 - xP1);
qreal T2 = ( yP3 - yP1 )/( xP3 - xP1 );

if (T2 > 0 && T1 - TOLERANCE < T2 && T1 + TOLERANCE > T2 ) //TOLERANCE = 0.025
return true;
}
}

return false;
}

QLineF CLASSE:curveLineAt( const QwtPlotCurve *curve, double x ) const
{
QLineF line;

if ( curve->dataSize() >= 2 )
{
const QRectF br = curve->boundingRect();
if ( br.isValid() && x >= br.left() && x <= br.right() )
{
int index = qwtUpperSampleIndex<QPointF>(
*curve->data(), x, compareX() );

if ( index == -1 &&
x == curve->sample( curve->dataSize() - 1 ).x() )
{
// the last sample is excluded from qwtUpperSampleIndex
index = curve->dataSize() - 1;
}
if ( index > 0 )
{
line.setP1( curve->sample( index - 1 ) );
line.setP2( curve->sample( index ) );
}
}
}
return line;
}

struct compareX
{
inline bool operator()( const double x, const QPointF &pos ) const
{
return ( x < pos.x() );
}
};
Last edited by BrFla; 24th July 2013 at 16:03.

3. Beginner
Join Date
Jul 2013
Posts
6
Qt products
Platforms

## Re: How to pick the line of a curve? (Pt BR Como pegar a linha de uma curva?)

Use the comments from the previous example. Uso comentarios do exemplo anterior
It can be used for one or more curves in the graph. Este mÃ©todo pode ser usado quando voce possuir em seu grÃ¡fico uma ou mais curvas.
I return the clicked curve. Agora retorno a curva clicada.

QwtPlotCurve* CLASS::clickedCurve( const QPoint& _pos ) const
{
const QwtPlot *plot = this->plot();
if ( plot == NULL )
return NULL;

// translate pos into the plot coordinates
const QPointF &curvePosF = transformWindowToCanvas(_pos);

const QwtPlotItemList &curves = plot->itemList( QwtPlotItem::Rtti_PlotCurve );
for ( int i = curves.size() - 1; i >= 0; --i )
{

const QLineF line = curveLineAt( static_cast<const QwtPlotCurve *>( curves[i] ), curvePosF.x()); //Returns the two points that created the line
if ( !line.isNull() )
{
const double xP1 = plot->canvasMap(QwtPlot::xBottom).transform(line.p1().x ());
const double yP1 = line.p1().y();
const double xP2 = plot->canvasMap(QwtPlot::xBottom).transform(line.p2().x ());
const double yP2 = line.p2().y();
const double xP3 = plot->canvasMap(QwtPlot::xBottom).transform(curvePosF.x ());
const double yP3 = curvePosF.y();

if ((xP2 - xP1) == 0 || ( xP3 - xP1 ) == 0)
return NULL;

qreal RazaoT1 = (yP2 - yP1)/(xP2 - xP1);
qreal RazaoT2 = ( yP3 - yP1 )/( xP3 - xP1 );

if (RazaoT2 > 0 && RazaoT1 - TOLERANCIA < RazaoT2 && RazaoT1 + TOLERANCIA > RazaoT2)
return static_cast<QwtPlotCurve *>( curves[i] );

}
}

return NULL;
}

const QPointF CLASS::transformWindowToCanvas( const QPoint& _pos ) const
{
const QwtPlot* pPlot = this->plot();

const double dX = pPlot->canvasMap( QwtPlot::xBottom ).invTransform( _pos.x() );
const double dY = pPlot->canvasMap( QwtPlot::yLeft ).invTransform( _pos.y() );

return QPointF(dX, dY);
}

I hope I have helped
Last edited by BrFla; 26th July 2013 at 14:36.