ユーザーがアナログ時計を時間通りに設定できるクラスを作ろうとして立ち往生しています。現在の時刻を設定するには、時針ではなく分針を時計回りまたは反時計回りに動かさなければなりません。分針の進行に合わせて時針が動くのですが、時針がうまく動かせません。角度の臨界点がある12時と6時を通過するたびに滑らかな動きをするわけではありません。
これが今までの私のトレーニングです。12 時の角度はもちろん最小角度である 0 度に等しく、6 時の角度は最大角度である 180 度です。したがって、12 から 6 まで (時計回り) では正の角度 (0.180) になり、6 から 12 まで (時計回り) では負の角度 (-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;
}
}
誰か助けてくれませんか?誰かが私を助けることができるなら、私はあなたの名前を私の最初の胎児の娘に入れることを約束します...冗談です.