Установите аналоговые часы на время жестами, касаясь минутной стрелки по часовой стрелке или против часовой стрелки
Я застрял, пытаясь создать класс, позволяющий пользователям устанавливать аналоговые часы вовремя. Они должны перемещать минутную стрелку, а не часовую стрелку, по часовой стрелке или против часовой стрелки, чтобы установить текущее время. Часовая стрелка перемещается в соответствии с ходом минутной стрелки, но я не могу правильно перемещать часовую стрелку. Он не имеет плавного движения каждый раз, когда проходит через двенадцать и шесть часов, где есть критические точки угла.
Это моя тренировка до этого момента. В двенадцать часов угол равен 0 градусам, минимальный угол курса, а в шесть часов угол равен 180 градусам, максимальный угол. Итак, с двенадцати до шести (по часовой стрелке) у нас положительные углы (0,180), а с шести до двенадцати (по часовой стрелке) у нас отрицательные углы (-180,0). Это нормально, но если я хочу вычислить правильное положение часовой стрелки в соответствии с ходом минутной стрелки, я должен перевести эти углы в диапазон 0-360 градусов.
Вот где я обращаюсь с жестами:
@Override
public boolean onTouch(View v, MotionEvent event) {
// Clock is the clock sphere and the minutes hand.
final float xc = clock.getTranslationX() + (clock.getWidth() / 2);
final float yc = clock.getTranslationY() + (clock.getHeight() / 2);
final float x = event.getX();
final float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
clock.clearAnimation();
mMinutesCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
break;
case MotionEvent.ACTION_MOVE:
/**
* Translate angles from [-179,179] to [0,360] to be able to move
* hours hand properly.
*/
// Start Angle
mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
mMinutesPrevAngle = mMinutesCurrAngle;
// Finish angle
mMinutesCurrAngle = Math.toDegrees(Math.atan2(event.getX() - xc, yc - event.getY()));
mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
if ((mMinutesCurrAngle > mMinutesPrevAngle)) {
// Clockwise between 12 and 6
mHoursCurrAngle = mLastSpinHoursAngle + (mMinutesCurrAngle / 12);
} else if ((mMinutesCurrAngle < mMinutesPrevAngle)) {
// counter-Clockwise between 6 and 12
mHoursCurrAngle = mLastSpinHoursAngle + (mMinutesCurrAngle / 12);
} else if ((mMinutesCurrAngle > mMinutesPrevAngle) && (mMinutesCurrAngle < 0)) {
// Clockwise between 6 and 12
mHoursCurrAngle = mLastSpinHoursAngle + (- mMinutesCurrAngle / 12);
} else if ((mMinutesCurrAngle < mMinutesPrevAngle) && (mMinutesCurrAngle < 0)) {
// counter-Clockwise between 6 and 12
mHoursCurrAngle = mLastSpinHoursAngle + (mMinutesCurrAngle / 12);
}
newSpin();
// Transelate angles to the original format to represent them properly.
mMinutesPrevAngle = translate360Angle(mMinutesPrevAngle);
mMinutesCurrAngle = translate360Angle(mMinutesCurrAngle);
animate(clock, mMinutesPrevAngle, mMinutesCurrAngle, 0);
animate(hour, mHoursPrevAngle, mHoursCurrAngle, 0);
mHoursPrevAngle = mHoursCurrAngle;
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
Вот где я перевожу углы:
/**
* Translate angles from [-179,179] to [0,360] to be able to move
* hours hand properly.
* @param minutesAngle
* @return
*/
private double set360Angle(double angle) {
if (angle < 0) return (360 + angle);
else return angle;
}
/**
* Transelate angles to the original format to represent them properly.
* @param angle
* @return
*/
private double translate360Angle(double angle) {
if (angle > 180) return (-360 + angle);
else return angle;
}
И вот где я знаю, если минутная стрелка начинает новый спин:
private void newSpin() {
if (translate360Angle(mMinutesPrevAngle) < 0 && translate360Angle(mMinutesCurrAngle) > 0) {
// New Spin clockwise
// I must remember hour hand angle
mLastSpinHoursAngle = mHoursPrevAngle;
} else if (translate360Angle(mMinutesPrevAngle) > 0 && translate360Angle(mMinutesCurrAngle) < 0) {
// New Spin counter-clockwise
// I must remember hour hand angle
mLastSpinHoursAngle = mHoursPrevAngle;
}
}
Кто-нибудь может мне немного помочь? если кто-нибудь может мне помочь, я обещаю назвать ваше имя моей первой нерожденной дочери... шучу.
1 ответ
Я обнаружил, где проблема была...
Проблема заключалась в "условиях if" внутри метода newSpin(). Здесь, перед проверкой условий, я перевел углы в исходный формат (от 0 градусов до 180 градусов для двенадцати часов до шести часов по часовой стрелке и от -180 градусов до 0 градусов для шести часов до двенадцати градусов). часов, по часовой стрелке тоже). Таким образом, вместо этого проверьте, запускает ли пользователь новое вращение минутной стрелкой. Он добавляет / вычитает новое вращение каждый раз, когда пользователь проходит через шесть часов вместо двенадцати.
Итак, я исправил это, изменив эти условия и проверив оба угла минутной стрелки, предыдущий и текущий, в формате 360 градусов. Теперь, если предыдущий угол больше 355 градусов, а текущий угол меньше 5 градусов, я добавляю новый спин в mSpinNumber. Аналогично, если предыдущий угол меньше 5 градусов, а текущий угол больше 355 градусов, я вычитаю спин в mSpinNumber. Я также изменил имя метода с newSpin() на CalcuHourHandAngle().
private void calculateHourHandAngle() {
if ((mMinutesPrevAngle > 355) && (mMinutesCurrAngle < 5)) {
// New Spin clockwise
mSpinNumber++;
} else if ((mMinutesPrevAngle < 5) && (mMinutesCurrAngle > 355)) {
// New Spin counter-clockwise
mSpinNumber--;
}
mHoursCurrAngle = (mSpinNumber * (360/12)) + (mMinutesCurrAngle / 12);
}
Я также избавляюсь от ненужного кода в методе onTouch():
@Override
public boolean onTouch(View v, MotionEvent event) {
// Clock is the clock sphere and the minutes hand.
final float xc = clock.getTranslationX() + (clock.getWidth() / 2);
final float yc = clock.getTranslationY() + (clock.getHeight() / 2);
final float x = event.getX();
final float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
clock.clearAnimation();
hour.clearAnimation();
mMinutesCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
break;
case MotionEvent.ACTION_MOVE:
/**
* Translate angles from [-179,179] to [0,360] to be able to move
* hours hand properly.
*/
// Start Angle
mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
mMinutesPrevAngle = mMinutesCurrAngle;
// Finish angle
mMinutesCurrAngle = Math.toDegrees(Math.atan2(event.getX() - xc, yc - event.getY()));
mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
calculateHourHandAngle();
animate(clock, translate360Angle(mMinutesPrevAngle), translate360Angle(mMinutesCurrAngle), 0);
animate(hour, mHoursPrevAngle, mHoursCurrAngle, 0);
mHoursPrevAngle = mHoursCurrAngle;
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
Теперь я могу знать, какой час установил пользователь, потому что я знаю начальную позицию стрелок часов, количество вращений и угол минутной стрелки.