Math has defeated me once again. This is such a simple task, but I can't manage to get it done.
Scenario: I draw on a SurfaceView a round image. The user touches a point on image border and starts to drag it adround. I need to rotate the circle image according to user movement. I have two important piece of information, the image center X,Y coordinates and the touched points coordinates.
As you can see in the image, the user touched a point, according to my draw the touched point angle should be around 40. I can't manage to calculate it properly.
I tried using this formula:
angle = Math.atan2(touchedY - centerY, touchedX - centerX) * 180 / Math.PI
I can't manage to understand how I should calculate the angle, as it is now, it doesn't work properly and values are not good. For instance, in the case of the image, the angle calculate is -50.
Thank you for your time, any informations is gladly taken.
LE: Actually I did a mistake I think, as mentioned below. Should the circle be like:
Let's reformulate the problem: You want to find the angle between two vectors. The first vector is the upvector going straigt up from your center-point (u), and the second vector is the vector from the center point to the touch point (v).
Now we can recall (or google) that
cos a = uv / (|u|*|v|)
Where a is the angle between the vectors and |u| is the length of a vector. The upvector, u, is (0, 1) and has length 1.
Multiplying the vectors by hand cancels the x-term and gives us something like this.
double tx = touch_x - center_x, ty = touch_y - center_y;
double t_length = Math.sqrt(tx*tx + ty*ty);
double a = Math.acos(ty / t_length);
Note how the v vector is obtained by subtracting the center point from the touch point. Remember to convert to degrees if needed.
first of all, the rotate angle should be determined by the origin of CenterX, and CenterY. So your (touchedY - centerY, touchedX - centerX) should be (centerY - touchedY, centerX - touchedX).
And the correct answer may be:
(int) (Math.toDegrees(Math.atan2(centerY - touchedY, centerX - touchedX)));
Hope it helps
You need 3 points for an angle. You only have 2 (center and touch). Choose a fixed 3rd point, for example the one at 90 in your picture, and use @vidstige's answer to find your equation.
I tried a lot of things to do something like that and come with this:
Its getting the view position instead of the center of the screen, but you can addapt it:
ROTATE IMAGE VIEW BASED ON TOUCH POINT:
iv = (ImageView) findViewById(R.id.soldier); // img view to rotate
int touch_x = (int) event.getX(); // touch point x
int touch_y = (int) event.getY(); // touch point y
int[] location = new int[2];
iv.getLocationInWindow(location); // get img location on screen
float angle = (float) Math.toDegrees(Math.atan2( touch_x - location[0], touch_y - location[1]));
if(angle < 0){
angle += 360;
}
iv.setRotation(-angle);
private fun getAngle(touchX: Float, touchY: Float): Double {
var angle: Double
val x2 = touchX - centerX
val y2 = touchY - centerY
val d1 = Math.sqrt((centerY * centerY).toDouble())
val d2 = Math.sqrt((x2 * x2 + y2 * y2).toDouble())
if (touchX >= centerX) {
angle = Math.toDegrees(Math.acos((-centerY * y2) / (d1 * d2)))
} else
angle = 360 - Math.toDegrees(Math.acos((-centerY * y2) / (d1 * d2)))
return angle
}
where touchX = event.getX and touchY = event.getY
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With