Android - Как повернуть изображение

У меня есть изображение и оно находится в imageView. Я хочу добавить функцию, которая позволяет пользователям вращать изображение, если они пытаются повернуть его вправо. Например, если пользователь пытается повернуть его влево, оно не вращается.

введите здесь описание изображения

Это моя вертушка.

Я пытался использовать 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)

Это реализация кода, основанная на псевдокоде ответа. 515 = центр колеса.


person uguro    schedule 03.01.2021    source источник


Ответы (1)


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
  }
}

Примечание: я думаю, что приведенный выше код будет вести себя неестественно, если бросок будет горизонтальным. Если вы хотите, чтобы ваш жест вращения был более реалистичным, я думаю, вам лучше рассчитать тангенциальный компонент.

Редактировать: Вот как вы можете рассчитать тангенциальную составляющую.

Вам нужно рассчитать скалярную проекцию вектора скорости на единичную касательную окружности в точке точка, в которой произошло событие касания.

Псевдокод:

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 евклидово векторное вращение).

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

Наконец, вы берете скалярное произведение, чтобы получить скалярную проекцию:

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

Если scalarProjection положительное, это означает, что жест бросания выполняется по часовой стрелке. Если он отрицательный, это означает, что жест направлен против часовой стрелки.

В качестве бонуса, поскольку мы использовали единичный тангенс, результирующая скалярная проекция также показывает, насколько быстро происходит бросок по часовой стрелке, поэтому вы можете изменить анимацию вращения, чтобы она была быстрее или медленнее, или установить порог, чтобы небольшая скорость в это направление не приводит к вращению колеса.

введите здесь описание изображения

person maurice    schedule 03.01.2021
comment
Я пробовал этот подход, но я не работал так, как хочу. Из-за его круга в некоторых ситуациях пользователь может начать вращение на X = 360 и закончить на X = 180, но все еще пытается вращаться в правую сторону. - person uguro; 03.01.2021
comment
Правильно, это то, что я пытался сказать в примечании. Вы пытались рассчитать тангенциальную составляющую броска? - person maurice; 03.01.2021
comment
Я не смог найти формулу, которая вычисляет переменную, которая показывает мне, как пользователь вращал колесо, используя значения Y2-Y1 и X2-X1. - person uguro; 03.01.2021
comment
Я добавил объяснение и некоторый псевдокод того, как вычислить скалярную проекцию, которая показывает, в какую сторону пользователь крутил колесо. Надеюсь, поможет! - person maurice; 04.01.2021