如何正确地重绘从圆圈开始的角度,从当前时间开始到圆圈受影响的点?

时间:2013-09-05 21:38:44

标签: android math geometry android-canvas

我在画布上画了一个圆圈。在这个圆圈的顶部,我绘制一个角度,该角度从圆的一部分开始,等于当前时间。

然后在onTouchEvent中,角度应该从起点(当前时间)重新绘制到终点,基于圆圈上的一个点。

问题在于onTouchEvent方法中计算动态扫描角度。

我尝试过不同的计算,取自不同的Stackoverflow帖子/建议,没有一个根据我的期望不起作用。角度onTouchEvent的反应总是有点不可预测。

我的代码段:

@Override
public void draw(Canvas canvas) {
    super.draw(canvas);

    int radius = getRadius();
    int startAngle = getStartAngle();

    canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, this.bkgPaint);

    this.arcRect = new RectF((getWidth() / 2) - radius, (getHeight() / 2) - radius, (getWidth() / 2) + radius, (getHeight() / 2) + radius);
    canvas.drawArc(this.arcRect, startAngle, sweepAngle, true, arcPaint);
}

@Override
public boolean onTouchEvent(MotionEvent e) {
    if (e.getAction() == MotionEvent.ACTION_MOVE) {
        sweepAngle = (int) ((360.0D + Math.toDegrees(Math.atan2(e.getX() - 360.0D, 360.0D - e.getY()))) % 360.0D);
        invalidate();
    }
    return true;
}

private int getStartAngle() {
    Calendar cal = Calendar.getInstance();
    int minutes = cal.get(Calendar.HOUR_OF_DAY) * 60 + cal.get(Calendar.MINUTE);
    if (minutes > 720) {
        minutes -= 720;
    }
    int angle = minutes / 2;
    return (angle += 270) % 360;
}

private int getRadius() {
    return ((80 * getWidth()) / 100) / 2;
}

1 个答案:

答案 0 :(得分:2)

我在颜色选择器中使用了类似的计算方法。它是开源的,您可以找到来源here

在你的情况下,我将从计算结束角度开始,如下所示:

@Override
public boolean onTouchEvent(MotionEvent e) {
    int action = e.getAction();
    switch (action) {
    case MotionEvent.ACTION_DOWN:
    case MotionEvent.ACTION_MOVE:

        int x = (int) e.getX();
        int y = (int) e.getY();
        int cx = x - getWidth() / 2;
        int cy = y - getHeight() / 2;

        endAngle = (float) (Math.toDegrees(Math.atan2(cy, cx)) + 360f) % 360f;

        invalidate();

        return true;
    }
    return super.onTouchEvent(e);
}

需要使用模数添加360度。完成此操作后,圆圈右侧为0度,底部为90度,左侧为180度,顶部为270度。

现在你的扫掠角度为endAngle - startAngle。就是这样!