《PCL点云库学习&VS2010(X64)》Part 47 鼠标选取点云坐标的计算原理

来源:互联网 发布:淘宝售后人工客服电话 编辑:程序博客网 时间:2024/06/06 19:48

openGL从鼠标坐标转换到三维坐标转换的方法

利用鼠标获取的二维坐标,映射到三维点云中,查找出对应的三维坐标,是选点的基本算法步骤。
参考博文:
在opengl下从鼠标坐标转换到三维坐标的方法

基本原理:

1、利用鼠标的mousePress()函数找到鼠标坐标点;
2、屏幕坐标转换:将鼠标坐标转换到屏幕坐标;
3、glReadPixels()函数找到深度坐标winZ;
4、gluUnProject()找到对应投影坐标Z。

注:

1、openGL为左下角坐标系;
2、gluUnProject()函数得到的是模型坐标,用射线和要检测的目标求 交点,获取三维坐标。利用该原理可以实现影像与点云交互选点,详细解释见后面的参考链接。

一般用来拾取物体:

fPoint CMy3D_SurfaceView::Get_3D_pos(CPoint Tpoint){    CMy3D_SurfaceDoc *pDoc=(CMy3D_SurfaceDoc*)GetDocument();    fPoint Rp;//vcg::Point3f Rp;//pcl::PointXYZ Rp;    GLint viewport[4];    GLfloat TransVect[3];    GLdouble modelview[16];    GLdouble projection[16];    GLfloat rotx,roty;    GLfloat winX,winY,winZ;    GLdouble posX,posY,posZ;    GLfloat scalex,scaley.scalez;    glPushMatrix();    glTranslatef(TransVect[0],TransVect[1],TransVect[2]);    if(pDoc->Init) roty=0.0f;    glRotatef(roty+20.0f,0.0f,1.0f,0.0f);    glScalef(scalx,scaly,scalz);    glGetIntegerv(GL_VIEWPORT,viewport);    glGetDoublev(GL_MODELVIEW_MATRIX,modelview);    glGetDoublev(GL_PROJECTION_MATRIX,projection);    glPopMatrix();    winX=(float)Tpoint.x;    winY=viewport[3]-(float)Tpoint.y;//转换为屏幕坐标    glReadPixels((int)winX,(int)winY,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&winZ);//获取鼠标屏幕坐标处像素的深度Z    gluUnProject(winX,winY,winZ,modelview,projection,viewport,&posX,&posY,&posZ);    Rp.x=posX;    Rp.y=posY;    Rp.z=posZ;    return Rp;}

另一个例子(参考:gluUnProject()函数得到的是什么坐标):

void C3DSLoader::GetCoordinate(float x,float y,float z,float& resultx,float& resulty,float& resultz,int intMode)  {   GLint viewport[4];     GLdouble modelview[16];     GLdouble projection[16];     GLfloat winX, winY, winZ;     GLdouble posX, posY, posZ;     GLdouble Point3f[3];       //   glMatrixMode(GL_MODELVIEW);   //glLoadIdentity();   //gluLookAt(0,0,0,  0,0,-10, 0,1,0);   //glLoadIdentity();   //gluLookAt(vertor3Eye.x,vertor3Eye.y,vertor3Eye.z,vertor3Center.x,       //vertor3Center.y,vertor3Center.z,vertor3Up.x,vertor3Up.y,vertor3Up.z);   glGetDoublev(GL_MODELVIEW_MATRIX, modelview);     glGetDoublev(GL_PROJECTION_MATRIX, projection);     glGetIntegerv(GL_VIEWPORT, viewport);     if(intMode==0)   {       winX = (float)x;       winY = (float)viewport[3] - (float)y;       glReadPixels(int(winX), int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);            gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);             resulty= (float)posY;   }   else if(intMode==1)   {       winX = x;       winY = y;       winZ=z;      // gluProject(winX, winY, winZ, modelview, projection, viewport, (GLdouble*)&resultx, (GLdouble*)&resulty, (GLdouble*)&resultz);        gluProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);        resulty=(float)viewport[3] - (float)posY;   }   resultx=(float)posX;   resultz=(float)posZ;   //Point3f[0] = posX;//*100;   //Point3f[1] = posY;//*100;    //Point3f[2] = posZ;//*100;   //QString strMessage=QString("X = %1,Y = %2,Z = %3s").arg(Point3f[0]).arg(Point3f[1]).arg(Point3f[2]);   //   //QMessageBox::warning(null,"",strMessage);  }  

这个例子有两种模式:第一种是鼠标选中屏幕中二维点来计算三维点坐标,第二种是直接利用三维点计算出三维点,再将y坐标换算到屏幕坐标中,得到实际三维坐标(参考解释:用OpenGL实现射线拣取对象)。

阅读全文
0 0
原创粉丝点击