I have an ImageView that you can use to do a one-finger pan, or a two finger scale. It works fine. I've extended it to handle rotation, and its behaviour is causing some confusion.
When there's a multi-touch event this method gets called, which should return an angle of rotation in degrees. It is not doing what I expect.
private int fingersAngle(MotionEvent event)
{
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
int degrees = (int)(Math.toDegrees(Math.atan2(y, x)));
return degrees;
}
As I rotate the two fingers I'd expect outputs like...
158 166 168 169 174 176 179 181 etc
But what I actually get is more like this:
158 166 -179 179 -179 179 -179
The problem seems to be with signs. How does this method know whether it's 180 or -180, or 90 or -270? The image often rotates the wrong way, and then suddenly jumps and starts rotating the opposite way. Even worse, the direction it initially rotates is effectively random.
I'm testing the app using a Nexus One, but also see the same problem on an Advent Vega tablet. Both devices work ok with Google Maps in 3D to rotate the screen (if a bit jumpy sometimes) so the evidence doesn't suggest a hardware limitation.
A secondary problem is that when the two fingers are approximately vertically or horizontally aligned the angle simply doesn't change, so the rotation "sticks" for about 10-20 degrees top/bottom/left/right.
Currently I'm doing a check to see if the angle has suddenly changed a huge amount, and if so, to subtract it from 360. Ugly as hell, but it helps a little.
Hopefully one of you has seen this before and knows how to extract the angular rotation from a multi-touch gesture.
Some things in Android are so easy it's amazing, but stuff like this is seriously painful.