Search code examples
qtqglviewer

Wrong coordinates under Mouse on qglviewer


I draw some lines on qglviewer Now i need to computate the shortest way from mouse position to curve

void viewer::mouseMoveEvent(QMouseEvent *e) 
{
qglviewer::Vec xx(e->pos().x(), e->pos().y(), 1);
qglviewer::Vec xxx = this->camera()->unprojectedCoordinatesOf(xx);
float dist1track = std::numeric_limits<float>::max();
for(int i = 0; i < wtrjF.size(); i++)
{
   Atom atom = wtrjF[i];
   for(float t = 0; t < atom.pos.size(); t++)
   {
       if(dist1track > qSqrt(qPow(atom.pos[t][0] - xxx[0], 2) + qPow(atom.pos[t][1] - xxx[1], 2)))
       {
           dist1track = qSqrt(qPow(atom.pos[t][0] - xxx[0], 2) + qPow(atom.pos[t][1] - xxx[1], 2));
           name = atom.wname;
           wid = atom.wid;
           pos = QString::number(atom.pos[0][0]) + "_" + QString::number(atom.pos[0][1]);
       }
   }
}
qDebug()<<name<<dist1track;
}

But its give me wrong curve I think i got wrong coordinates under mouse cursor, but don't know how to fix it. Also tried get coords like:

qglviewer::Vec xx = camera()->pointUnderPixel(e->pos(), found);
qglviewer::Vec xx(e->pos().x(), e->pos().y(), 0);
glReadPixels(e->pos().x(), view[3] - e->pos().y(), 1, 1, GL_DEPTH_COMPONENT, 
GL_FLOAT, &z1);
qglviewer::Vec xx(e->pos().x(), e->pos().y(), z1);

Any advises?

Screen of mouse position

yea, now i draw line from cursor to nearest point. wrong coords


Solution

  • You should compute the distance from Atom points to the ray formed by the camera origin and the mouse clicked point.

    Mouse ray in real world coordinate system Source

    Here is an example :

    qreal distance_point_to_ray( qglviewer::Vec P, qglviewer::Vec orig, qglviewer::Vec dir ){
    
        qreal dotP_Ray = (P - orig) * dir; //<-- dot product of P on ray
        qreal dot_dir_dir = dir * dir;   //we need this when dir is not normalized.  
    
        qreal t0 = dotP_Ray / dot_dir_dir;
        qglviewer::Vec BP = P - (orig + dir * t0 );  //B is the projection of P on ray.
    
        return sqrt( BP * BP );
    }
    
    void viewer::mouseMoveEvent(QMouseEvent *e)
    {
        qglviewer::Vec orig, dir;
    
        //get mouse ray in real world coordinate.
        camera()->convertClickToLine(e->pos(), orig, dir);
    
        float dist1track = std::numeric_limits<float>::max();
        for(int i = 0; i < wtrjF.size(); i++)
        {
            Atom atom = wtrjF[i];
            for(int t = 0; t < atom.pos.size(); t++)
            {
                //assum that atom.pos is an array of qglviewer::Vec
                float d = distance_point_to_ray( atom.pos[t], orig, dir );
    
                if(dist1track > d )
                {
                    dist1track = d;
                    name = atom.wname;
                    wid = atom.wid;
    
                    pos = QString("POS: [%1, %2, %3]").arg(atom.pos[t][0], 0, 'g', 3 )
                            .arg(atom.pos[t][1], 0, 'g', 3 )
                            .arg(atom.pos[t][2], 0, 'g', 3 );
                }
            }
        }
    
        qDebug() << name << dist1track;
    }