Неправильные координаты под мышкой на 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 ответ
Решение
Вы должны вычислить расстояние от точек атома до луча, образованного точкой начала камеры и точкой щелчка мыши.
https://stackru.com/images/eba0ecbcaaf6646f5d03ed b108ac0311a87a24c7.jpg Источник
Вот пример:
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;
}