Android - 如何旋转图像

Android - How to spin the image

我有一张图片,它在 imageView 中。我想添加一个功能,允许用户在尝试将图像旋转到右侧时旋转图像 side.For 例如,如果用户尝试将图像旋转到左侧,它不会旋转。

这是我的转轮。

我尝试使用 GestureDetector 和 onFling 事件,但它不足以检测用户是否试图将其旋转到右侧或左侧。我该怎么做?

编辑:

            var normalVectorX = e2?.x!! - 515
            var normalVectorY = e2?.y!! - 515

            var tangentVectorX  = -normalVectorY
            var tangentVectorY = normalVectorX

            var tangentVectorLength = (Math.sqrt(Math.pow((515 - e2?.y!!).toDouble(), 2.0)) + Math.pow((e2?.x!! - 515).toDouble(), 2.0))

            var unitTangentX = tangentVectorX / tangentVectorLength
            var unitTangentY = tangentVectorY / tangentVectorLength

            var scalarProjection = (velocityX * unitTangentX) + (velocityY * unitTangentY)

            if (scalarProjection > 0) // Right Side
                spinWheel((spinCountX * 360).toFloat() + 360 - (mPrizeIndex * 60) , 12000)

这是基于answer伪代码的代码实现。 515 = 轮子的中心。

onFling 为您提供相应投掷手势的 MotionEvent。然后您可以调用 getX(int)getY(int) 来获取坐标。

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
  float x = e2.getX(0);  // Assuming you only care about the first finger
  float y = e2.getY(0);
  if (x < imageView.getWidth() / 2) {
    // fling is on the left side
  } else {
    // fling is on the right side
  }
}

旁注:我认为如果水平滑动,上面的代码会表现得不自然。如果你想让你的旋转手势更逼真,我认为你最好计算 tangential component.

编辑:这是计算切向分量的方法。

您需要计算触摸事件所在点圆的单位切线上的速度矢量 scalar projection

伪代码:

velocityVector = (velocityX, velocityY)
locationOfTouch = (e2.getX(0), e2.getY(0))
centerOfWheel = (166, 155)  # Measured from your image
normalVector = locationOfTouch - centerOfWheel
             = (locationOfTouch.x - centerOfWheel.x, locationOfTouch.y - centerOfWheel.y)

为了获得顺时针方向的切向量,我们采用 normalVector,交换 X 和 Y 分量,并对 X 取反(来自 2D Euclidean vector rotations)。

tangentVector = (-normalVector.y, normalVector.x)
unitTangent = tangentVector / tangentVector.length()

最后,你取点积得到标量投影:

scalarProjection = velocityVector.dotProduct(unitTangent)
                 = (velocityVector.x * unitTangent.x) + (velocityVector.y * unitTangent.y)

如果scalarProjection为正数,表示滑动手势为顺时针方向。如果为负数,则表示手势为逆时针方向。

作为奖励,由于我们使用了单位切线,因此生成的标量投影也代表顺时针方向的投掷速度,因此您可以将旋转动画更改得更快或更慢,或者设置一个阈值,例如那个方向的小速度不会触发轮子旋转。