Impostare un orologio analogico in tempo con i gesti, toccando il minuto in senso orario o in senso antiorario

StackOverflow https://stackoverflow.com//questions/24039913

Domanda

Sono bloccato cercando di creare una classe che consente agli utenti di impostare un orologio analogico in tempo. Devono spostare la mano dei minuti, non la mano dell'ora, in senso orario o in senso antiorario per impostare l'ora corrente. L'ora si sposta da solo in base al progresso della mano dei minuti, ma non posso essere in grado di spostare correttamente la mano dell'ora. Non ha un movimento fluido ogni volta passa attraverso dodici e sei, dove ci sono punti critici d'angolo.

Questo è il mio allenamento fino a questo momento. Alle dodici in punto, l'angolo è uguale a 0 gradi, l'angolo minimo del corso, e alle sei in punto, l'angolo è di 180 gradi, l'angolo massima. Quindi, da dodici a sei (in senso orario), abbiamo angoli positivi (0,180), e, da sei a dodici (in senso orario), abbiamo angoli negativi (-180,0). Va bene, ma se voglio calcolare ciò che sarà la posizione corretta della mano di un'ora secondo i progressi della mano dei minuti, devo tradurre questo gamma di angoli su 0-360 gradi.

Ecco dove gestisco i gesti:

@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;
}
.

Ecco dove Traduco angoli:

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

Ed ecco dove so se la mano dei minuti inizia una nuova rotazione:

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

Qualcuno può aiutarmi un bit di litle? Se qualcuno può aiutarmi, prometto di mettere il tuo nome alla mia prima figlia non nata ... sto solo scherzando.

È stato utile?

Soluzione

Ho scoperto dove era il problema ...

Il problema è stato il metodo "se condizioni" all'interno del newspin (). Qui, prima delle condizioni di controllo, ho tradotto gli angoli al formato originale (da 0 gradi a 180 gradi per dodici in punto alle sei in punto, in senso orario, e da -180 gradi a 0 gradi, per le sei in punto a dodici o 'Orologio, in senso orario). Quindi, invece controlla se l'utente inizia una nuova rotazione con la mano dei minuti, si trattava di / sottrarre un nuovo spin ogni volta che l'utente passa attraverso le sei in punto invece dodici.

Allora, l'ho riparata a modificare tali condizioni e controllando sia gli angoli a mano minuto, precedente e corrente, su formato a 360 gradi. Ora, se l'angolo precedente è più grande di 355 gradi e l'angolo corrente è inferiore a 5 gradi, aggiungo una nuova rotazione a MspinNumber. Allo stesso modo, se l'angolo precedente è inferiore a 5 gradi e l'angolo corrente è più grande di 355 gradi, sottrai un giro a MspinNumber. Ho anche fatto il nome del metodo di cambiamento da Newspin () a CalculehourHandngle ().

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);
}
.

Ho anche sbarazzato del codice non necessario in OnTouch () Metodo:

@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;
}
.

Ora potrò sapere che ora ha impostato l'utente, perché conosco la posizione iniziale dell'orologio delle mani, il numero di giri e, l'angolo della mano dei minuti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top