0

I have an image and its in imageView. I want to add a functionally that allows users to spin the image if they try to spin it to the right side.For example if user tries to spin it to the left side, it doesnt spin.

enter image description here

This is my spinwheel.

I tried to use GestureDetector and onFling event but it wasn't enough for me to detect if user tries to spin it to the right side or left side. How can i do this ?

Edit:

            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)

This is the code implementation based on the pseudo code of answer. 515 = center of the wheel.

ahmetnecdeto
  • 69
  • 1
  • 1
  • 7

1 Answers1

2

onFling gives you the MotionEvents of the corresponding fling gesture. You can then call getX(int) and getY(int) to get the coordinates.

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

Side note: I think the code above will behave unnaturally if the fling is horizontal. If you want your spin gesture to be more realistic, I think you will be better off calculating the tangential component.

Edit: Here's how you would calculate the tangential component.

You would want to calculate the scalar projection of the velocity vector on the unit tangent of the circle at the point where the touch event is.

Pseudo code:

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)

To get the clockwise tangent vector, we take the normalVector, swap the X and Y components, and negate the X (from 2D Euclidean vector rotations).

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

Finally, you take the dot product to get the scalar projection:

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

If scalarProjection is positive, that means the fling gesture is in the clockwise direction. If it is negative, that means the gesture is in anti-clockwise direction.

As a bonus, since we used the unit tangent, the resulting scalar projection also represents how fast the fling is in the clockwise direction, so you can change the spin animation to be faster or slower, or set a threshold such that a small velocity in that direction doesn't trigger the wheel to spin.

enter image description here

Maurice Lam
  • 1,577
  • 9
  • 14
  • I tried this approach but i didn't work like how i want. Because of its circle, in some situations user can start spinning at X = 360 and finish at X = 180 but still trying to spin to right side. – ahmetnecdeto Jan 03 '21 at 20:04
  • Right, that is what I was trying to say in the side note. Have you tried calculating the tangential component of the fling? – Maurice Lam Jan 03 '21 at 20:33
  • I couldn't find a formula which calculates a variable that shows me which way user spinned the wheel by using Y2-Y1 and X2-X1 values. – ahmetnecdeto Jan 03 '21 at 20:53
  • I have added an explanation and some pseudocode of how to calculate the "scalar projection", which shows which way the user spinned the wheel. Hope it helps! – Maurice Lam Jan 03 '21 at 21:49