LucKy_one

Always aiming higher


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 搜索

在iOS平台上的3D地图框架WhirlyGlobe上实现一个指南针

发表于 2014-05-12 更新于 2014-08-03
需要在WhirlyGlobe的3D地图上来实现一个指南针的功能,初步考虑需要以下几个步骤:监测地图位置,改变的时候触发事件——旋转指南针的图片到对应的角度。

需要在WhirlyGlobe的3D地图上来实现一个指南针的功能,初步考虑需要以下几个步骤:监测地图位置,改变的时候触发事件——旋转指南针的图片到对应的角度。
找到地图的缩放,拖动,旋转的方法后,发现所有涉及角度变换的地方都是改变了Eigen::Quaternionf rotQuat的值。下面介绍下Quaternion:

Quaternion 的定义
四元数一般定义如下:

q=w+xi+yj+zk

其中 w,x,y,z是实数。同时有:

i*i=-1 
j*j=-1    
k*k=-1

四元数也可以表示为:

q=[w,v]

其中v=(x,y,z)是矢量,w是标量,虽然v是矢量,但不能简单的理解为3D空间的矢量,它是4维空间中的的矢量,也是非常不容易想像的。

通俗的讲,一个四元数(Quaternion)描述了一个旋转轴和一个旋转角度。这个旋转轴和这个角度可以通过 Quaternion::ToAngleAxis转换得到。当然也可以随意指定一个角度一个旋转轴来构造一个Quaternion。这个角度是相对于单位四元数而言的,也可以说是相对于物体的初始方向而言的。

当用一个四元数乘以一个向量时,实际上就是让该向量围绕着这个四元数所描述的旋转轴,转动这个四元数所描述的角度而得到的向量。
(摘自http://www.linuxgraphics.cn/opengl/opengl_quaternion.html)

简单来说Quaternion是用来表示旋转的,地图所存储的Quaternion变量表示了从初始位置到当前位置的旋转变量,这样我们可以通过计算北极点(0,0,1)经过旋转之后位置:

Eigen::Vector3f northPole = (rot * Eigen::Vector3f(0,0,1)).normalized();

P.S. Eigen是一个非常著名的C++数学库;
然后就可以算出所需要的角度了:

float angle = atan2(northPole.x(), northPole.y());//atan2为math.h下的C函数

UIVIEW有一个transform属性来负责控制变型的,我们可以创建一个旋转变换来旋转图片,每次旋转当前的角度和上次的差值。

CGFloat rotation = 0.0 -(lastCompassAngle-angle); //lastCompassAngle存储了上次的角度
CGAffineTransform currentTransform = compass.transform;CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
[compass setTransform:newTransform];lastCompassAngle = angle;

OK大功告成!!
参考文章:
http://www.cppblog.com/heath/archive/2009/12/13/103127.html
http://www.linuxgraphics.cn/opengl/opengl_quaternion.html

# iOS # WhirlyGlobe # Map
hello hexo! 搭建hexo中参考的资料
绑定自己的域名以及将DNS更换为DNSPOD

Liu Tianhe

喜欢金融,喜欢科技
31 日志
29 标签
RSS
GitHub E-Mail
© 2014 – 2022 Liu Tianhe
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Mist v7.3.0