我正在尝试编写一个简单的概念验证应用程序,允许用户旋转时钟的分针。我很难为OnTouchEvent提供正确的逻辑。
到目前为止,我有以下代码:
public boolean onTouchEvent(MotionEvent e) {
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_MOVE:
//find an approximate angle between them.
float dx = x-cx;
float dy = y-cy;
double a=Math.atan2(dy,dx);
this.degree = Math.toDegrees(a);
this.invalidate();
}
return true;
}
protected void onDraw(Canvas canvas) {
super .onDraw(canvas);
boolean changed = mChanged;
if (changed) {
mChanged = false;
}
int availableWidth = getRight() - getLeft();
int availableHeight = getBottom() - getTop();
int x = availableWidth / 2;
int y = availableHeight / 2;
cx = x;
cy = y;
final Drawable dial = mDial;
int w = dial.getIntrinsicWidth() + 100;
int h = dial.getIntrinsicHeight() + 100;
boolean scaled = false;
if (availableWidth < w || availableHeight < h) {
scaled = true;
float scale = Math.min((float) availableWidth / (float) w, (float) availableHeight / (float) h);
canvas.save();
canvas.scale(scale, scale, x, y);
}
if (changed)
{
dial.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2));
}
dial.draw(canvas);
canvas.save();
float hour = mHour / 12.0f * 360.0f;
canvas.rotate(hour, x, y);
final Drawable hourHand = mHourHand;
if (changed) {
w = hourHand.getIntrinsicWidth() + 30;
h = hourHand.getIntrinsicHeight() + 30;
hourHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2));
}
hourHand.draw(canvas);
canvas.restore();
canvas.save();
float minute = mMinutes / 60.0f * 360.0f;
if (bearing == 0)
{
canvas.rotate(minute, x, y);
}
else
{
canvas.rotate((float)bearing, x, y);
}
final Drawable minuteHand = mMinuteHand;
if (changed) {
w = minuteHand.getIntrinsicWidth() + 30;
h = minuteHand.getIntrinsicHeight() + 30;
minuteHand.setBounds(x - w, y - h, x + w, y + h);
}
minuteHand.draw(canvas);
canvas.restore();
if (scaled) {
canvas.restore();
}
}
然后基于此,我的OnDraw方法将分针旋转到指定的“this.degree”(只调用canvas.rotate)。我假设我的数学不在这里。我试着按照这里的例子:Calculate angle for rotation in Pie Chart,但仍然没有正确旋转分针。任何帮助,将不胜感激。
答案 0 :(得分:2)
数学看起来正确。你的计算应该给你触摸事件的角度,在中心点的正确右侧的触摸应该给你0度。
需要注意的一些事项
Canvas.rotate(float, float, float)
方法,或单独添加其他翻译,以确保绕正确的点旋转。没有任何翻译,它将围绕(0,0)(视图的左上角)旋转更多关于轮换: 旋转总是发生在“当前”(0,0)点附近。 “当前”是指当前矩阵应用后的(0,0)点。首次输入onDraw时,(0,0)点应该是视图的左上角。每当您应用平移/缩放/等时,您可能会相对于视图更改(0,0)点的位置。
我认为在设置正确的旋转中心方面,以下内容应该有效:
//first we save the initial matrix, so we can easily get
//back to this state after we're done rotating
canvas.save();
//I *think* you need to negate the center offsets here,
//because you are conceptually moving the canvas, rather
//than moving the center directly
canvas.translate(-cx, -cy);
//<perform the rotation and draw the clock hand>
//...
//and now restore the matrix back to the initial state
canvas.restore();
答案 1 :(得分:0)
您的计算适用于测量分钟指针的角度 在模拟时钟的相应象限中旋转......这里很少 位变化可以使分钟或小时的手在旋转 触摸位置....在onTouch()方法中调用以下方法进行动作移动
public float getRotationAngle(float x, float y) {
float dx = x - cx;
float dy = y - cy;
double a = Math.atan2(dy, dx);
double degree = Math.toDegrees(a)+90;
if(angle<0){
degree=degree+360;
}
return (float) degree;
}
我有这种方法用于计算角度的矢量概念,但如果你想要的话,如果你想要的话,我会给出那个逻辑....