1
votes

I am currently working on a 3D model viewer for Android using OpenGL-ES. I want to create a rotation effect according to the gesture given. I know how to do single-axis rotation, such as rotate solely on the x-, y- or z-axis. However, my problem is that I don't know how to combine them all 3 together and have my app know in which axis I want to rotate depending on the touch gesture. Gestures I have in mind were:

  • Swipe up/down for x-axis
  • Swipe left/right for y-axis
  • swipe in circular motion for z-axis

How can I do this?

EDIT: I found out that 3 types of swipes can make the moment very ugly. Therefore what I did was remove the z-axis motion. After removing that condition, I found that the other 2 work really well in conjunction with the same algorithm.

2
I haven't programmed in Android, but this seems easy to me. Detect a swipe up or down (if Android has gesture recognizers, use that; else, detect the first touch, then the touch up, and get a direction from that) then apply the amount of rotation on whatever axis you want based on the distance/speed of the swipe. You're going to have to do a bit more work for circular gesture but you'll probably find something on SO.Dominic K
Yes, that much I knew. I did say that I knew how to handle single axis swipes. My problem is how to recognize individual type of touch motions, such as straight swipes and curved swipes in the same handler. Direction of the swipe is easy once I have figured out the corresponding paths.drum

2 Answers

2
votes

http://developer.android.com/resources/articles/gestures.html has some info on building a 'gesture library'. Not checked it out myself, but seems to fit what you're looking for

Alternatively, try something like gestureworks.com (again, I've not tried it myself)

I use a progressbar view for zooming in and out. I then use movement in x on the GLSurfaceView to rotate around the y axis and movement in y to rotate around the x axis

The problem with a gesture is that the response is not instant as the app tries to determine what gesture the user used. If you then use how far the user moves their finger to determine the amount to rotate/zoom then there is no instant feedback and so it takes time for the user to learn how to control rotate/zoom amount. I guess it would work if you were rotating/zooming by a set amount each gesture

1
votes

It sounds like what you are looking to do is more math intensive than you might know. There are two ways to do this mathematically. (1) using quaternions (2) using basic linear algebra (but will result in gimbal lock if you arent careful.. but since you are just spinning then this is not a concern to you).. Lets go the second route since its easier.. What you need to do is recieve the beginning and end points of the swipe via a gesture implement and when you have those two points.. calculate the line that it makes. When you have that line, you can easily find the perpendicular vector to that line with high school math. That should now be your axis of rotation in your rotation matrix:

    //Rotate around the axis based on the rotation matrix (rotation, x, y, z)
    gl.glRotatef(rot, 1.0f, 1.0f, 0.0f);

No need for the Z rotation since you can not rotate in the Z plane with a 2D tablet. The 1.0f, 1.0f are the values that should be variables that represent the x,y of your vector. The (rot) should serve as the magnitude of the distance between the two points.

I havent done this in a while so let me know if you need more precision.