DeviceOrientationEvent: как бороться с сумасшедшей гаммой, когда бета приближается/достигает 90 градусов?

У кого есть опыт DeviceOrientationEvent и телефон/планшет под рукой?

Выполняя следующие фрагменты кода на устройстве с гироскопом, я заметил, что гамма (вращение влево/вправо вдоль оси Y) становится большой и непредсказуемой, когда бета приближается к 90 градусам (устройство направлено прямо вверх). Я предполагаю, что это карданный замок.

var data, raf, alpha = document.getElementById("alpha"),
  beta = document.getElementById("beta"),
  gamma = document.getElementById("gamma");

window.addEventListener("deviceorientation", processData);
window.addEventListener('click', togglePause);
updateText();

function processData(e) {
  data = e;
}

function updateText() {
  if (data) {
    alpha.textContent = Math.round(data.alpha);
    beta.textContent = Math.round(data.beta);
    gamma.textContent = Math.round(data.gamma);
  }
  raf = requestAnimationFrame(updateText);
}

function togglePause(e) {
  if (raf) {
    cancelAnimationFrame(raf);
    raf = null;
    window.removeEventListener("deviceorientation", processData);
  } else {
    window.addEventListener("deviceorientation", processData);
    raf = requestAnimationFrame(updateText);
  }
}
body {
  font: normal 30px/200% sans-serif;
  margin: 20px;
  cursor: default;
}
span {
  font-size: 50px;
  vertical-align: middle;
}
<body>
  alpha: <span id="alpha">null</span>
  <br>beta: <span id="beta">null</span>
  <br>gamma: <span id="gamma">null</span>
  <br>[tap to pause/resume]
</body>

https://jsfiddle.net/1us8p1ad/show

Мой вопрос: как я могу предсказуемо отслеживать левую/правую ориентацию устройства с помощью гаммы? Гамма - единственное значение, которое меня волнует - 3D-пространство не требуется.

Я изучал использование матрицы вращения и кватерниона, как обсуждалось здесь, но не получение достоверных результатов. Фактически, примеры на странице автора на github также ломаются, когда бета-версия достигает 90 градусов! То же самое с этим руководством по MDN — проверьте его на своем устройстве: когда это прямо вверх, мяч сходит с ума. Как эти отклонения остались незамеченными!


person calipoop    schedule 05.01.2017    source источник
comment
Помогает ли это CodePen? Он использует углы кватерниона вместо углов Эйлера, чтобы избежать блокировки карданного подвеса.   -  person u01jmg3    schedule 15.01.2017
comment
@ u01jmg3 спасибо за ваш ответ - этот codepen, однако, все еще сталкивается с проблемой блокировки - вы заметите, что если вы держите устройство прямо вверх и вниз, скручивание не дает никакого эффекта. Напротив, если вы положите устройство горизонтально, вращение его влево/вправо даст желаемый результат.   -  person calipoop    schedule 15.01.2017


Ответы (2)


Кажется, блокировка подвеса — известное препятствие в реальном мире, и многие приложения избегают его, ограничивая движение устройства (в моем случае это невозможно).

Мое решение состояло в том, чтобы преобразовать значения альфа/бета/гамма в матрицу вращения, а затем извлечь данные из одного из значений матрицы. Код, который я использовал, был предоставлен здесь из W3C.

Обратите внимание, я пытался использовать кватернионы, но полученные значения не помогли для движения только в одном направлении.

person calipoop    schedule 15.01.2017
comment
Из-за того, что у вас есть код, которым вы можете поделиться, который создает матрицу вращения? - person u01jmg3; 15.01.2017
comment
@ u01jmg3, конечно! Я обновил свой ответ, включив в него источник кода, который я использовал. Все обсуждение на этой странице очень важно для понимания моей проблемы. - person calipoop; 15.01.2017
comment
Спасибо, ты спас мою задницу. У меня он работает не идеально, гамма все еще немного дергается, но это приемлемо. - person Tomasz Nowak; 27.08.2018
comment
Гамма немного поправилась. Раньше это было почти непригодно для использования под таким углом, теперь это просто терпимо ... Все еще не могу понять, как это исправить полностью. - person Coburn; 10.09.2018
comment
Итак, я заставил это работать, без блокировки карданного подвеса, но вам нужно использовать код W3C. FULLTILT.js использует этот код внутри, но реализует если вы используете THREE.js, вам нужно будет преобразовать основной формат строки в основной формат матрицы столбца, прежде чем применять его к вашим Vector3 или Object3D. По какой-то причине я все еще получал блокировку карданного подвеса, когда сам брал альфу, гамму, бету и бросал их в THREE.Matrix3... - person Coburn; 10.09.2018
comment
Мне пришлось переключиться на {"type": "game"} в FULLTILT.js, и теперь я получаю ту же сумасшедшую гамма-асимптоту: c - person Coburn; 11.09.2018

попробуйте погуглить "карданный замок" по причине,

и не просто фокусируйтесь на самой гамме, часть ее значения угла идет на ось альфа, вам нужно пересчитать, учитывая другие 2 измерения

см. аналогичный вопрос: https://stackoverflow.com/a/52264991/5853749

person wsxmax    schedule 10.09.2018