Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rotate dial in limited degrees

All
I want rotate image in particular angle as like below image. I have code for rotation but it rotate 360 degree but I want it only for particular degrees and get the selected number which is upper side of dial.

enter image description here


below is my code. My custom View this work fine but lake of perfomance.

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector.OnGestureListener;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class MyDialView extends View implements OnGestureListener{
    private static Bitmap bimmap;
    private static Paint paint;
    private static Rect bounds;
    private int totalNicks = 100;
    private int currentNick = 0;
    private GestureDetector gestureDetector;
    private float dragStartDeg = Float.NaN;
    float dialerWidth = 0,dialerHeight = 0;

    private static Paint createDefaultPaint() {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        return paint;
    }
    private float xyToDegrees(float x, float y) {
        float distanceFromCenter = PointF.length((x - 0.5f), (y - 0.5f));
        if (distanceFromCenter < 0.1f
                || distanceFromCenter > 0.5f) { // ignore center and out of bounds events
            return Float.NaN;
        } else {
            return (float) Math.toDegrees(Math.atan2(x - 0.5f, y - 0.5f));
        }
    }
    public final float getRotationInDegrees() {
        return (360.0f / totalNicks) * currentNick;
    }

    public final void rotate(int nicks) {
        currentNick = (currentNick + nicks);
        if (currentNick >= totalNicks) {
            currentNick %= totalNicks;
        } else if (currentNick < 0) {
            currentNick = (totalNicks + currentNick);
        }
        Log.e("Current nick", String.valueOf(currentNick));
        if((currentNick > 80 || currentNick < 20)){
            invalidate();
        }
    }
    public MyDialView(Context context, AttributeSet attrs) {
        super(context, attrs);
        bimmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.out_round);
        paint = createDefaultPaint();
        gestureDetector = new GestureDetector(getContext(), this);
        dialerWidth = bimmap.getWidth() /2.0f;
        dialerHeight = bimmap.getHeight() / 2.0f;
        bounds = new Rect();
    }



    @Override
    protected void onDraw(Canvas canvas) {
        canvas.getClipBounds(bounds);
            canvas.save(Canvas.MATRIX_SAVE_FLAG);
            //{
                canvas.translate(bounds.left, bounds.top);

                float rotation = getRotationInDegrees();
                canvas.rotate(rotation, dialerWidth, dialerHeight);
                canvas.drawBitmap(bimmap, 0,0,null);
                //canvas.rotate(- rotation, dialerWidth, dialerHeight);
            //}     
            canvas.restore();
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (gestureDetector.onTouchEvent(event)) {
            return true;
        } else {
            return super.onTouchEvent(event);
        }
    }
    //Gesture detector methods
    @Override
    public boolean onDown(MotionEvent e) {
        float x = e.getX() / ((float) getWidth());
        float y = e.getY() / ((float) getHeight());

        dragStartDeg = xyToDegrees(x, y);
        //Log.d("deg = " , ""+dragStartDeg);
        if (! Float.isNaN(dragStartDeg)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY) {
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {

    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
            float distanceY) {
        if (! Float.isNaN(dragStartDeg)) {
            float currentDeg = xyToDegrees(e2.getX() / getWidth(), 
                    e2.getY() / getHeight());

            if (! Float.isNaN(currentDeg)) {
                float degPerNick = 360.0f / totalNicks;
                float deltaDeg = dragStartDeg - currentDeg;

                final int nicks = (int) (Math.signum(deltaDeg) 
                        * Math.floor(Math.abs(deltaDeg) / degPerNick));

                if (nicks != 0) {
                    dragStartDeg = currentDeg;
                    rotate(nicks);
                } 
            } 

            return true;
        } else {
            return false;
        }
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

}


I want 0-9 according to user selection & also allow user rotation to 0-9 not more rotation.

I have also check another code this is below.

dialer = (ImageView) findViewById(R.id.imageView_ring);
        dialer.setOnTouchListener(new MyOnTouchListener());
        dialer.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                // method called more than once, but the values only need to be initialized one time
                if (dialerHeight == 0 || dialerWidth == 0) {
                    dialerHeight = dialer.getHeight();
                    dialerWidth = dialer.getWidth();

                    // resize
                    Matrix resize = new Matrix();
                    resize.postScale((float)Math.min(dialerWidth, dialerHeight) / (float)imageOriginal.getWidth(), (float)Math.min(dialerWidth, dialerHeight) / (float)imageOriginal.getHeight());
                    imageScaled = Bitmap.createBitmap(imageOriginal, 0, 0, imageOriginal.getWidth(), imageOriginal.getHeight(), resize, false);

                    // translate to the image view's center
                    float translateX = dialerWidth / 2 - imageScaled.getWidth() / 2;
                    float translateY = dialerHeight / 2 - imageScaled.getHeight() / 2;
                    matrix.postTranslate(translateX, translateY);

                    dialer.setImageBitmap(imageScaled);
                    dialer.setImageMatrix(matrix);
                    Log.e("Rotation degree :"+rotationDegrees, String.valueOf(tickNumber));
                }
            }
        });

int tickNumber = 0;
    private void rotateDialer(float degrees) {

        //System.out.println("Rotation Done :: "+rotationDone);

       // if(!rotationDone) {

            this.rotationDegrees += degrees;
            this.rotationDegrees = this.rotationDegrees % 360;

            tickNumber = (int)this.rotationDegrees*100/360;
            // It could be negative
            if (tickNumber > 0) tickNumber = 100 - tickNumber;


            //this.rotationDegrees  = Math.abs(rotationDegrees);
            this.tickNumber = Math.abs(tickNumber);

           if(tickNumber  < 20 || tickNumber > 80){
               Log.e("Rotation degree :"+rotationDegrees, String.valueOf(tickNumber));
               matrix.postRotate(degrees, dialerWidth / 2, dialerHeight / 2);
               dialer.setImageMatrix(matrix);
           }

       // }
    }
    /**
     * @return The angle of the unit circle with the image view's center
     */
    private double getAngle(double xTouch, double yTouch) {

        double delta_x = xTouch - (dialerWidth) /2;
        double delta_y = (dialerHeight) /2 - yTouch;
        double radians = Math.atan2(delta_y, delta_x);

        double dx = xTouch - dWidth;
        double dy = (dHeight - ((dialerHeight) /2)) -  yTouch;
        double dRadi = Math.atan2(dy, dx);
        //Log.e("MY degree", String.valueOf( Math.toDegrees(dRadi)));
        //return Math.toDegrees(dRadi);
        return Math.toDegrees(radians);
    }



    /**
     * Simple implementation of an {@link OnTouchListener} for registering the dialer's touch events. 
     */
    private class MyOnTouchListener implements OnTouchListener {

        private double startAngle;

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:

                    // 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 rotationAngleRadians = Math.atan2(event.getX() - (dialer.getWidth() / 2 ),     ( (dialer.getHeight() / 2 ) - event.getY()));
                    double angle = (int) Math.toDegrees(rotationAngleRadians);
                    Log.i("gg", "rotaion angle"+angle);*/

                    double currentAngle = getAngle(event.getX(), event.getY());
                    //if(currentAngle < 130 || currentAngle < 110){
                        //Log.e("Start angle :"+startAngle, "Current angle:"+currentAngle);
                        rotateDialer((float) (startAngle - currentAngle));
                        startAngle = currentAngle;
                    //}


                    //Log.e("MOVE start Degree:"+startAngle, "Current Degree :"+currentAngle);
                    break;

                case MotionEvent.ACTION_UP:
                    //allowRotating = true;
                    break;
            }

            // set the touched quadrant to true
            //quadrantTouched[getQuadrant(event.getX() - (dialerWidth / 2), dialerHeight - event.getY() - (dialerHeight / 2))] = true;

            //detector.onTouchEvent(event);

            return true;
        }
    }
like image 775
Girish Bhutiya Avatar asked Dec 28 '12 09:12

Girish Bhutiya


1 Answers

I do not understand your problem. The code below rotate the image 48 degrees.

ImageView dialer = (ImageView) findViewById(R.id.imageView_ring);

int degrees = 48;
Matrix matrix = new Matrix();
matrix.setRotate(degrees);
Bitmap bmpBowRotated = Bitmap.createBitmap(imageOrginal, 0, 0, imageOrginal.getWidth(),imageOrginal.getHeight(), matrix, false);

dialer.setImageBitmap(bmpBowRotated);
like image 190
Simon Schubert Avatar answered Oct 20 '22 17:10

Simon Schubert