0

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

然后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;
}
4

1 回答 1

2

我在我的颜色选择器中使用了类似的计算。它是开源的,你可以在这里找到源代码。

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

@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。就是这样!

于 2013-09-07T13:48:56.437 回答