В iOS openGL лучший способ вращать сферу прикосновениями

Я нарисовал объект Globe с помощью OpenGL, и я могу вращать его касанием пальца, но в некоторых случаях он не работает, потому что я вращаю, используя разницу между x и y.

    Rotation3D rot = sphere.currentRotation;
rot.x += diffX ;
rot.y += diffY ;
rot.z += 10 ;
sphere.currentRotation = rot; 

когда вы перемещаете палец из верхнего правого в нижний левый, это не работает.

Любые идеи ?

Спасибо Питер Габра


person Gabra    schedule 05.06.2013    source источник


Ответы (2)


Для произвольного поворота объектов проще всего сохранить их текущую ориентацию в виде матрицы преобразования и манипулировать элементами. Я подробно объясняю это здесь.

Единственное отличие состоит в том, что в этом другом вопросе OP хотел применить вращение из двух элементов управления (горизонтального и вертикального), тогда как вам нужно вращение на основе перетаскивания. Методика в основном такая же, но вместо вращения вокруг оси X или Y вам необходимо вычислить произвольную ось вращения из дельта-вектора касания следующим образом:

axis = [0, 0, 1] ⨯ [diffX, diffY, 0]

( = "перекрестный продукт")

Затем вы поворачиваете векторы U, V и W (как описано в моем другом ответе) вокруг оси на некоторый угол, пропорциональный длине вектора дельты:

M = rotation(k * length([diffX, diffY, 0]), axis)
U = M * U
V = M * V
W = M * W

Если вы обнаружите, что объект вращается в направлении, противоположном ожидаемому, есть три возможности:

  1. Если неверно происходит только вертикальное вращение, вам нужно отрицать diffY. Это частая ошибка, которую я делаю из-за несоответствий между системами координат OpenGL и UIKit.
  2. Если это все вращение, вы можете либо поменять местами аргументы в перекрестном произведении, либо использовать [0, 0, -1]. Обычно это происходит из-за путаницы между левыми и правыми системами координат.
  3. Если это просто горизонтальное вращение, сделайте обе настройки. (Не отрицайте diffX, никто не использует координаты X слева направо.)
person Marcelo Cantos    schedule 05.06.2013
comment
Углы Эйлера ужасны. Вместо этого используйте вращение на основе кватернионов. У вас не будет проблем с блокировкой кардана, она просто работает, никаких специальных исправлений не требуется. en.wikipedia.org/wiki/Gimbal_lock - person occulus; 05.06.2013
comment
@occulus: В моем ответе не используются углы Эйлера и нет подвеса. Кватернионы удобны, если вам нужно хранить их миллионы (например, обратная кинематика), но (IIRC) они менее эффективны в применении, чем матрицы. - person Marcelo Cantos; 05.06.2013
comment
Сообщение, на которое вы ссылаетесь, мне очень похоже на углы Эйлера, но я рассмотрю его поближе позже. - person occulus; 05.06.2013
comment
И то, что вы теряете в эффективности, вы выигрываете, если не возитесь с особыми случаями. - person occulus; 05.06.2013
comment
@occulus: У меня есть две опубликованные игры, в которых используется описываемое мной решение. Ни один из них не страдает от блокировки кардана. Оба они являются бесплатными приложениями, так что не стесняйтесь убедиться в этом сами (если, конечно, у вас есть кое-что). - person Marcelo Cantos; 05.06.2013
comment
@occulus: Какие особые случаи? Весь алгоритм описан выше (M = rotation…). - person Marcelo Cantos; 05.06.2013
comment
Хорошо, я имел в виду особые случаи сложения углов Эйлера, но если вы этого не делаете, игнорируйте меня! - person occulus; 05.06.2013
comment
@occulus: это может помочь, если вы сосредоточитесь на ИЗМЕНИТЬ 2 в связанном ответе. Это объясняет разницу между тем, что пытался сделать ОП, что действительно связано с углами Эйлера, и тем, что я предлагал. - person Marcelo Cantos; 05.06.2013

Если вы используете углы Эйлера: Я рекомендую не использовать углы Эйлера для моделирования вращений. Вместо этого используйте кватернионы. Может показаться, что это усложняет ваш код, но ротации хорошо работают, когда вы используете Quaternions. Вот некоторые преимущества:

  • очень просто применить взаимодействие с пользователем к текущему состоянию вращения
  • нет проблем с блокировкой карданного подвеса
  • нет необходимости регулировать смещение матрицы после многократных поворотов
  • вы можете легко интерполировать повороты

Обратите внимание, что Apple предоставляет вам тип Quaternion для использования: GLKQuaternion. Нет необходимости писать свой собственный класс Quaternion.

Смотрите также:

person occulus    schedule 05.06.2013