IOS openGL най-добрият начин за завъртане на сфера с touchesMoved

Начертах обект 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: Имам две публикувани игри, които използват решението, което описвам. Нито един от тях не страда от заключване на кардана. И двете са безплатни приложения, така че не се колебайте да се убедите сами (ако имате iThing, разбира се). - person Marcelo Cantos; 05.06.2013
comment
@occulus: Какви специални случаи? Целият алгоритъм е както е описано по-горе (M = rotation…). - person Marcelo Cantos; 05.06.2013
comment
А, добре, имах предвид специални случаи, ако съставяте ъгли на Ойлер, но ако не правите това, тогава ме игнорирайте! - person occulus; 05.06.2013
comment
@occulus: Може да помогне, ако се съсредоточите върху EDIT 2 в свързания отговор. Това обяснява разликата между това, което ОП се опитваше да направи, което включва ъгли на Ойлер, и това, което предложих. - person Marcelo Cantos; 05.06.2013

В случай, че използвате ъгли на Ойлер: Препоръчвам да не използвате ъгли на Ойлер за моделиране на ротации. Вместо това използвайте кватерниони. Може да изглежда, че прави кода ви по-сложен, но ротациите работят добре, когато използвате Quaternions. Ето някои предимства:

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

Имайте предвид, че Apple ви предоставя тип Quaternion, който да използвате: GLKQuaternion. Няма нужда да пишете свой собствен клас Quaternion.

Вижте също:

person occulus    schedule 05.06.2013