Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determin the final position or angle of a rotated Image

Tags:

java

android

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 enter image description here

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);




}
like image 579
huskyd97 Avatar asked Nov 11 '22 07:11

huskyd97


1 Answers

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.

like image 159
Sipty Avatar answered Nov 14 '22 22:11

Sipty