I am trying to implement two finger rotation in android however, it is not quite working as expected. The goal is to implement rotation like Google Earth does (two-finger rotating the image around the focal point). Currently my rotation listener looks like this:
private class RotationGestureListener {
private static final int INVALID_POINTER_ID = -1;
private float fX, fY, sX, sY, focalX, focalY;
private int ptrID1, ptrID2;
public RotationGestureListener(){
ptrID1 = INVALID_POINTER_ID;
ptrID2 = INVALID_POINTER_ID;
}
public boolean onTouchEvent(MotionEvent event){
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
sX = event.getX();
sY = event.getY();
ptrID1 = event.getPointerId(0);
break;
case MotionEvent.ACTION_POINTER_DOWN:
fX = event.getX();
fY = event.getY();
focalX = getMidpoint(fX, sX);
focalY = getMidpoint(fY, sY);
ptrID2 = event.getPointerId(event.getActionIndex());
break;
case MotionEvent.ACTION_MOVE:
if(ptrID1 != INVALID_POINTER_ID && ptrID2 != INVALID_POINTER_ID){
float nfX, nfY, nsX, nsY;
nfX = event.getX(event.findPointerIndex(ptrID1));
nfY = event.getY(event.findPointerIndex(ptrID1));
nsX = event.getX(event.findPointerIndex(ptrID2));
nsY = event.getY(event.findPointerIndex(ptrID2));
float angle = angleBtwLines(fX, fY, nfX, nfY, sX, sY, nsX, nsY);
rotateImage(angle, focalX, focalY);
fX = nfX;
fY = nfY;
sX = nfX;
sY = nfY;
}
break;
case MotionEvent.ACTION_UP:
ptrID1 = INVALID_POINTER_ID;
break;
case MotionEvent.ACTION_POINTER_UP:
ptrID2 = INVALID_POINTER_ID;
break;
}
return false;
}
private float getMidpoint(float a, float b){
return (a + b) / 2;
}
private float angleBtwLines (float fx1, float fy1, float fx2, float fy2, float sx1, float sy1, float sx2, float sy2){
float angle1 = (float) Math.atan2(fy1 - fy2, fx1 - fx2);
float angle2 = (float) Math.atan2(sy1 - sy2, sx1 - sx2);
return (float) Math.toDegrees((angle1-angle2));
}
}
However whenever I rotate the angle of rotation is much larger and it sometimes it rotates to the wrong side. Any ideas on how to fix this?
By the way I am testing it on a Motorola Atrix, so it does not have the touchscreen bug.
Thanks