Получить угол наклона Эйлера на устройстве Android
Я пытаюсь получить рыскание устройства Android, выраженное в углах Эйлера.
Чтобы быть ясным, я не хочу, чтобы "Азимут" (это угол к магнитному северу), я хочу вращение оси "z" устройства Android, как показано на этом рисунке.
Это (ИМХО) должно быть осью, используемой в некоторых автомобильных играх для определения степени рулевого управления.
Насколько я понимаю, я мог бы просто использовать значения акселерометра (без магнитных полей), но я не могу получить определенное значение. (вероятно, из-за отсутствия понимания того, как работает матрица вращения).
Может ли кто-нибудь указать мне правильное направление?
1 ответ
Если вы хотите вычислить вращение вокруг оси z устройства независимо от положения устройства (плоского или не плоского), вам необходимо отслеживать несколько вещей. Если приложение поддерживает как "Портрет", так и "Пейзаж", то это более сложно, я собираюсь дать ответ, когда действие ограничено только Портретом.
Таким образом, плоскость здесь означает, что угол наклона меньше 25 или более 155 градусов и не ровный в противном случае.
Когда устройство находится в переходе из плоского состояния в не плоское и наоборот, в пользовательском интерфейсе возможно некоторое несоответствие.
Зарегистрируйтесь для TYPE_GRAVITY
а также TYPE_MAGNETIC_FIELD
(необходимо для квартиры) и сделайте расчет ниже.
getRotationMatrix
a [0] a [1] a [2]
а [3] а [4] а [5]
а [6] а [7] а [8]подсчитывать
pitch = Math.asin(-R[7])
- С помощью
pitch
чтобы определить плоскостность устройства (я думаю, что вы можете использовать менее 45 и более 135 для определения плоскостности, вам просто нужно поэкспериментировать, чтобы увидеть,azymuth
значение верное) если устройство не плоское, вращение - Math.atan2(a[6], a[7])
Если устройство плоское, чтобы начать с получения начального
azymuth = Math.atan2(R[1], R[4])
а затем взять разницу с последующимazymuths
чтобы получить вращение.Если устройство переходит из плоского состояния в не плоское, проблем не должно быть, вращение - это просто вращение для не плоского сверху.
Если устройство переходит из не плоской в плоскую, то вам нужно получить начальный
azymuth
, Этот начальныйazymuth
можно установить в направлении задней камеры Math.atan2(-a[2], -a[5]), если устройство находится в вертикальном положении и вращение происходит только вокруг оси z, это направление не должно меняться. В действительности это, вероятно, изменится на несколько градусов, поэтому вам нужно будет взять среднее значение.
Вся математика, кроме Math.atan2(a[6], a[7]), объяснена в Android: алгоритмы для SensorManager.getRotationMatrix и SensorManager.getOrientation()
Итак, позвольте мне дать объяснение для поиска вращения, когда устройство не является плоским.
Как объяснено в ссылке выше, вы должны указать фиксированный вектор и изменяющийся вектор, чтобы вычислить угол между ними. В этом случае изменяющийся вектор представляет собой вектор, лежащий на оси y устройства, а фиксированный вектор представляет собой проекцию вектора гравитации на плоскость xy устройства. В матрице вращения над последней строкой находится нормализованный гравитационный вектор в координате устройства, поэтому проекция на плоскость xy устройства имеет вид (a[6], a[7]). Теперь с помощью простой тригонометрии видно, что Math.atan2(a[6], a[7]) - это угол между осью y устройства и гравитационной проекцией. (Нарисуйте картинку, если вы ее не видите).