【问题标题】:Calculate angle of touched point and rotate it in Android计算触摸点的角度并在Android中旋转
【发布时间】:2011-10-28 08:26:56
【问题描述】:

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

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

如图所示,用户触摸了一个点,根据我的绘制,触摸点的角度应该在 40 度左右。我无法正确计算。

我尝试使用这个公式:

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

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

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

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

【问题讨论】:

  • 为什么你有0向北?

标签: android math geometry atan2


【解决方案1】:

让我们重新表述问题:您想找到两个向量之间的角度。第一个向量是从你的中心点(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 向量。如果需要,记得转换成度数。

【讨论】:

  • upvector 不应被假定为直线上升。
  • 嗯,这就是 OP 想要的。我把它作为一个练习来创建一个用任意向上向量计算角度的函数。
  • Math.acos 返回半圆角,考虑使用Math.atan2
  • 是的,五年后我再次阅读他的问题,他应该旋转并限制到 360 以获得预期值。
【解决方案2】:

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

而正确的答案可能是:

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

希望对你有帮助

【讨论】:

  • 考虑到第二张图像,使用您的公式,当我点击 TouchedXY 点时,返回的角度为:130...
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    我尝试了很多事情来做类似的事情并得到了这个:

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

    根据触摸点旋转图像视图:

         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
      }
      

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

      【讨论】:

        【解决方案6】:

        表示两点之间的角度,单位为度

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

        【讨论】:

          猜你喜欢
          • 2014-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-18
          • 1970-01-01
          • 1970-01-01
          • 2014-11-18
          • 2013-03-04
          相关资源
          最近更新 更多