Sorry if the title sounds confusing - but this is what I am trying to do:
I have a large circular button on which I detect touch direction. I am able to find the UP/DOWN/LEFT/RIGHT from the dy and dx of the change in touch input coordinates like this:
if(Math.abs(dX) > Math.abs(dY)) {
if(dX>0) direction = 1; //left
else direction = 2; //right
} else {
if(dY>0) direction = 3; //up
else direction = 4; //down
}
But now I would like to handle cases where the button can be slightly rotated and thus the touch direction will also need to adjust for this. For example, if the button is rotated slightly to the left, then UP is now the finger moving northwest instead of just pure north. How do I handle this?
Use Math.atan2(dy, dx) to get the angle anticlockwise from the positive horizontal of the coordinate in radians
double pressed = Math.atan2(dY, dX);
subtract the rotation amount (anticlockwise rotation amount in radians) from this angle, putting the angle into the coordinate system of the button
pressed -= buttonRotation;
or if you have your angle in degrees, convert it to radians
pressed -= Math.toRadians(buttonRotation);
You can then calculate an easier direction number from this angle
int dir = (int)(Math.round(2.0d*pressed/Math.PI) % 4);
This gives right 0, up 1, left 2 and down 3. We need to correct the case where the angle is negative, as the modulo result will also be negative.
if (dir < 0) {
dir += 4;
}
Now supposing that these numbers are bad and you don't want to use them, you can just switch on the result to return whatever you like for each direction. Putting that all together:
/**
* @param dY
* The y difference between the touch position and the button
* @param dX
* The x difference between the touch position and the button
* @param buttonRotationDegrees
* The anticlockwise button rotation offset in degrees
* @return
* The direction number
* 1 = left, 2 = right, 3 = up, 4 = down, 0 = error
*/
public static int getAngle(int dY, int dX, double buttonRotationDegrees)
{
double pressed = Math.atan2(dY, dX);
pressed -= Math.toRadians(buttonRotationDegrees);
// right = 0, up = 1, left = 2, down = 3
int dir = (int)(Math.round(2.0d*pressed/Math.PI) % 4);
// Correct negative angles
if (dir < 0) {
dir += 4;
}
switch (dir) {
case 0:
return 2; // right
case 1:
return 3; // up
case 2:
return 1; // left;
case 3:
return 4; // down
}
return 0; // Something bad happened
}