APP下载

基于Open GL选择机制的模型变换组件的实现*

2011-08-17高明向陈定方杨艳芳

关键词:三维空间视点原点

高明向 陈定方 杨艳芳

(武汉理工大学理学院1) 武汉 430063) (武汉理工大学智能制造与控制研究所2) 武汉 430063)

在开发和用户交互的三维图形处理程序[1-2]时,常常需要使用鼠标控制模型的平移、旋转和缩放等模型变换操作.模型变换的具体形式是多种多样的[3],许多变换结果可以通过几个基本变换的连续作用而得到.如果将这些基本变换形式以菜单或者工具栏命令的形式进行定义[4],程序的菜单/工具栏将是非常臃肿的.如果以快捷键的形式进行定义,将会严重侵占应用程序的快捷键资源,导致定义程序使用的其它快捷键时出现困难,也不便于用户操作.将模型变换命令进行可视化表示,建立模型变换组件,并使用鼠标对这些命令进行选择与执行,既方便用户操作又可节约应用程序资源.本文在基于Open GL的建模环境中实现了这项技术.

1 Open GL选择机制

作为一种快速、高质量的3D图形软件接口,Open GL提供了一种进行交互式3D应用的选择操作.通过Open GL的选择机制[5],用户能够知道,在窗口中的某个特定区域中绘制的是哪个物体,用户用鼠标选取了哪个物体等.

在使用Open GL的选择机制时,首先将景物绘制到帧缓存中,然后进入选择模式并重新绘制景物.进入选择模式后,帧缓存的内容将不发生变化.在退出选择模式时,Open GL返回一个与视图体相交的图元系列.系列中的每个图元都会产生一个命中信息,并以图元名称及选中记录数组的形式返回.在选择模式中,当发送绘制图元命令时,要为图元命名.这样,在返回名称列表时,可以用它来确定用户选中的图元[6].

基于这种选择机制,可以先将基本的模型变换命令用一定的图元进行可视化表示,从而创建模型变换组件,然后使用鼠标对这些图元进行选取,选取了特定的图元相当于选择了相应的模型变换命令.下面介绍实现这种模型变换组件的关键技术.

2 平移组件

3D环境中平移变换的基本操作有3种:分别沿着x,y和z 3个坐标轴方向的平移.为增强平移变换操作的便利性,可再增加3种变换形式:分别在xoy,yoz和xoz平面上的平移操作.

2.1 平移变换命令的可视化表示

如图1所示,平移变换命令可使用三维直角坐标系统进行可视化表示:3条共点且相互垂直的有向线段构成该变换系统的坐标轴,分别表示沿着x,y和z方向的平移命令,任意两个轴所在的平面上各绘制一个4边形,分别表示在xoy,yoz和xoz平面上的平移命令.为描述方便,把这些轴或者四边形称为变换系统的部件.

图1 平移变换组件

2.2 平移变换命令的解析与执行

用鼠标选取这些部件的过程可分为两个阶段:当鼠标处于一个部件的上方时,称为命中(hit)部件,此时按下鼠标按键,部件才被选中(selected).在绘制变换系统时,给每个部件分别命名,当一个部件被选中时,由部件的名称即可解析出相应的平移变换命令,并通知应用程序,准备执行.当按下并移动鼠标时,开始执行这个命令,进行相应的平移变换操作.

2.3 鼠标控制物体的移动

用鼠标平移物体的过程中,一般要求物体总是处于鼠标下方,与鼠标同步移动.实现这种要求的基本方法是,移动鼠标过程中,实时计算鼠标点的窗口坐标对应的三维空间坐标,然后将物体的位置坐标用它代替即可.

下面的算法给出一种将鼠标点的窗口坐标映射到三维空间坐标的方法.这种方法以被选中物体的位置为参考,先求出该点的屏幕深度,然后以这个屏幕深度为参考,把鼠标的窗口坐标映射为三维空间坐标:

void Win Pos To World(int pos X,int pos Y,float obj-Position[],floatworld Pos[])

double win Coordinate[]= {0,0,0};

//将物体位置坐标映射为窗口坐标,获取该位置处对应的屏幕深度

World ToScreen(obj Position,win Coordinate);//将鼠标的窗口坐标映射为三维空间坐标

Screen To World(pos X,pos Y,win Coordinate[2],world Pos);

函数 Win Pos To World(*)有4个参数,pos X,pos Y是鼠标点的窗口坐标;obj Position[]是被选中物体的三维空间位置,当物体被选中时,使变换系统的原点移动到这个位置,因此物体的位置就是变换系统(局部坐标系)的原点对应的三维空间坐标(世界坐标系);worl d Pos[]是鼠标点对应的三维空间坐标.Worl d To Screen(*)方法封装了Open GL实用库中的gl u Project(*)函数,作用是把给定的三维空间坐标映射为窗口坐标,win Coor dinate[2]是该点对应的屏幕深度值.Screen To Worl d(*)方法封装了gl u Un Pr oject(*)函数,作用是把窗口坐标映射为由win Coordinate[2]指定的屏幕深度处三维空间坐标.

使用这种方法移动物体会存在的这样的问题:当选定了一种变换命令并开始移动物体时,变换系统的原点会突然跳到鼠标的下方,而且鼠标与变换系统原点间的屏幕距离越远,这种跳跃越明显.原因是,如图2所示,设在按下鼠标按键时,鼠标位于P0,这点与变换系统的原点O间总会存在一定的屏幕距离,相应于三维空间中,此二点总是存在一定的向量差OP0,而将物体位置坐标用鼠标坐标代替时,并没有将这个差值考虑进去.所以,确定物体平移后的位置时,只要将这个差值考虑进去,问题就解决了.

图2 消除跳跃的方法

3 缩放组件

缩放组件的实现方法与平移组件非常相似,实现的效果见图4b),不再赘述.

4 旋转组件

最基本的旋转变换有3种,即分别绕着x,y,z坐标轴的旋转变换.下文提及的旋转变换中,旋转角度均可用鼠标移动的屏幕距离与窗口宽度、高度的相对大小确定.因而,下文仅说明如何确定旋转轴.

4.1 基本旋转变换的可视化表示

绕着3个坐标轴的旋转操作命令,可以用xoy,yoz和xoz平面上的以变换系统原点为圆心的3个圆环(ring)进行可视化表示.当鼠标选中xoy面上的圆环时表示执行绕着z轴的旋转命令,而选中xoz面上的圆环时表示执行绕着y轴的旋转命令等等.

为了便于判断哪个部件被命中或者选中,只要对处于命中/选中状态的圆环使用不同的颜色绘制即可.为了看上去更具有立体感,这些圆环需要由两部分构成:一是靠近视点的部分,用实线绘制,二是远离视点的部分,则用虚线绘制.当变换系统处于场景中的不同位置或者视点位置发生变化时,这2个部分是不断变化的,因而要动态更新这两部分的数据.更新方法是:将构成圆环的每个点相对于圆心的位置矢量与由物体指向视点的矢量进行点乘运算,结果为正值的构成靠近视点的部分,反之则构成远离视点的部分.

4.2 绕空间任意轴旋转的可视化表示

绕空间任意轴旋转亦是一种常用的变换方式.这种变换命令可直接使用以变换系统的原点为圆心的填充圆(filled circle)进行可视化表示.这个圆与基本变换中使用的圆环半径相同.当鼠标位于填充圆内,且没有命中4.1所述的部件时,通过改变填充圆的透明度,通知用户即将执行绕任意轴旋转的命令,按下并移动鼠标时就可通知程序执行该命令.

至于旋转角度和旋转轴的求解,比较典型的方法是Ne He Open GL编程指南中提供的旋转球法[7].本文提出了一种更为简单的求解旋转轴的方法.

如图3所示,设O点是旋转变换系统(局部坐标系统)的原点,位于物体的位置坐标(世界坐标)处,^n是填充圆面的单位法线向量,其方向由O点指向视点(根据§4.4的方法,总可以保证圆面与视点正对).设当鼠标位于P0点时按下左键并移动,某时刻移动到了P1点.则此过程的旋转轴用向量r表示,可由下式计算:

式中:OP0,OP1分别为从O 点到P0,P1点的向量.O点的世界坐标是已知的,等于欲进行旋转变换物体位置的世界坐标.^n由视点和O点的世界坐标求出.P0点和P1点的世界坐标可使用2.3的方法由鼠标窗口坐标映射到世界坐标得到.

图3 求解任意旋转轴

4.3 以视线为转轴的旋转变换

三维计算机图形学中,把视点与物体(位置)的连线称为视线.绕着视线的旋转变换也是较为常用的一种变换形式.这种变换的可视化表示方法较为简单,可直接使用以变换系统的原点为圆心的圆环表示,但半径必须比§4.2填充圆的半径大.这种变换的旋转轴即为视点的三维空间坐标(世界坐标)与物体的空间坐标(变换系统原点对应的世界坐标)的差值构成的空间向量.

4.4 调整变换组件的空间方位

对于4.2,4.3所使用的填充圆,必须随着视点或者物体位置的不同对它们的空间方位进行调整,以使其始终正对视点,以免出现有时看起来呈正圆形,有时呈椭圆形,有时又呈一条线的情况.调整方法是:首先,计算视点与物体(位置)的连线与xoz面的夹角angle XZ以及该连线在xoz面的投影与z轴夹角angle Z.然后,使这些圆面绕着Y轴旋转angle XZ.最后,使它们绕着X轴旋转-angle Z.

5 结束语

本文在Visual C++编程环境下,将这些变换组件封装在一起,构建CTransfor m类,这就使得这些变换组件能够很容易地应用到图形或应用系统中.只要在程序文件中包含该类的头文件,并定义一个该类的实例(指针变量,或者声明一个CTransfor m类型的普通变量),然后利用类所提供的用户接口,执行必要的命令即可.

CTransfor m类提供了3种用户接口.一种是变换组件的属性接口,用于设置/获取变换组件的位置、缩放量、旋转轴、当前的变换类型及状态等.另一种是组件的绘制接口,用根据当前变换的类型及状态,显示不同的变换组件.三种变换类型间的切换可以通过菜单或者工具栏实现,仅需要增加三个程序菜单项或工具栏按钮.第三种是用于获取3D场景视点信息的接口,该接口主要用于旋转变换,能够根据视点的位置自动调整旋转组件的在场景中的姿态(参阅4.4).

图4是三类模型变换组件的实现效果图.当选中一个物体时,根据程序的当前变换要求显示相应的变换组件,并将该组件定位到被选中的物体上,根据模型变换的实际需要,通过鼠标选择相应的变换部件,按下并移动鼠标时,相应的变换命令得以执行.这项技术已经用于正在开发的虚拟物理环境的软件平台及“基于磁各向异性的Galfenol本征非线性模型及其应用研究(20090143110005)”的仿真软件开发试验中,使得应用程序的界面得到很大程度的简化,同时也使得对场景中模型的控制变得简单、方便,效果好.

图4 模型变换组件效果图

[1]刘鹏程,艾廷华,胡晋山.基于Open GL技术的隧道仿真系统的研究与开发[J].计算机工程,2008,34(6):240-242.

[2]朱志峰,余德义.利用OPENGL技术开发3D飞行仿真应用程序[J].计算机仿真,2005,21(3):194-196.

[3]王胜全,范燮昌,谈士力.Open GL中的坐标变换分析[J].机械与电子,2004(2):65-67.

[4]王亚平,余 柯,罗 堃.在Open GL中一种新的拾取方法及其应用[J].工程图学学报,2003(2):60-64.

[5]Woo M,Neider J,Davis T.OPENGL编程权威指南[M].北京:中国电力出版社,2001.

[6]杨 冬,王 琰,祁 燕.虚拟装配环境中基于分层结构三维实体的拾取[J].沈阳理工大学学报,2007,26(1):17-20.

[7]Terence J.Open GL Tutorials:Lesson 48[CP/OL].[2011-02-26].htt p://nehe.gamedev.net/data/lessons/lesson.asp?lesson=48

猜你喜欢

三维空间视点原点
前庭刺激对虚拟环境三维空间定向的影响及与空间能力的相关关系
Book Pilot 飞行选书师,让书重新回到原点
重返历史“原点”的旅程
红领巾环保走进三维空间——“6·5世界环境日”活动方案
三维空间的二维图形
在原点震荡的扰动Schrödinger-Poisson系统的无穷多个解
基于虚拟三维空间数字技术的房屋土地管理系统
视点
关于原点对称的不规则Gabor框架的构造
让你每天一元钱,物超所值——《今日视点—2014精萃》序