2016-02-01 8 views
1

У меня есть интересная математическая проблема, которую я просто не могу понять.Расчет угловых углов стрелки

Я создаю лицо для часов для износа андроида и вам нужно разработать угол поворота для рук на основе времени.

Обычно это было бы просто, но вот кикер: руки не являются центральными на часах. Допустим, у меня есть циферблат, который измеряет 10,10 Моя минутная точка поворота составляет 6,6 (внизу слева 0,0), а моя часовая стрелка находится на 4,4.

Как бы я мог определить угол в любую минуту, чтобы точка всегда указывала на правильную минуту?

Thanks

+0

Может быть, я неправильно ваш ответ, но если вы говорите, просто применить руку смещения после этого, то точка не будет нацелена на правильный номер в конце. например, 12 вечера. вращение будет 0, а затем после смещения рук подсказки будут указывать либо прямо справа от 12, либо просто слева – doodlleus

ответ

1

Ok, с помощью ответа Нико мне удалось сделать хитрости и получить рабочий пример.

Основные изменения, которые необходимо было включить, заключались в изменении порядка входов на вычисление atan, а также в создании настроек из-за настойчивости андроида, чтобы система координат перевернулась.

См. Мой код ниже.

 //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; 
} 

Спасибо за вашу помощь все

+0

Где я могу получить минутуOffsetX и minuteOffsetY? Или вы можете дать нам полную функцию onDraw? –

+1

2 смещения - это количество в пикселях от центра. По умолчанию обе руки будут на 0,0 – doodlleus

+0

Спасибо ... и mRadius? –

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)