Android中SensorManager.getRotationMatrix函数原理解释
SensorManager是Android中的一个类,其有一个函数getRotationMatrix
,可以计算出旋转矩阵,进而通过getOrientation
求得设备的方向(航向角、俯仰角、横滚角)。函数getRotationMatrix的源码如下所示,源码中虽然对该函数整体进行了解释,但是对代码中各个参数的计算没有说明,如为什么加速度的数值要和磁力计的数值做差乘。在网上各种搜索后,找到一段老外对这个问题的英文解释,很好的回答了上述问题。大意翻译(包括自己的理解)如下:加速度数值和磁力计数值均是向量,手机水平放置时,加速度读数实际上就是重力向量,方向是竖直朝下的;磁力计表示本地的磁场,不考虑环境影响及磁偏角的话,认为磁场方向是水平南北朝向的。因此,代码中首先对加速度和磁力计数据做了一个差乘,得出一个水平东西方向的向量(差乘的定义)。经过这个运算,本来只有一个平面的向量,变成了三个三维立体平面的向量,从而可以用来计算设备的方向。源码中后面又做了一次差乘,是用计算出的水平东西方向的向量和重力向量做的差乘,这次运算重新得出一个水平南北方向的向量,最后旋转矩阵中用这三个向量(两个计算出的水平向量、一个重力向量)构成。
1、SensorManager.getRotationMatrix
public static boolean getRotationMatrix(float[] R, float[] I,
float[] gravity, float[] geomagnetic) {
// TODO: move this to native code for efficiency
float Ax = gravity[0];
float Ay = gravity[1];
float Az = gravity[2];
final float Ex = geomagnetic[0];
final float Ey = geomagnetic[1];
final float Ez = geomagnetic[2];
float Hx = Ey*Az - Ez*Ay;
float Hy = Ez*Ax - Ex*Az;
float Hz = Ex*Ay - Ey*Ax;
final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz);
if (normH < 0.1f) {
// device is close to free fall (or in space?), or close to
// magnetic north pole. Typical values are > 100.
return false;
}
final float invH = 1.0f / normH;
Hx *= invH;
Hy *= invH;
Hz *= invH;
final float invA = 1.0f / (float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az);
Ax *= invA;
Ay *= invA;
Az *= invA;
final float Mx = Ay*Hz - Az*Hy;
final float My = Az*Hx - Ax*Hz;
final float Mz = Ax*Hy - Ay*Hx;
if (R != null) {
if (R.length == 9) {
R[0] = Hx; R[1] = Hy; R[2] = Hz;
R[3] = Mx; R[4] = My; R[5] = Mz;
R[6] = Ax; R[7] = Ay; R[8] = Az;
} else if (R.length == 16) {
R[0] = Hx; R[1] = Hy; R[2] = Hz; R[3] = 0;
R[4] = Mx; R[5] = My; R[6] = Mz; R[7] = 0;
R[8] = Ax; R[9] = Ay; R[10] = Az; R[11] = 0;
R[12] = 0; R[13] = 0; R[14] = 0; R[15] = 1;
}
}
if (I != null) {
// compute the inclination matrix by projecting the geomagnetic
// vector onto the Z (gravity) and X (horizontal component
// of geomagnetic vector) axes.
final float invE = 1.0f / (float)Math.sqrt(Ex*Ex + Ey*Ey + Ez*Ez);
final float c = (Ex*Mx + Ey*My + Ez*Mz) * invE;
final float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE;
if (I.length == 9) {
I[0] = 1; I[1] = 0; I[2] = 0;
I[3] = 0; I[4] = c; I[5] = s;
I[6] = 0; I[7] =-s; I[8] = c;
} else if (I.length == 16) {
I[0] = 1; I[1] = 0; I[2] = 0;
I[4] = 0; I[5] = c; I[6] = s;
I[8] = 0; I[9] =-s; I[10]= c;
I[3] = I[7] = I[11] = I[12] = I[13] = I[14] = 0;
I[15] = 1;
}
}
return true;
}
2、英文原文解释
If I understand your problem correctly you want your phone to know its 3D orientation. You need at least two vectors to do that. The xyz accelerometer produces a gravity vector that goes straight down. An xyz magnetometer can provide a second vector that is horizontally towards magnetic north and vertically downward in the northen hemisphere. The cross-product of these two vectors will be horizontal the magnetic east-west directions and the cross-product between the east-west vector and the gravity vector will be horizontal in the magnetic north-south directions. Formulas exist for converting magnetic to geographical north although I don't know them offhand. An xyz accelerometer by itself produces just the gravity vector, which could allow you to use your cell phone as an electronic bi-directional level (lateral and axial to the orientation of the accelerometer).
Read more: https://www.physicsforums.com
Android中SensorManager.getRotationMatrix函数原理解释的更多相关文章
- Android中的LruCache的原理和使用
Android中的LruCache的原理和使用 LruCache,虽然很多文章都把LRU翻译成"最近最少使用"缓存策略,但Android中的LruCache真的如此吗? 答案是No ...
- Android中调用C++函数的一个简单Demo
这里我不想多解释什么,对于什么JNI和NDK的相关内容大家自己去百度或谷歌.我对Android的学习也只是个新手.废话少说直接进入正题. 一.在Eclipse中创建一个Android Applicat ...
- android中画弧函数canvas.drawArc()之理解
在学习android中图形图像处理技术这部分内容时,对绘制圆弧函数canvas.drawArc()的用法.参数含义及画图原理很是不理解,在网上搜索了一些,加上自己的理解,在此做个小总结,作为学习过程中 ...
- Android 中View的工作原理
Android中的View在Android的知识体系中扮演着重要的角色.简单来说,View就是Android在视觉的体现.我们所展现的页面就是Android提供的GUI库中控件的组合.但是当要求不能满 ...
- Android中微信抢红包插件原理解析和开发实现
一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...
- Android中图像变换Matrix的原理、代码验证和应用(一)
第一部分 Matrix的数学原理 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类.Android中的Matrix是一个3 x 3的矩阵,其内容如下: Matri ...
- Android中图像变换Matrix的原理、代码验证和应用(三)
第三部分 应用 在这一部分,我们会将前面两部分所了解到的内容和Android手势结合起来,利用各种不同的手势对图像进行平移.缩放和旋转,前面两项都是在实践中经常需要用到的功能,后一项据说苹果也是最近才 ...
- Android中Broadcast Receiver组件具体解释
BroadcastReceiver(广播接收器)是Android中的四大组件之中的一个. 以下是Android Doc中关于BroadcastReceiver的概述: ①广播接收器是一个专注于接收广播 ...
- 【Android中Broadcast Receiver组件具体解释
】
BroadcastReceiver(广播接收器)是Android中的四大组件之中的一个. 以下是Android Doc中关于BroadcastReceiver的概述: ①广播接收器是一个专注于接收广播 ...
随机推荐
- ORA-19502: write error on file "", blockno (blocksize=)/linux下磁盘空间满了解决办法--Virtualbox
今天,在测试环境启动数据库时,报错: SQL> startup; ORACLE instance started. Total System Global Area 285212672 byt ...
- LeetCode_Reverse Linked List II
Reverse a linked list from position m to n. Do it in-place and in one-pass. For example: Given -> ...
- 单片机 认识HEX文件
看过几篇常用指令的用法后,我们换换口味,介绍一下Intel 原厂所公布的HEX文件标准格式,相信经过本文的介绍,一定可以让您对8051的操作有更进一步的认识.以下是一个程序经编译器编译后所得到的HEX ...
- Keil "RECURSIVE CALL TO SEGMENT"彻底解决
我们在做菜单程序或通过函数指针调用函数时,如果被调用的函数中有包含了常量字符串,那么经常会出现这样的的错误提示:"RECURSIVE CALL TO SEGMENT"意思是&quo ...
- Android setTextColor无效_安卓setTextColor()的参数设置方式
通过代码setTextColor时.如果color是一个资源文件 会set失败 没有效果 遇到这样的情况有两种解决办法.亲测过.两种都是有效的 一.注解方式 通过在方法上面添加注解解决问题 代码如下 ...
- Copy Constructor in Java
Reference: TutorialPoints, GeekforGeeks The copy constructor is a constructor which creates an objec ...
- UVA 10285 Longest Run on a Snowboard(记忆化搜索)
Problem C Longest Run on a Snowboard Input: standard input Output: standard output Time Limit: 5 sec ...
- 《Java程序员面试笔试宝典》之字符串创建与存储的机制是什么
在Java语言中,字符串起着非常重要的作用,字符串的声明与初始化主要有如下两种情况: (1) 对于String s1=new String("abc")语句与Strin ...
- 基础总结篇之九:Intent应用详解
看似尋常最奇崛,成如容易卻艱辛.北宋.王安石 看似普通的事情其实最不同寻常,并不是简简单单就可以做好的:成功看起来似乎很容易,而成功的过程却充满着艰辛. 对于我们认为很普通的事情,不屑一顾,就永远不会 ...
- 利用PHPExcel转Excel柱形图
这在附还有一个转柱形图的效果及代码. 原PHP报表效果: 转成Excel后的效果: 附上代码: <? php /** * PHPExcel * * Copyright (C) 2006 - 20 ...