在OpenGL的使用中,用其显示3D点云是非常常见的操作,而进一步让用户可以选择点云以查看其信息可以使得开发变得更加简单,本篇文章我们将讨论怎么实现这一功能。
要用鼠标圈选点云,要解决的问题就是得到鼠标圈选的范围内有哪些点,也就是要知道OpenGL的顶点到屏幕坐标之间的映射关系。这一映射关系我们在摄像机这篇文章已经得到了,它就是:
QMatrix4x4 mvp;
这个对象,我们在顶点着色器中用它和顶点坐标相乘直接得到了顶点的3D坐标:
gl_Position = MVP * vec4(posVertex, 1.0f);
因此如果我们在鼠标圈选之后遍历所有的点,然后再计算一遍这个投影关系,就可以知道哪些点是在圈选的范围内的点,代码和解释如下:
for (int i = 0; i < 230400; i++)
{
QVector4D screen = mvp.map(QVector4D(QVector3D(vertices[i * 6 + 0], vertices[i * 6 + 1], vertices[i * 6 + 2]), 1.0f));
//QVector4D是四维的齐次坐标,需要将前三维的值除以第四个维度的值,以转换到笛卡尔坐标系下
if (screen.w() != 0.0f)
{
screen.setX(screen.x() / screen.w());
screen.setY(screen.y() / screen.w());
screen.setZ(screen.z() / screen.w());
}
//这里我们直接选择了x,y轴-0.5~0.5的点,也就是OpenGL显示框内中心长宽为显示框一半的矩形圈内的点,如果想实现鼠标圈选,则再做一次鼠标圈选范围到OpenGL显示框的映射关系就可以了。需要注意的是OpenGL显示宽的长和宽都是用-1~1进行表示的。
if (screen.x() > -0.5 && screen.x() < 0.5 && screen.y() > -0.5 && screen.y() < 0.5)
{
}
}
参考文章
https://blog.csdn.net/weixin_42108411/article/details/105392471