3D-вращение при 2D-жесте/движении (OpenGL/Cocos3D)

Я использую OpenGL, а именно Cocos3d, для отображения глобуса в проекте iPhone/iPad. Я хочу, чтобы пользователь мог вращать земной шар пальцем. Вращение только вокруг одной оси работает нормально, но я не знаю, как решить 3 оси вместе...

Захват движения пальца также работает -> я получаю 2D-значения (x/y), но как мне преобразовать их в 3D-вращение?


person Django    schedule 01.03.2012    source источник


Ответы (2)


Представьте, что в центре окна находится трехмерная сфера (не эллипс), которая касается краев окна. Он находится в пространстве экрана, а не в мировом пространстве. «Пространство экрана» означает, что если ваше окно имеет размер 640x480, то сфера расположена по координатам x=320,y=240 и имеет радиус 240 (min(width,height)/2), независимо от вашей матрицы представления модели/проекции.

Когда пользователь нажимает на кнопку мыши, он выбирает точку на сфере. Если щелчок находится за пределами этой сферы, начальная точка перемещается в границу сферы. Назовем эту точку pointA. Когда пользователь перетаскивает мышь, положение мыши отмечает, где пользователь хочет, чтобы эта начальная точка была. Назовем его pointB.

Теперь для сферы довольно легко вычислить 3-ю координату по первым двум, поскольку R^2 = X^2+y^2+z^2 Таким образом, вы можете вычислить 3-ю координату для начальной точки (pointA) и 3-ю координату для текущей точки (pointB). Теперь, используя две точки, вы можете вычислить два вектора из центра сферы (O) в точку (vectorOA = pointA - O; vectorOB = pointB - O). Теперь, когда у вас есть два вектора, вы можете использовать их для вычисления оси вращения (используя векторное произведение = rotationAxis = normalize(vecOA x vecOB);) и угол поворота (используя acos для скалярного произведения нормализованных векторов = acos(dot(normalize(vecOA), normalize(vecOB))). Используя ось и угол, вы можете построить матрицу вращения в пространстве экрана, которую затем можно преобразовать в нужное пространство и применить к объекту.

Этот метод обычно называют «трекбол». Он использовался в некоторых примерах в Microsoft DirectX SDK, и вы сможете найти его где-нибудь в NVidia OpenGL SDK. Поэтому, если вы не понимаете объяснения, я предлагаю взять любой SDK и изучить любой пример, который позволяет вам вращать объект с помощью мыши.

person SigTerm    schedule 01.03.2012
comment
+1 для трекбола. Объяснение с помощью нескольких красивых изображений: viewport3d.com/trackball.htm - person ma cılay; 01.03.2012

Простой способ — просто установить вращение вокруг оси Y на компонент translationInView x для вращения, а вращение вокруг оси X — на компонент translationInView y. Возможно, вам придется разделить перевод на некоторую величину, поскольку значения поворота указаны в радианах. Обычно я считаю, что предоставления пользователю 2 степеней свободы достаточно, но если вам нужно разрешить пользователю вращаться вокруг оси z, вы можете рассмотреть возможность использования UIRotationGestureRecognizer для отдельной обработки этого случая.

CGPoint translation = [sender translationInView:self.view];
_rotationY = translation.x / 100.0f;
_rotationX = translation.y / 100.0f;
person Jeremy    schedule 02.03.2012