zoukankan      html  css  js  c++  java
  • 关于Touch的顺时针(CW),逆时针(CCW)旋转

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    
    /**
     * @author 麦子 2013.7.10
     */
    public class TouchRoundView extends View
    {
    
        private Paint paint = null; // 画笔
        private float px, py; // Touch 记录点
        private float angle = 0; // 记录全局旋转的角度
        private float[] touch = null; // 测试点
    
        public TouchRoundView(Context context)
        {
            super(context);
            this.init();
        }
    
        public TouchRoundView(Context context, AttributeSet attrs)
        {
            super(context, attrs);
            this.init();
        }
    
        private void init()
        {
            this.paint = new Paint();
            this.paint.setAntiAlias(true); // 抗锯齿
            this.paint.setStyle(Paint.Style.STROKE); // 设置为画线
        }
    
        @Override
        protected void onDraw(Canvas canvas)
        {
            canvas.drawColor(Color.WHITE); // 设置为白底
            float cx = this.getWidth() / 2;
            float cy = this.getHeight() / 2;
            canvas.drawCircle(cx, cy, 10, paint); // 中心点
            canvas.drawCircle(cx, cy, 200, paint); // 画圆
            if (this.touch != null)
            {
                canvas.drawLine(cx, cy, this.touch[0], this.touch[1], this.paint);
            } else
            {
                canvas.drawLine(cx, cy, cx, cy - 200, this.paint);
            }
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event)
        {
            int action = event.getAction();
            float x = event.getX(), y = event.getY();
            if (action == MotionEvent.ACTION_MOVE)
            {
                float cx = this.getWidth() / 2;
                float cy = this.getHeight() / 2;
                float angle1 = TouchRoundView.angle(cx, cy, this.px, this.py, cx, cy - 100);
                float angle2 = TouchRoundView.angle(cx, cy, x, y, cx, cy - 100);
                float tAngle1 = CWAngle(cx, cy, this.px, this.py, angle1);
                float tAngle2 = CWAngle(cx, cy, x, y, angle2);
                this.angle = this.angle + (tAngle2 - tAngle1);
                this.touch = getLocationFromPointRoundPointAngle(cx, cy - 200, cx, cy, this.angle);
            }
            this.px = x;
            this.py = y;
            this.postInvalidate();
            return true;
        }
    
        /**
         * 计算三点间的夹角 cx, cy (角顶点)
         * 
         * @param cx
         *            角顶点x坐标
         * @param cy
         *            角顶点y坐标
         */
        public static float angle(float cx, float cy, float fx, float fy, float sx, float sy)
        {
            float ma_x = fx - cx;
            float ma_y = fy - cy;
            float mb_x = sx - cx;
            float mb_y = sy - cy;
            float v1 = (ma_x * mb_x) + (ma_y * mb_y);
            float ma_val = (float) Math.sqrt(ma_x * ma_x + ma_y * ma_y);
            float mb_val = (float) Math.sqrt(mb_x * mb_x + mb_y * mb_y);
            float cosM = v1 / (ma_val * mb_val);
            float angle = (float) (Math.acos(cosM) * 180 / Math.PI);
            return angle;
        }
    
        /***
         * 第四象限 | 第一象限 <br>
         * ———————————————— <br>
         * 第三象限 | 第二象限 <br>
         * 
         * @param cx
         *            中心x坐标
         * @param cy
         *            中心y坐标
         * @param ax
         *            活动点x坐标
         * @param ay
         *            活动点y坐标
         * 
         * @param calDegree
         *            活动点与垂直方向上的夹角
         * 
         * @return 计算顺时针方向的角度(0~360)
         */
        public static float CWAngle(float cx, float cy, float ax, float ay, float calDegree)
        {
            calDegree %= 360; // 求模运算
            if (ax > cx && ay < cy)
            { // 第一象限
                return calDegree;
            } else if (ax > cx && ay >= cy)
            { // 第二象限
                return calDegree;
            } else if (ax < cx && ay >= cy)
            { // 第三象限
                return 360 - calDegree;
            } else if (ax < cx && ay < cy)
            { // 第四象限
                return 360 - calDegree;
            } else if (ax == cx && ay < cy)
            { // 垂直于中心点之上
                return 0;
            } else if (ax == cx && ay > cy)
            { // 垂直于中心点之下
                return 180;
            }
            return 0;
        }
    
        /**
         * 计算一个点绕另一个点旋转一个角度后的新位置
         * 
         * @param cx
         *            旋转点x坐标
         * @param cy
         *            旋转点y坐标
         */
        public static float[] getLocationFromPointRoundPointAngle(float x, float y, float cx, float cy, float angle)
        {
            float radians = (float) Math.toRadians(angle);
            float rx = (float) (Math.cos(radians) * (x - cx) - Math.sin(radians) * (y - cy) + cx);
            float ry = (float) (Math.sin(radians) * (x - cx) + Math.cos(radians) * (y - cy) + cy);
            return new float[] { rx, ry };
        }
    
    }

    PS:最近项目中可能会出现随着手指来旋转某个对象,在网上查了一些资料自己整理出来了,上面的三个静态方法是在网上搜索加上自己理解整理的,可以单独出来直接用。

  • 相关阅读:
    【万丈高楼平地起 第一季 链表是怎样链成的】
    【笔记——ASP.NET基础知识(一)】
    【万丈高楼平地起 第二季 队列和栈】
    【没有银弹No Silver Bullet】
    【简单示例:数据库表转XML】
    【软件工程小知识】
    【总结——SQL Server中的数据类型】
    【总结—.Net Framework集合类】
    【笔记——ASP.NET基础知识(二)】
    【总结——ASP.NET对象】
  • 原文地址:https://www.cnblogs.com/smile365/p/3182765.html
Copyright © 2011-2022 走看看