Définir une horloge analogique sur le temps avec les gestes, le toucher aiguille des minutes dans le sens horaire ou anti-horaire

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

Question

Je suis coincé à essayer de faire une classe qui permettent aux utilisateurs de définir une horloge analogique sur le temps.Ils ont à se déplacer aiguille des minutes, pas heures à la main, dans le sens horaire ou antihoraire pour régler l'heure actuelle.Aiguille des heures se déplace lui-même en fonction des minutes aiguille des progrès, mais je ne peux pas être en mesure de déplacer l'aiguille des heures correctement.Il n'a pas un mouvement fluide à chaque fois que traverse douze heures et six heures, où il y a de l'angle de points critiques.

C'est ma séance d'entraînement jusqu'à ce moment.À douze heures, l'angle est égal à 0 degrés, l'angle minimal de cours, et à six heures, l'angle est de 180 degrés, le maximum de l'angle.Ainsi, à partir de douze à six (sens horaire), nous avons des angles positifs (0,180), et, à partir de six à douze (sens horaire), nous avons négatif angles (-180,0).C'est ok, mais si je veux calculer quelle sera la position correcte de l'aiguille des heures en fonction avec des minutes aiguille des progrès, j'ai à traduire que les angles de 0-360 degrés de la gamme.

C'est là que je me charge de gestes:

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

C'est là que je traduire les angles:

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

Et c'est là où je sais que si l'aiguille des minutes commence un nouveau spin:

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

Quelqu'un peut-il m'aider un petit peu?si quelqu'un peut m'aider, je vous promets de mettre votre nom pour mon premier enfant à naître fille ...c'est juste une blague.

Était-ce utile?

La solution

J'ai découvert où était le problème...

Le problème était le "si les conditions" à l'intérieur de newSpin() la méthode.Ici, avant de vérifier les conditions, j'ai traduit les angles pour le format de l'original (de 0 à 180 degrés pendant douze heures à six heures, aiguilles d'une montre, et de -180 ° à 0°, pour six heures à douze heures, dans le sens des aiguilles trop).Ainsi, au lieu de vérifier si l'utilisateur démarre une nouvelle spin avec aiguille des minutes, Il a été l'ajout/soustraction d'un nouveau spin à chaque fois que l'utilisateur passe par six heures au lieu de douze heures.

Alors, j'ai fait réparer la modification de ces conditions, et de vérifier à la fois des minutes aiguille des angles, anciennes et actuelles, sur 360 degrés format.Maintenant, si l'angle est plus grand que 355 degrés et l'angle courant est inférieure à 5 degrés, j'ai ajouter une nouvelle rotation à mSpinNumber.De même, si l'angle est inférieur à 5 degrés et l'angle actuel est plus grand que 355 degrés, je soustrais un tour à mSpinNumber.J'ai aussi fait du changement de la méthode nom de newSpin() pour calculateHourHandAngle().

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

J'ai également de se débarrasser de code inutile dans onTouch() la méthode:

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

Maintenant je être en mesure de savoir à quelle heure avez-définie par l'utilisateur, parce que je sais que la position initiale des mains de l'horloge, le nombre de tours et l'aiguille des minutes d'angle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top