很久很久以前,那还是大一下,苦逼的学习了openGL,也算踏进了图形学领域吧,如今在中科院的工作也和图形学的相关,一切的偶然加上本人也喜欢图形学的缘故,在这条路走的还那么算回事,基本的知识差不多还是掌握了,也对openGL比较熟悉。可是以后的工作却和图形学一点都不搭边,本来也确实想放弃在这个领域浪费时间了,可是不知道为何又舍不得,所以,心里也暗自说,不管怎样,还是坚持一点点的学习图形学吧,正如乔布斯所说,你学习的任何东西,抑或改变你的一身,原话貌似不是这样啦。结合项目要求,研究了三维点的拾取,其实老早就想写一篇类似的文章了,但是比较偷懒,没有做,也不想发一篇很水的文章。
接吻
在充满三维物体的游戏中,如何能够准确的拾取你指定的物体,对游戏体验很重要,所以今天就来介绍一下如何在三维场景中拾取三维点。并附上了代码。也来明白3维点,如果映射到二维屏幕上面的,本问特别适合初学者。
前戏
我们知道,所谓的3D,其实还是显示在二维屏幕上,只不过图像的呈现非常具有真实感。那么3维的点如何转换到屏幕上的二维坐标呢?
这里已openGL的流程图为例,其他的图形库如DirectX也差不多。
先明白几个图形学中的几个概念,所谓的世界坐标系就是全局坐标系,物体的点坐标就是依据这个坐标系给定的。点,物体的旋转,缩放以及平移都是在这个坐标系中进行的;观察坐标系也称摄像机坐标系,想想一下我们照相的时候,其实是以摄像机为原点建立了坐标系,然后将所拍的景色投影到胶片上,所以这个坐标系决定了点和物体如何映射到观察平面,我们一般有二种投影方式,正投影和透视投影。观察平面可以想象成以前老式相机的胶片,也可以想象成你的屏幕。
有了之前的知识,我们就能明白openGL中一些高级的东西。在openGL中,openGL本身维护了二套矩阵,模型视图矩阵和投影矩阵。我们本身看不到,诸如glTranslate, glRotatef,gluLookAt和glLoadIdentity都是在操作这二套矩阵,至于openGL当前状态下的是什么矩阵,由glMatrixMode决定,相应的参数有GL_MODELVIEW和GL_PROJECTION。
模型视图矩阵M0作用是,将P0点进过一些的动作转换到观察坐标系,这些动作包含旋转,缩放和平移。转换后的P0坐标是以摄像机为原点建立起来的坐标P1。
P1 = M0 * P0
投影矩阵M1作用是,将P1坐标转换到屏幕坐标P2,注意这里的屏幕坐标已经正规化,也就是说,P2的坐标范围已经在【-1,1】里了。至于为什么要正规化,我也不知道,不过貌似很多数学知识都要正规化,可想而知,0,1这二个数字的神奇,哈哈,乱说的,意淫一下。
P2 = M1 * P1
给一个二维的例子吧
在黑色坐标系中的P0,如果在x,y轴平移的话,就会达到P1,记住这里P1还是相对于黑色坐标系,在转换到红色坐标系中后,此刻的P1才有红色坐标系中的坐标,以上的所有动作就相当于模型视图矩阵的作用,即P1 = M0 * P0.
接下来在观察坐标系中的坐标P1,按照下图进行投影(以透视投影为例)
openGL中的观察平面就是上图中的近平面。所以在视野范围的内的点都将会投影到这个近平面上。视野范围就在近平面和远平面之间,其余空间的物体会被裁剪。
高潮
在计算机中,做的工作远比以上介绍的多,诸如裁剪,正规化和光栅化都没有提及,不过单独从编程的角度来看,以上的知识足以。
- void display(void)
- {
- M3DMatrix44f mat_proj, mat_modelview;
-
- int width = glutGet( GLUT_WINDOW_WIDTH ), height = glutGet( GLUT_WINDOW_HEIGHT );
- glViewport (0, 0, (GLsizei) width, (GLsizei) height);
-
- glGetIntegerv(GL_VIEWPORT, viewport);
-
- glClear (GL_COLOR_BUFFER_BIT);
-
- glPushAttrib(GL_POLYGON_BIT);
- glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
-
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity ();
- gluPerspective(65.0, (GLfloat) width/(GLfloat) height, 1.0, 300);
-
-
- glGetFloatv(GL_PROJECTION_MATRIX, mat_proj);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- gluLookAt(0, 0, 70, 0, 0, 0, 0, 1, 0);
- glColor4f(0.1, 0.4, 0.6, 0.7);
- glPushMatrix();
-
-
- glGetFloatv(GL_MODELVIEW_MATRIX, mat_modelview);
-
-
-
- glPopMatrix();
- glPopAttrib();
-
-
- selection.set_config( corners, 8, left_bottom, right_top, mat_modelview, mat_proj, viewport);
-
-
-
-
-
- if( bool_select_area ){
-
- selection.draw_area();
- selection.highlight_selected_pts();
-
- }
- }
注意看上面的工作主要是获取当前openGL状态,即得到模型视图矩阵,投影矩阵和视口参数。
既然我们知道得到正规化的坐标点是如下方式:
P2 = M1 * M0 * P0,然后再通过视口参数转换成像素坐标,在判断P2点是否落在所选的区域中,即可判断是否选中三维点。
具体的代码请看后面的连接中 math3d.cpp中的函数m3dProjectXY。
睡觉
具体的代码全部放在我的github上了,具体的点击一下连接
https://github.com/baiyang/opengl
在上几个图,
-----------------打造高质量的文章 更多关注 把酒泯恩仇---------------
为了打造高质量的文章,请 推荐 一下吧。。。。谢谢了,请关注我后续的文章,会更精彩哦
请关注sina微博:http://weibo.com/baiyang26
把酒泯恩仇官方博客:http://www.ibaiyang.org 【推荐用google reader订阅】
把酒泯恩仇官方豆瓣:http://www.douban.com/people/baiyang26/
如果您想转载本博客,请注明出处
如果您对本文有意见或者建议,欢迎留言
分享到:
相关推荐
本文介绍一种改进的三维拾取方法,该方法基于OpenGL这一广泛使用的图形库,能够有效地处理三维地形图上的点拾取,并返回点的精确三维坐标。 #### 三维拾取方法概述 三维拾取是指在三维图形场景中选取特定位置的过程...
OpenGL场景中的三维点拾取是一项重要的交互技术,它允许用户通过鼠标点击屏幕上的特定位置来选择场景中的三维对象或点。这项技术广泛应用于各种3D应用程序,如CAD软件、游戏和虚拟现实环境。以下是实现这一功能涉及...
与传统的OpenGL拾取方法相比,射线拾取方法具有更高的准确性和响应速度,尤其适用于复杂场景下的交互式三维应用。然而,每种方法都有其适用场景和局限性,选择合适的方法需考虑具体的应用需求和技术限制。 #### ...
使用OpenGL实现三维坐标的鼠标拣选_-_Y___Y的专栏_-_CSDN博客
三维_实现openGL拾取功能+能够精确定位三维点_优质项目实战
OpenGL拾取操作是计算机图形学中的一个重要概念,它允许用户在3D场景中选择或“拾取”特定的对象。在游戏、虚拟现实应用或者任何交互式3D界面中,拾取功能都至关重要,因为它提供了与场景中元素进行交互的方式。在...
在这个项目中,我们将深入探讨如何利用OpenGL实现交互式的场景控制,包括鼠标拾取对象以及使用键盘的功能键来操纵模型的旋转。 首先,让我们了解OpenGL的基础。OpenGL是一个跨语言、跨平台的应用程序编程接口(API...
OpenGL太阳系拾取例子是一个基于OpenGL图形库的项目,展示了如何在三维空间中实现对太阳系模型中的对象进行选择或“拾取”。OpenGL是一个跨语言、跨平台的编程接口,用于渲染2D、3D矢量图形。在这个例子中,我们将...
在屏幕上,每个对象都有一个对应的坐标,拾取就是通过鼠标点击的屏幕坐标反向投影到三维空间,找到与该点最接近的对象。通常,这个过程包括两个主要步骤:一是将屏幕坐标转换为视口坐标,然后转换为归一化设备坐标...
基于OpenGL的三维窗口裁剪_拾取算法研究
在“OpenGL三维地形建模”中,主要涉及以下几个核心知识点: 1. **DEM数据读入**:DEM(Digital Elevation Model)是数字高程模型,通常用于表示地理表面的海拔信息。在建模中,通过读取DEM数据可以获取地形的高度...
该算法搜索所有与拾取点XY坐标匹配的三维点,并找出其中Z坐标最小的点,即离观察者最近的点。这样,即使在没有直接的Z坐标信息的情况下,也能准确找到对应的三维点。 #### 技术优势 - **精度高**:针刺取点方法能...
利用OpenGL实现了三维点云的显示,添加了鼠标控制事件,可以用鼠标对三维点云模型进行移动、缩放等功能。很不错的源代码,本代码运行环境是VS2010,需要添加OpenGL的配置。很不错的源代码分享给大家。
OPENGL三维场景搭建、漫游、交互。包括凹凸地形,键盘交互、鼠标交互、树木,火焰等
三维迷宫的创建及走迷宫过程中的交互功能的实现。掌握可交互的OpenGL应用程序的开发设计的方法,掌握系统处理鼠标和键盘事件的编程方法,掌握OpenGL应用程序的拾取机制,掌握并学会利用OpenGL开发场景漫游程序的编程...
在本研究中,通过VTK实现的三维拾取技术,用户可以指定屏幕上的一个点,该工具会计算出这个点对应的三维空间坐标,从而实现对三维模型的精确测量。这一过程对于提高医疗诊断的准确性和手术计划的有效性至关重要。 #...
基于opengl的鼠标交互拾取,从二维转到三维坐标 基于opengl的鼠标交互拾取,从二维转到三维坐标 基于opengl的鼠标交互拾取,从二维转到三维坐标 基于opengl的鼠标交互拾取,从二维转到三维坐标
可以完美实现点云数据的读取和显示,通过MFC和OpenGL实现。还要详细点?我想我表达的已经够清楚了吧
重新修改了一下