问题
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:
回答1:
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.
回答2:
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
回答3:
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.
回答4:
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);
回答5:
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
回答6:
this for angle betweet two point in Degree
angle = (Math.atan2(y2-y1,x2-x1) *180 / Math.PI)
来源:https://stackoverflow.com/questions/7926816/calculate-angle-of-touched-point-and-rotate-it-in-android