我有一个有趣的数学问题,我就是想不通。
我正在为 android 磨损构建表盘,需要根据时间计算出指针的旋转角度。
通常这很简单,但关键在于:指针不在时钟的中心。假设我有一个测量 10,10 的钟面,我的分针枢轴点位于 6,6(左下角为 0,0),我的时针位于 4,4。
我将如何计算出任何给定分钟的角度,以使该点始终指向正确的分钟?
谢谢
好的,在 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;
}
谢谢大家的帮助
只需根据方向矢量计算角度即可。
首先,计算目标位置。对于分针,这可能是:
targetX = radius * sin(2 * Pi / 60 * minutes)
targetY = radius * cos(2 * Pi / 60 * minutes)
然后计算从手的枢轴到目标的方向向量:
directionX = targetX - pivotX
directionY = targetY - pivotY
并计算角度:
angle = atan2(directionX, directionY)