APP下载

基于Android的校园三维导览系统的设计与实现*

2015-09-09许林然

关键词:触点坐标系建模

许林然

(哈尔滨师范大学)

0 引言

随着移动通信技术、计算机信息技术等新技术的高速发展,平板电脑、智能手机等移动设备层出不穷,智能手机等移动设备已经成为人们日常生活的必需工具,快捷直观的地图查询越来越受到人们的重视[1].Android是 Google公司于2007年11月5日发布的基于Linux内核的移动平台,是一个真正的开源移动开发平台[2].

OpenGL是由SGI公司开发的一套3D图形软件接口标准.OpenGL的体系结构简单、使用方便,并且具有与操作平台无关的优良特性,这使得其迅速成为一种3D图形接口的工业标准,并陆续在各种平台上得以实现.Android平台下支持的高性能的3D图像编程接口是通过OpenGL ES来实现的.OpenGL ES是专门根据手持及移动设备的特点对OpenGL标准进行裁剪定制产生的[3].OpenGL ES是 OpenGL 三维图形 API的子集.

为了加快校园的数字化进程以及方便外界和广大学生对校园的地理环境进行了解,开发一个基于Android的校园的三维导览系统具有重要意义.该系统提供的移动端三维地图的展示相对传统的二维地图展示,具有方便快捷、直观形象的特点.

1 系统设计

在OpenGL ES当中只支持点、线和三角形面这三种基本图元的绘制,三角形面是最基础的平面类型,同时也是OpenGL ES中唯一的平面类型,利用若干个三角形面可以构成复杂的三维物体.由于在OpenGL ES中并没有提供构建复杂三维模型的高级命令,所以使用OpenGL ES程序来建立三维模型时过程比较繁琐、直观性较差、编程量较大.此外如果建模时需要对模型的数据进行修改,那么修改的效率也是很低的.

运用三维建模软件进行建模不需要编程便可以直观地构造外观精细的三维模型,大大提高了软件的开发效率.由于最终的目的是能够在Android平台上对三维场景进行控制和交互,于是,需要把三维建模软件中已建立好的模型的数据导入到 Android平台上加以利用,然后在OpenGL ES程序中对模型数据进行解析[4],运用光照、纹理和模型变换等函数,就可以把三维场景在Android平台上渲染出来.

Android中的用户界面视图的显示与交互是通过Activity组件加载用户界面View来实现的,同样对于三维场景的显示也需要借助于View.Android专门定义了 GLSurfaceView类,该类是View类的子类,它为OpenGL ES提供了一个专用的渲染线程.GLSurfaceView类是 Android和OpenGL ES联系的纽带.

系统的设计思路如图1所示.

图1 系统设计思路图

2 系统关键技术实现

2.1 三维场景的建模与OBJ格式文件的解析

三维场景建模的首要任务就是收集建模的数据[1],系统所需的建模数据主要有校园的二维平面图、校园的地形图、实测图片、三维观测数据等.其中校园的二维平面图是指校园的规划设计CAD图,它是三维场景建模的主要数据源;校园的地形是指校园的遥感卫星图像,它可以作为三维场景的地形底图;实测图片是指建筑物、道路、草地等的表面纹理图片;三维观测数据指的是建筑物的高程数据.系统在进行三维场景建模时所采用的三维建模软件是3DMAX,该软件具有模型表达精细、建模工具丰富等特点.由于校园规划设计CAD图是三维建模的主要数据源,使用3DMAX进行三维建模可以实现与建模数据源的无缝融合[5].

在3DMAX中完成校园三维场景的建模后,由于Android平台上的OpenGL ES无法直接读取模型文件,所以就需要把模型文件保存为OpenGL ES可以读取的文件,3DMAX中提供了几种可以被OpenGL ES读取的输出文件格式,在此选择了比较通用的OBJ文件格式.OBJ文件是以纯文本的形式记录三维模型的顶点、法向量、纹理坐标和材质使用信息.在JAVA程序中结合正则表达式对OBJ文件进行解析,把解析过程中所获取的顶点坐标、纹理坐标、法向量坐标等模型信息存放到数组ArrayList当中,以便OpenGL ES进行模型的绘制与渲染时使用.其代码如下所示(以获取顶点坐标为例):

String[]tempsa=temps.split("[]+");//用空格分割行中的各个组成部分

if(tempsa[0].trim().equals("v"))

{//此行为顶点坐标

//若为顶点坐标行则提取出此顶点的XYZ坐标添加到原始顶点坐标列表中

坐标

坐标

坐标

2.2 三维地图的平移功能的实现

三维场景的平移功能的实现需要用到平移变换函数 glTranslatef(floatx,floaty,floatz),在Renderer类中定义两个成员变量xoffest和yoffest,分别表示沿x轴和y轴的位移,并对其进行初始化,然后传给 glTranslatef函数.在 GLSurfaceView的屏幕触摸事件下,如果发生ACTION_MOVE操作,则根据屏幕拖动的起点和终点计算X轴方向的位移和Y轴方向的位移,分别赋给xoffest和yoffest,然后调用GLSurfaceView的重绘方法requestRender()屏幕上即呈现出三维场景平移后的效果.

2.3 三维地图的放大、缩小功能的实现

在Renderer类中定义两个成员变量xScale和yScale,分别表示在X轴和Y轴上的缩放因子,并对其进行初始化,在onDrawFrame()函数中调用 glScale(xScale,yScale,1.0f).当发生放大或缩小操作时,根据预先设定的放大或缩小比例,修改xScale和yScale的值,然后调用GLSurfaceView的重绘方法requestRender()屏幕上即呈现出三维场景放大或缩小后的结果.能够产生放大和缩小的操作有以下两种.

第一种是直接点击屏幕上的放大、缩小按钮.ImageButton按钮是Android SDK提供的基本的UI组件,为了能使ImageButton按钮能够“悬浮”在GLSurfaceView上,把ImageButton按钮布局在另一个XML文件中,并在该XML文件中设置OnClick属性,以便响应在主程序中定义的放大、缩小方法,然后通过 LayoutInflater把这个XML文件和程序默认的XML合并在一起.其代码如下所示:

//设置主程序的界面布局属性

LinearLayout GLSurfaceViewLinearLayout=new Line arLayout(this);

GLSurfaceViewLinearLayout.setLayoutParams(

new LayoutParams(LayoutParams.FILL_PARENT,

LayoutParams.FILL_PARENT));GLSurfaceViewLinearLayout. setOrientation(LinearLayout.VERTICAL);

//获取XML布局的文件

LayoutInflaterinflater = (LayoutInflater)this.getSystemService

(Context.LAYOUT_INFLATER_SERVICE);//把获取的XML文件实例化

LinearLayout imagebuttonLinearLayout =(LinearLayout)

inflater.inflate(R.layout.zoom,GLSurface-ViewLinearLayout,false);

//合并

GLSurfaceViewLinearLayout.addView(imagebuttonLinearLayout);

//添加合并后的布局文件

addContentView(GLSurfaceViewLinearLayout,new LayoutParams

(LayoutParams.MATCH_PARENT,Layout-Params.MATCH_PARENT));

放大、缩小按钮“悬浮”在GLSurfaceView上的运行效果如图2所示.

第二种是触摸屏幕进行放大和缩小.运用到了Android的多点触控技术,当用两个手指触摸屏幕时,首先记录一下最先触摸到屏幕的手指的触点坐标,定义一个变量oldDist,用来表示两个触点的相对位置变化前的触点距离,初始化为0,当第二个手指按下的瞬间,计算两个触点间的距离并赋给oldDist.另外再定义一个变量newD-ist,用来记录两个触点的相对位置变化后的触点距离,当newDist>oldDist时,执行放大操作,当newDist<oldDist时,执行缩小操作,其代码实现如下所示:

float newDi

st=Distance(e);

if(newDist> oldDist&&mRenderer.xScale <=5.0f)//放大,最大放大5 倍

{ mRenderer.xScale + = 0.1f;

图2 放大、缩小按钮的“悬浮”

mRenderer.yScale+=0.1f;oldDist=newDist;

requestRender();//重绘画面 }if(newDist< oldDist&&mRenderer.xScale >=0.5f)//缩小,最小缩小 0.5 倍

{mRenderer.xScale-=0.1f;mRenderer.yScale-=0.1f;oldDist=newDist;

requestRender();//重绘画面 }

2.4 简单的信息浏查询功能的实现

简单的信息浏览功能就是当用户点击三维场景中的某一地物时,会呈现出一个介绍该地物相关信息的界面.通过用户点击屏幕所获取的坐标是在屏幕坐标系中的坐标,但是三维场景中地物的坐标是三维坐标,要想使屏幕上的触点位置坐标与地物的三维坐标相对应,就需要在Open-GL ES的世界坐标系和屏幕坐标系之间进行一个坐标系间的转换,本系统选择是把OpenGL ES的世界坐标系转换为了屏幕坐标系(根据投影知识,Z轴坐标经转换后是没有实际意义的),转换函数如下所示:

矩阵

gl.glGetIntegerv(GL11.GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES,

bits,0);//获取模型变换的矩阵信息

for(int i=0;i < bits.length;i++){

model[i]= Float.intBitsToFloat(bits[i]);

}gl.glGetIntegerv(GL11.GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES,bits,0);//获取投影变换的矩阵信息

for(int i=0;i < bits.length;i++){

project[i]=Float.intBitsToFloat(bits[i]);

}GLU.gluProject(objX,objY,objZ,model,0,project,0,

new int[]{0,0,getWidth(),getHeight()},0,win,0);//该函数得到的二维屏幕坐标的原点是在屏幕左下角,Y轴方向与屏幕左边界平行向上.

win[1]=getHeight()- win[1];//使Y轴坐标转换为坐标原点在屏幕左上角,Y轴方向与屏幕左边界平行向向下的坐标系中的Y轴坐标return win;}

根据地物的边界来确定两个边界坐标,经过坐标转换,可以确定一个屏幕点击区域,只要用户点击位置在这个区域内,就可以浏览该地物相应的信息.这样就避免了必须要点击某个准确的点才能浏览信息而给用户带来的不便.信息的显示是通过运用Intent组件来调用Activity的方式来实现的.被调用的Avtivity的有关信息需要在AndroidManifest.xml文件中设置.该功能的运行效果如图3所示.以查询校区某一教学楼为例,其代码为:

Intent intent=new Intent(getApplicationContext(),ActivityLiOne.class);StartActivity(intent);

3 结束语

在Android移动平台上实现三维地图可视化的方法,运用Android和OpenGL ES三维开发技术实现了三维地图的平移、放大、缩小和简单的信息查询功能.该系统能够形象直观地展现真实的校园景观,方便了用户对学校的了解.基于Android的校园三维导览系统可以为数字化校园提供一个移动端的三维平台,为数字化校园的进一步发展奠定了基础.

图3 简单信息查询图

[1]王亚美,鲁田.基于OpenGL ES的二三维地图可视化客户端设计与实现[J].计算机应用与软件,2013,30(9):77-80.

[2]郝玉龙.Android程序设计基础[M].北京:清华大学出版社;北京交通大学出版社,2011.10.

[3]欧阳零.Android核心技术与实例详解:第2版[M].北京:电子工业出版社,2013.

[4]黄小凤,宋瑾钰,俞成海.基于OpenGL ES的移动平台的三维模型绘制[J].工业控制计算机,2013,26(1):60-62.

[5]吴庆双,王楠.安徽师范大学三维虚拟校园系统建设研究[J].重庆文理学院学报,2012,31(1):62–67.

猜你喜欢

触点坐标系建模
中国人民大学新闻学院教授 林升栋:将消费者触点思维融入广告媒体计划
独立坐标系椭球变换与坐标换算
联想等效,拓展建模——以“带电小球在等效场中做圆周运动”为例
航空电转换器的损伤原因分析及修理
接触器辅助触点接触电阻产生原因分析
基于PSS/E的风电场建模与动态分析
不对称半桥变换器的建模与仿真
解密坐标系中的平移变换
坐标系背后的故事
可靠性技术在继电器控制中的应用探讨