2

I drew Globe object using OpenGL and i can rotate it with finger touch , but it doesn't work well in some cases because i am rotating using the difference between x and y

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

when you move your finger from Top Right to bottom Left it isn't work good.

Any ideas ?

Thanks Peter Gabra

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Gabra
  • 74
  • 5

2 Answers2

0

To arbitrarily rotate objects, it's easiest to store their current orientation as a transformation matrix and manipulate the elements. I explain this in detail here.

The only difference is that in that other question, the OP wanted to apply rotations from two controls (horizontal and vertical), whereas you are after drag-based rotation. The technique is basically the same, but instead of rotating around either the X or Y axis, you need to compute an arbitrary axis of rotation from the touch's delta vector as follows:

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

( = "cross product")

Then you rotate the U, V and W vectors (as described in my other answer) around the axis by some angle in proportion to the length of the delta vector:

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

If you find the object rotating in the opposite direction to what you expect, there are three possibilities:

  1. If it's only the vertical rotation that goes the wrong way, you need to negate diffY. This is a common mistake I make due to inconsistencies between OpenGL and UIKit coordinate systems.
  2. If it's all rotation, you can either swap the arguments in the cross-product or use [0, 0, -1]. This is usually because of confusion between left- and right-handed coordinate systems.
  3. If it's just the horizontal rotation, make both adjustments. (Don't negate diffX, no one uses left-to-right X-coordinates.)
Community
  • 1
  • 1
Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • Euler angles are horrible. Use Quaternion-based rotations instead. You won't have problems with gimbal lock, and it just works, no special fixes needed. http://en.wikipedia.org/wiki/Gimbal_lock – occulus Jun 05 '13 at 10:47
  • @occulus: My answer doesn't use Euler angles and doesn't suffer from gimbal lock. Quaternions are handy if you need to hold gazillions of them (e.g., inverse kinematics), but (IIRC) they are less efficient to apply than matrices. – Marcelo Cantos Jun 05 '13 at 10:49
  • The post you linked to looks very much like Euler angles to me but I'll have a closer look later. – occulus Jun 05 '13 at 10:59
  • And what you lose in efficiency, you gain in not having a fudge around with special cases. – occulus Jun 05 '13 at 11:00
  • @occulus: I have [two published games](http://squz.com/) that use the solution I describe. Neither of them suffers from gimbal lock. They're both freemium apps, so feel free to see for yourself (if you have an iThing, of course). – Marcelo Cantos Jun 05 '13 at 11:02
  • @occulus: What special cases? The entire algorithm is as described above (`M = rotation…`). – Marcelo Cantos Jun 05 '13 at 11:02
  • Ah ok, I was referring to special cases if compounding euler angles, but if you're not doing that then ignore me! – occulus Jun 05 '13 at 11:03
  • @occulus: It might help if you focus on "EDIT 2" in the linked answer. It explains the difference between what the OP was trying to do, which does involve Euler angles, and what I proposed. – Marcelo Cantos Jun 05 '13 at 11:08
0

In case you're using Euler angles: I recommend not using Euler angles to model rotations. Use Quaternions instead. It might seem like it makes your code more complicated, but rotations work well when you use Quaternions. Here's some advantages:

  • it's very straightforward to apply user interaction to current rotation state
  • no gimbal lock problems
  • no need for matrix drift adjustments after repeated rotations
  • you can interpolate rotations easily

Note that Apple give you a Quaternion type to use: GLKQuaternion. No need to write your own Quaternion class.

See also:

Community
  • 1
  • 1
occulus
  • 16,959
  • 6
  • 53
  • 76