I have an ImageView of a Wheel that is spinning on Fling. How can I detect the final position of the wheel when the rotation is complete? basically , similar to a wheel of fortune wheel, result depends on where the wheel stopped
Is there a way to detect when the fling/rotation is finished , then get the final angle? I want to associate this angle with one of the 4 quadrants in the circle and set a result from that. Thanks, some of my code below //////////////////////////Gesture Detect /////////////////
private class MyWheelOnTouchListener implements OnTouchListener {
private double startAngle;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
rotateAnim(); // test
// reset the touched quadrants
for (int i = 0; i < quadrantTouched.length; i++) {
quadrantTouched[i] = false;
}
allowRotating = false;
startAngle = getAngle(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
double currentAngle = getAngle(event.getX(), event.getY());
rotateDialer((float) (startAngle - currentAngle));
startAngle = currentAngle;
break;
case MotionEvent.ACTION_UP:
allowRotating = true;
break;
}
// set the touched quadrant to true
quadrantTouched[getQuadrant(event.getX() - (wheelWidth / 2), wheelHeight - event.getY() - (wheelHeight / 2))] = true;
wheeldetector.onTouchEvent(event);
return true;
}
}
/**
* Simple implementation of a {@link SimpleOnGestureListener} for detecting a fling event.
*/
private class MyWheelGestureDetector extends SimpleOnGestureListener {
private double endAngle;
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// get the quadrant of the start and the end of the fling
int q1 = getQuadrant(e1.getX() - (wheelWidth / 2), wheelHeight - e1.getY() - (wheelHeight / 2));
int q2 = getQuadrant(e2.getX() - (wheelWidth / 2), wheelHeight - e2.getY() - (wheelHeight / 2));
// the inversed rotations
if ((q1 == 2 && q2 == 2 && Math.abs(velocityX) < Math.abs(velocityY))
|| (q1 == 3 && q2 == 3)
|| (q1 == 1 && q2 == 3)
|| (q1 == 4 && q2 == 4 && Math.abs(velocityX) > Math.abs(velocityY))
|| ((q1 == 2 && q2 == 3) || (q1 == 3 && q2 == 2))
|| ((q1 == 3 && q2 == 4) || (q1 == 4 && q2 == 3))
|| (q1 == 2 && q2 == 4 && quadrantTouched[3])
|| (q1 == 4 && q2 == 2 && quadrantTouched[3])) {
wheel.post(new FlingWheelRunnable(-1 * (velocityX + velocityY)));
} else {
// the normal rotation
wheel.post(new FlingWheelRunnable(velocityX + velocityY));
}
endAngle = getAngle(e1.getX(), e2.getY());
return true;
}
}
/**
* A {@link Runnable} for animating the the dialer's fling.
*/
private class FlingWheelRunnable implements Runnable {
private float velocity;
public FlingWheelRunnable(float velocity) {
this.velocity = velocity;
}
@Override
public void run() {
if (Math.abs(velocity) > 5) { // original = 5
rotateDialer(velocity / 100); // original = 75
velocity /= 1.0666F; // original = 1.0666F
wheel.getRotation()); <-- maybe something like this, but not working??
// post this instance again
wheel.post(this);
}
}
}
/**
* @return The angle of the unit circle with the image view's center
*/
private double getAngle(double xTouch, double yTouch) {
double x = xTouch - (wheelWidth / 2d);
double y = wheelHeight - yTouch - (wheelHeight / 2d);
switch (getQuadrant(x, y)) {
case 1:
return Math.atan(y / x) * 180 / Math.PI;
case 2:
return 180 - Math.atan(y / x) * 180 / Math.PI;
case 3:
return 180 + (-1 * Math.atan(y / (x)) * 180 / Math.PI);
case 4:
return 360 + Math.atan(y / (x)) * 180 / Math.PI;
default:
return 0;
}
}
/**
* @return The selected quadrant.
*/
private static int getQuadrant(double x, double y) {
if (x >= 0) {
return y >= 0 ? 1 : 4;
} else {
return y >= 0 ? 2 : 3;
}
}
/**
* Rotate the wheel.
*
* @param degrees The degrees, the dialer should get rotated.
*/
private void rotateDialer(float degrees) {
matrix.postRotate(degrees, wheelWidth / 2, wheelHeight / 2);
wheel.setImageMatrix(matrix);
}
I'm not sure this would be compatible with your current implementation, but have you tried detecting the color of the final wheel? All you need to do is load it with BitmapFactory:
Bitmap slice = BitmapFactory.decodeFile();
// just go through the documentation
// to find the easiest, for you, way to load it
Then just take out a pixel:
int slicePixel = slice.getPixel(0, 0);
And finally detect the color:
int red = Color.red(slicePixel);
int blue = Color.blue(slicePixel);
int green = Color.green(slicePixel);
Hopefully this would be helpful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With