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