1

我有一个有趣的数学问题,我就是想不通。

我正在为 android 磨损构建表盘,需要根据时间计算出指针的旋转角度。

通常这很简单,但关键在于:指针不在时钟的中心。假设我有一个测量 10,10 的钟面,我的分针枢轴点位于 6,6(左下角为 0,0),我的时针位于 4,4。

我将如何计算出任何给定分钟的角度,以使该点始终指向正确的分钟?

谢谢

4

2 回答 2

1

好的,在 Nico 的回答的帮助下,我设法进行了调整并获得了一个工作示例。

需要合并的主要更改是更改 atan 计算的输入顺序以及由于 android 坚持将坐标系倒置而进行调整。

请在下面查看我的代码。

        //minutes hand rotation calculation
        int minute = mCalendar.get(Calendar.MINUTE);

        float minutePivotX = mCenterX+minuteOffsetX;
        //because of flipped coord system we take the y remainder of the full width instead
        float minutePivotY = mWidth - mCenterY - minuteOffsetY;

        //calculate target position
        double minuteTargetX = mCenterX + mRadius * Math.cos(ConvertToRadians(minute * 6));
        double minuteTargetY = mCenterY + mRadius * Math.sin(ConvertToRadians(minute * 6));

        //calculate the direction vector from the hand's pivot to the target
        double minuteDirectionX = minuteTargetX - minutePivotX;
        double minuteDirectionY = minuteTargetY - minutePivotY;

        //calculate the angle
        float minutesRotation = (float)Math.atan2(minuteDirectionY,minuteDirectionX );
        minutesRotation = (float)(minutesRotation * 360 / (2 * Math.PI));

        //do this because of flipped coord system
        minutesRotation = minutesRotation-180;

        //if less than 0 add 360 so the rotation is clockwise
        if (minutesRotation < 0)
        {
            minutesRotation = (minutesRotation+360);
        }


        //hours rotation calculations
        float hour = mCalendar.get(Calendar.HOUR);
        float minutePercentOfHour = (minute/60.0f);
        hour = hour+minutePercentOfHour;

        float hourPivotX = mCenterX+hourOffsetX;
        //because of flipped coord system we take the y remainder of the full width instead
        float hourPivotY = mWidth - mCenterY - hourOffsetY;

        //calculate target position
        double hourTargetX = mCenterX + mRadius * Math.cos(ConvertToRadians(hour * 30));
        double hourTargetY = mCenterY + mRadius * Math.sin(ConvertToRadians(hour * 30));

        //calculate the direction vector from the hand's pivot to the target
        double hourDirectionX = hourTargetX - hourPivotX;
        double hourDirectionY = hourTargetY - hourPivotY;

        //calculate the angle
        float hoursRotation = (float)Math.atan2(hourDirectionY,hourDirectionX );
        hoursRotation = (float)(hoursRotation * 360 / (2 * Math.PI));

        //do this because of flipped coord system
        hoursRotation = hoursRotation-180;

        //if less than 0 add 360 so the rotation is clockwise
        if (hoursRotation < 0)
        {
            hoursRotation = (hoursRotation+360);
        }

这还包括一个小的辅助函数:

public double ConvertToRadians(double angle)
{
    return (Math.PI / 180) * angle;
}

谢谢大家的帮助

于 2016-02-01T23:23:50.307 回答
0

只需根据方向矢量计算角度即可。

首先,计算目标位置。对于分针,这可能是:

targetX = radius * sin(2 * Pi / 60 * minutes)
targetY = radius * cos(2 * Pi / 60 * minutes)

然后计算从手的枢轴到目标的方向向量:

directionX = targetX - pivotX
directionY = targetY - pivotY

并计算角度:

angle = atan2(directionX, directionY)
于 2016-02-01T18:37:38.860 回答