在Android中计算触摸点的角度并旋转它

发布于 2024-12-12 12:44:45 字数 589 浏览 0 评论 0原文

数学再次打败了我。这是一个如此简单的任务,但我无法完成它。

场景:我在 SurfaceView 上绘制圆形图像。用户触摸图像边框上的一个点并开始将其拖动。我需要根据用户的移动旋转圆形图像。 我有两个重要的信息,图像中心 X、Y 坐标和触摸点坐标。

在此处输入图像描述

正如你在图像中看到的,用户触摸了一个点,根据我绘制的触摸点角度应该是40左右。我无法正确计算它。

我尝试使用这个公式:

angle = Math.atan2(touchedY - centerY, touchedX - centerX) * 180 / Math.PI 

我无法理解应该如何计算角度,就像现在一样,它无法正常工作并且值不好。例如,在图像的情况下,角度计算为-50。

感谢您的宝贵时间,我们很乐意接受任何信息。

LE:实际上我认为我犯了一个错误,如下所述。圆圈应该是这样的:

在此处输入图像描述

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.

enter image description here

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:

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

匿名。 2024-12-19 12:44:46
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
}

其中 touchX = event.getX 且 touchY = event.getY

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

爱的十字路口 2024-12-19 12:44:46

这是两点之间的角度,以度为单位

angle = (Math.atan2(y2-y1,x2-x1) *180 / Math.PI)

this for angle betweet two point in Degree

angle = (Math.atan2(y2-y1,x2-x1) *180 / Math.PI)

浅暮の光 2024-12-19 12:44:45

让我们重新表述这个问题:您想要找到两个向量之间的角度。第一个向量是从中心点 (u) 直线向上的上向量,第二个向量是从中心点到触摸点的向量 (v) 。

现在我们可以回忆一下(或谷歌)

cos a = uv / (|u|*|v|)

其中a是向量和 |u|是向量的长度。上向量 u 为 (0, 1),长度为 1。

手动相乘向量会抵消 x 项,得到如下结果。

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);

请注意如何通过从触摸点减去中心点来获得 v 向量。如果需要,请记住转换为度数。

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.

吃→可爱长大的 2024-12-19 12:44:45

首先,旋转角度应由CenterX和CenterY的原点确定。
所以你的(touchedY - centerY,touchedX - centerX)应该是(centerY -touchedY,centerX -touchedX)。

正确答案可能是:

(int) (Math.toDegrees(Math.atan2(centerY - touchedY, centerX - touchedX)));

希望有帮助

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

朕就是辣么酷 2024-12-19 12:44:45

一个角度需要 3 个点。你只有 2 个(中心和触摸)。
选择一个固定的第三点,例如图片中 90 处的点,然后使用 @vidstige 的答案来找到您的方程。

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.

心凉 2024-12-19 12:44:45

我尝试了很多事情来执行类似的操作,并附带以下内容:

它获取视图位置而不是屏幕中心,但您可以调整它:

基于触摸点旋转图像视图:

     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);

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文