Android: векторы осей от ориентации / углов поворота? - PullRequest
3 голосов
/ 18 января 2012

Итак, в 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 голосов
/ 21 апреля 2012

Матрица вращения в Android обеспечивает поворот от фрейма тела (он же устройство) к фрейму мира (он же инерционный).На экране в обычном режиме отображается обычная камера, обращенная назад.Это основной режим для планшета, поэтому в кадре устройства имеются следующие оси:

camera_x_tablet_body = (1,0,0)
camera_y_tablet_body = (0,1,0)
camera_z_tablet_body = (0,0,1)

На телефоне, где портретный режим является основным, поворот устройства в альбомную ориентацию с верхним краем, повернутым влевоis:

camera_x_phone_body = (0,-1,0)
camera_y_phone_body = (1,0,0)
camera_z_phone_body = (0,0,1)

Теперь, применяя матрицу вращения, поместим это в кадр мира, поэтому (для матрицы вращения R [] размера 9):

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 голос
/ 22 января 2012
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 голосов
/ 02 февраля 2012

Матрица ориентации, которую вы получаете от getRotationMatrix, должна основываться на гравитационном поле и магнитном поле - другими словами, X указывает на восток, Y - на север, Z - на центр Земли.(http://developer.android.com/reference/android/hardware/SensorManager.html)

К вашему вопросу, я думаю, что три значения вращения можно использовать непосредственно как вектор, но предоставьте значения в обратном порядке: «Для углов Эйлера или Тейт-Брайана это очень простопреобразовать внутреннюю (вращающиеся оси) в внешнюю (статическую ось) конвенцию и наоборот: просто поменять местами порядок операций. (α, β, γ) вращение с использованием внутренней конвенции XYZ эквивалентно (γ, β, α) вращение с использованием внешнего соглашения ZYX; это верно для всех комбинаций осей Эйлера или Тейт-Брайана. "Источник Википедия

Надеюсь, это поможет!

...