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:
- 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.
- 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.
- If it's just the horizontal rotation, make both adjustments. (Don't negate
diffX
, no one uses left-to-right X-coordinates.)