安卓:从方向/旋转角度获取轴向向量?

3

在Android SensorManager中,有几种方法可以获取手机的方向:

float[] rotational = new float[9];
float[] orientation = new float[3];
SensorManager.getRotationMatrix(rotational, whatever, whatever, whatever);
SensorManager.getOrientation(rotational, orientation);

这会给你一个名为“旋转”的旋转矩阵和一个包含3个方向角的数组,称为“方向”。然而,在我的AR程序中我不能使用这些角度 - 我需要代表轴的实际向量。
例如,在维基百科上的这张图片中:
Euler Angles from Wikipedia
我基本上是被给予α,β和γ角度(虽然不完全准确,因为我没有N - 我得到了每个蓝色轴的角度),我需要找到代表X,Y和Z轴的向量(图中的红色)。有人知道如何进行这种转换吗?维基百科上的说明非常复杂,我试图按照它们的说明操作,但并没有成功。另外,我认为Android提供给您的数据可能与维基百科上的转换说明所期望的顺序或格式略有不同。
作为这些转换的替代方案,有人知道从相机的视角获取X,Y和Z轴的其他方法吗? (意思是,相机正在看哪个向量?相机认为哪个向量是“向上”的?)
3个回答

3
Android中的旋转矩阵提供了从设备框架(即身体框架)到世界框架(即惯性框架)的旋转。在屏幕上,普通的后置摄像头以横向模式显示。对于平板电脑来说,这是本机模式,因此在设备框架中具有以下轴:
camera_x_tablet_body = (1,0,0)
camera_y_tablet_body = (0,1,0)
camera_z_tablet_body = (0,0,1)

在手机上,竖屏是原生模式,在将设备旋转为横屏时,顶部向左指向的方式是:
camera_x_phone_body = (0,-1,0)
camera_y_phone_body = (1,0,0)
camera_z_phone_body = (0,0,1)

现在应用旋转矩阵将其置于世界坐标系中,因此(对于大小为9的旋转矩阵R []):
camera_x_tablet_world = (R[0],R[3],R[6]);
camera_y_tablet_world = (R[1],R[4],R[7]);
camera_z_tablet_world = (R[2],R[5],R[8]);

通常情况下,您可以使用SensorManager.remapCoordinateSystem()方法来实现,在上述电话示例中,它将是Display.getRotation()=Surface.ROTATION_90并给出您提供的答案。但如果您以不同的方式旋转(例如ROTATION_270),结果将会有所不同。
另外,顺带一提:在Android中获取方向的最佳方法是监听Sensor.TYPE_ROTATION_VECTOR事件。这些事件填充了大多数(即Gingerbread或更新版本)平台上最佳的方向。实际上,这是四元数的向量部分。您可以使用此方法获取完整的四元数(最后两行是获取RotationMatrix的方式)。
float vec[] = event.values.clone();
float quat[] = new float[4];
SensorManager.getQuaternionFromVector(quat, vec);
float [] RotMat = new float[9];
SensorManager.getRotationMatrixFromVector(RotMat, quat);

更多信息请访问:http://www.sensorplatforms.com/which-sensors-in-android-gets-direct-input-what-are-virtual-sensors

1
SensorManager.getRotationMatrix(rotational, null, gravityVals, geoMagVals);

// camera's x-axis
Vector u = new Vector(-rotational[1], -rotational[4], -rotational[7]); // right of phone (in landscape mode)
// camera's y-axis
Vector v = new Vector(rotational[0], rotational[3], rotational[6]); // top of phone (in landscape mode)
// camera's z-axis (negative into the scene)
Vector n = new Vector(rotational[2], rotational[5], rotational[8]); // front of phone (the screen)
// world axes (x,y,z):
// +x is East
// +y is North
// +z is sky

0
从getRotationMatrix获得的方向矩阵应基于重力场和磁场 - 换句话说,X指向东,Y指向北,Z指向地球中心。(http://developer.android.com/reference/android/hardware/SensorManager.html)
至于您的问题,我认为可以直接将三个旋转值用作矢量,但以相反的顺序提供值: “对于欧拉或Tait-Bryan角度,从内部(旋转轴)到外部(静态轴)约定,或者反之亦然,非常简单:只需交换操作的顺序。使用X-Y-Z内部约定的(α,β,γ)旋转等效于使用Z-Y-X外部约定的(γ,β,α)旋转; 对于所有欧拉或Tait-Bryan轴组合都是如此。” 出处 wikipedia 希望这可以帮助您!

但是这三个值会给你什么向量呢?我需要三个不同的向量——相机的前向、上向和右向向量。getRotationMatrix()返回的矩阵中有9个值……但我不知道如何将它们转换为我所需的3个向量。 - Dasmowenator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接