qglviewer上鼠标下的坐标错误

时间:2018-12-25 15:05:41

标签: qt qglviewer

我在qglviewer上画了一些线 现在我需要计算从鼠标位置到曲线的最短路径

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;
}

但是它给了我错误的曲线 我认为鼠标光标下的坐标错误,但是不知道如何解决。 还尝试获取坐标,例如:

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);

有人建议吗?

鼠标位置屏幕

是的,现在我从光标到最近的点画一条线。错误的坐标

1 个答案:

答案 0 :(得分:0)

您应该计算从原子点到相机原点和鼠标单击点形成的射线的距离。

Mouse ray in real world coordinate system Source

这里是一个例子:

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;
}