【问题标题】:Offset Clock Hands Angle Calculation偏移时钟指针角度计算
【发布时间】:2016-02-02 07:23:50
【问题描述】:

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

我正在为 Android Wear 制作表盘,需要根据时间计算出指针的旋转角度。

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

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

谢谢

【问题讨论】:

  • 也许我误解了你的答案,但如果你说之后只应用手偏移量,那么重点就不会指向最后的正确数字。以中午 12 点为例。旋转为 0,然后在偏移手后,尖端将指向 12 的右侧或左侧

标签: math clock angle watchface


【解决方案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;
}

感谢大家的帮助

【讨论】:

  • 从哪里获得 minuteOffsetX 和 minuteOffsetY?或者你能给我们完整的onDraw函数吗?
  • 2 个偏移量是距中心的像素量。默认情况下,双手都在 0,0
  • 谢谢...还有 mRadius?
  • 表盘半径
【解决方案2】:

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

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

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

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

directionX = targetX - pivotX
directionY = targetY - pivotY

并计算角度:

angle = atan2(directionX, directionY)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多