从rotationMatrix中提取偏航,俯仰和滚动

我有一个传感器pipe理器,根据设备的磁力计和加速度计返回一个rotationMatrix 。 我一直在试图计算用户设备的偏航俯仰和滚转,但是我发现俯仰和滚转相互干扰并给出不准确的结果。 有没有办法从rotationMatrix提取设备的YAW PITCH和ROLL?

编辑试图解释搅拌机的答案下面,我很感激,但还没有那里,我想从这样的旋转matrix得到的angular度:

  float R[] = phoneOri.getMatrix(); double rmYaw = Math.atan2(R[4], R[0]); double rmPitch = Math.acos(-R[8]); double rmRoll = Math.atan2(R[9], R[10]); 

我不知道我是否引用了matrix的错误部分,但我没有得到我想的结果。

我希望能获得度数的值,但是变得奇怪的整数。

我的matrix来自我的sensorManager ,看起来像这样:

 public void onSensorChanged(SensorEvent evt) { int type=evt.sensor.getType(); if(type == Sensor.TYPE_ORIENTATION){ yaw = evt.values[0]; pitch = evt.values[1]; roll = evt.values[2]; } if (type == Sensor.TYPE_MAGNETIC_FIELD) { orientation[0]=(orientation[0]*1+evt.values[0])*0.5f; orientation[1]=(orientation[1]*1+evt.values[1])*0.5f; orientation[2]=(orientation[2]*1+evt.values[2])*0.5f; } else if (type == Sensor.TYPE_ACCELEROMETER) { acceleration[0]=(acceleration[0]*2+evt.values[0])*0.33334f; acceleration[1]=(acceleration[1]*2+evt.values[1])*0.33334f; acceleration[2]=(acceleration[2]*2+evt.values[2])*0.33334f; } if ((type==Sensor.TYPE_MAGNETIC_FIELD) || (type==Sensor.TYPE_ACCELEROMETER)) { float newMat[]=new float[16]; SensorManager.getRotationMatrix(newMat, null, acceleration, orientation); if(displayOri==0||displayOri==2){ SensorManager.remapCoordinateSystem(newMat,SensorManager.AXIS_X*-1, SensorManager.AXIS_MINUS_Y*-1,newMat); }else{ SensorManager.remapCoordinateSystem(newMat,SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X,newMat); } matrix=newMat; 

当设备面朝上放置在桌子上时的样品matrix

 0.9916188, -0.12448014, -0.03459576, 0.0 0.12525482, 0.9918981, 0.021199778, 0.0 0.031676512,-0.025355382, 0.9991765, 0.0 0.0, 0.0, 0.0, 1 

回答

 double rmPitch = Math.toDegrees( Math.acos(R[10])); 

Solutions Collecting From Web of "从rotationMatrix中提取偏航,俯仰和滚动"

偏航,俯仰和俯仰对应于欧拉angular。 你可以很容易地将转换matrix转换成欧拉angular :

在这里输入图像说明

我相信Blender的回答是不正确的,因为他给出了从旋转matrix到欧拉angular(zxz extrinsic)的转换,滚动俯仰偏转是一种不同的欧拉angular(zyx extrinsic)。

实际的转换公式宁愿是:

 yaw=atan2(R(2,1),R(1,1)); pitch=atan2(-R(3,1),sqrt(R(3,2)^2+R(3,3)^2))); roll=atan2(R(3,2),R(3,3)); 

资源

Sensor Manager提供了一个SensorManager.getOrientation来获取所有三个angular度。