您的位置:首页 > 其它

根据圆心坐标以及手指坐标计算圆上点的位置

2018-03-05 16:52 344 查看
前些天朋友让我帮忙做一个功能“根据图上的点获取相应的颜色”,点是可拖动的,并且是以圆的形式做规律运动的,以前也没做过,所以想了很多方法都没实现,最后参考了别人的以角度算位置才算解决了。先说说需求在内圆或外圆中有个点,可以拖动,点一直在两条线的中间位置。解决方案,自定义view继承ImageView,以中心点坐标和手指坐标计算夹角,以夹角计算点的位置。@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {//获得初始效果super.onLayout(changed, left, top, right, bottom);
//获取中心点坐标
centerX = getWidth()/2;
centerY = getHeight()/2;
//获取半径
r = (getWidth()/2)-((getWidth()/2)/((ceng+1)*2)+30);
//初始化手指坐标点
X = centerX-50;
Y = centerY+500;
//通过手指坐标点和中心点获取初始点的位置
dianY = (int) (r + (r) * Math.cos(Math.PI * (getRotationBetweenLines(centerX,centerY,X,Y)) / 180));
dianY = (int) (r + (r) * Math.sin(Math.PI * (getRotationBetweenLines(centerX,centerY,X,Y)) / 180));
//修改手指初始点的位置
X = dianY;
Y = dianY;
//设置拖动监听
setOnTouchListener(this);
}
/**
*获取两条线的夹角   本方法为往上拷贝的方法,验证可以使用
* @param centerX
* @param centerY
* @param xInView
* @param yInView
* @return
*/
public static int getRotationBetweenLines(float centerX, float centerY, float xInView, float yInView) {
double rotation = 0;

double k1 = (double) (centerY - centerY) / (centerX * 2 - centerX);
double k2 = (double) (yInView - centerY) / (xInView - centerX);
double tmpDegree = Math.atan((Math.abs(k1 - k2)) / (1 + k1 * k2)) / Math.PI * 180;

if (xInView > centerX && yInView < centerY) {  //第一象限
rotation = 90 - tmpDegree;
} else if (xInView > centerX && yInView > centerY) //第二象限
{
rotation = 90 + tmpDegree;
} else if (xInView < centerX && yInView > centerY) { //第三象限
rotation = 270 - tmpDegree;
} else if (xInView < centerX && yInView < centerY) { //第四象限
rotation = 270 + tmpDegree;
} else if (xInView == centerX && yInView < centerY) {
rotation = 0;
} else if (xInView == centerX && yInView > centerY) {
rotation = 180;
}

return (int) rotation;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()){
case MotionEvent.ACTION_DOWN://获取手指按下坐标并根据坐标和点的位置判断本次操作是否有效
if (event.getX()<dianX-100||event.getX()>dianX+100||event.getY()<dianY-100||event.getY()>dianY+100){//判断本次拖动是否有效
t=true;
break;
}
X = (int)event.getX();
Y = (int)event.getY();
break;
case MotionEvent.ACTION_MOVE:
if (t){
break;
}
X = (int)event.getX();
Y = (int)event.getY();
if (ceng == 2){//因为图可能会有两层颜色所以才加了这个判断,进入内圈修改半径就可以了
if (X>getWidth()/4&&X<getWidth()-(getWidth()/4)&&Y>getWidth()/4&&Y<getWidth()-(getWidth()/4)){
r = (getWidth()/2)-((getWidth()/2)/((ceng+1))+30+(getWidth()/2)/((ceng+1)*2));
}else {
r = (getWidth()/2)-((getWidth()/2)/((ceng+1)*2)+30);
}
}
invalidate();//刷新view实现拖动效果,刷新时主要是调用了view的onDraw方法
break;
case MotionEvent.ACTION_UP:
t=false;
break;
}
return true;
}
上面代码为页面初始数据设置
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//获取夹角度数
int dushu = getRotationBetweenLines(centerX,centerY,X,Y)-90;
//根据夹角获取点的坐标
dianX = (int) (centerX + (r) * Math.cos(Math.PI * dushu / 180));
dianY = (int) (centerY + (r) * Math.sin(Math.PI * dushu / 180));
Paint paint = new Paint();
paint.setAntiAlias(false);
paint.setColor(Color.RED);
//将点画在view上
canvas.drawCircle( dianX, dianY, 10, paint);
//获取颜色可以写在这里,把接口的方法改一下或者加一个方法就好了
if (rotation != null){//这是接口方便做下一步操作
rotation.Rotation(dushu);
}
}
本文中主要代码为getRotationBetweenLines内的代码获取到了夹角的度数。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐