horloge.introuvable — Horloge introuvable

Dans son Catalogue d’objets introuvables [Carelman], Carelman propose des objets loufoques, dont la montre à chiffres mélangés.

Ce programme produit de telles montres.

../../_images/horloge1.png
../../_images/horloge2.png

Fonctionnement

Le fonctionnement est assez simple : j’ai un dictionnaire heures2angles dont :

  • les clefs sont les heures ;
  • les valeurs sont les angles où sont positionnées cette heure.

Par exemple, heures2angles[4] == 120 signifie que le nombre 4 sur l’horloge est situé à un angle de 120°.

Supposons ensuite qu’il soit 12h34’56”” (12 heures, 34 minutes et 56 secondes). Pour chaque aiguille, on calcule la valeur correspondante en secondes, ainsi que le total (le nombre de secondes écoulées lorsque l’aiguille a parcouru un tour complet).

  • secondes : \(56 ÷ 60\) ;
  • minutes : \(34×60+56 ÷ 60×60\) ;
  • heures : \(0×60×60 + 34×60 + 56 ÷ 12×60×60\) (12h correspond à 0h sur notre horloge).

Il faut ensuite savoir entre quels nombres (de 1 à 12, ou plutôt de 0 à 11) se trouvent chacune de ces proportions. C’est un simple calcul de proportionnalité. Par exemple pour les minutes :

Portion Total
34×60+56 60×60
? 12

Nous obtenons ici \(\frac{(34×60+56)×12}{60×60}\approx6,987\). L’aiguille des minutes sera donc située quelque part entre les nombres 6 et 7.

Pour connaître la position exacte, c’est une question de fonction affine. Supposons que sur notre horloge, le 6 soit situé à 120°, et le 7 à 30°. Nous cherchons alors une fonction affine \(f\) telle que : \(f(6)=120\) et \(f(7)=30\). L’angle de l’aiguille des minutes sera alors \(f(6,987)\). Et voilà !

Une subtilité éludée ici est ce qu’il se passe lorsque ce calcul fait passer par le chemin le plus long. Typiquement, si le chiffre 6 est à 330°, et le 7 à 30°. Avec notre calcul, entre 6h et 7h, l’angle de l’aiguille des heures parcourra presque tout le cadrant, son angle décroissant de 330° jusqu’à 30°, alors que cet angle devrait augmenter de 330° à 360° (c’est-à-dire 0°), puis ensuite augmenter de 0° à 30°. La solution trouvée est alors de détecter lorsque la différence d’angles est supérieure à 180°, et modifier alors un des deux angles (plus ou moins 360°) pour réduire cette différence à une valeur acceptable.

Toute ceci est fait dans la méthode Horloge.angle() :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    def angle(self, hand, total):
        """Renvoit l'angle d'une aiguille.

        Arguments :
        - `hand` : nombre d'unités de temps écoulées ;
        - `total` : nombre total d'unités de temps sur un tour de cadrant.

        Par exemple :
        - pour afficher l'aiguille des secondes s'il est 12h34'56'', alors `hand=56, total=60` ;
        - pour afficher l'aiguille des minutes s'il est 12h34'56'',
          alors `hands=(34*60+56), total=60*60` ;
        - etc.
        """
        exact = (12 * hand) / total
        lower, upper = math.floor(exact), math.ceil(exact) % 12
        if lower == upper:
            return self.heures2angles[lower]

        relative = exact - lower
        upperangle = self.heures2angles[upper]
        lowerangle = self.heures2angles[lower]

        widthangle = (upperangle - lowerangle + 180) % 360 - 180
        if widthangle == -180:
            widthangle = 180

        return (lowerangle + relative * widthangle) % 360

Ligne de commande

Affiche une « horloge introuvable ».

usage: horloge.introuvable [-h] [--version] [-c COULEUR] [-d DECALAGE]
                           [-v VITESSE] [-t TAILLE]
                           [heures [heures ...]]

Positional Arguments

heures Position des heures. Il y a plusieurs manières de les définir : - [alea1, alea2, alea3] : disposition aléatoire des heures, suivant différents algorithmes ; - vide ou « alea » : la position des heures est choisie au hasard, selon un des algorithmes suscités (choisi évidemment aléatoirement) ; - « 1 2 3 4 5 6 7 8 9 10 11 12 » : par la suite les heures dans le sens des aiguilles d’une montre, en terminant à la verticale (la valeur de l’option –decalage est alors définie, par défaut, pour que la dernière heure spécifiée soit en haut) ; - « 1:30 2:60 3:90 … 12:0 » : en précisant l’angle de chaque nombre. Dans les deux derniers cas, il est possible de ne pas indiquer toutes les heures.

Named Arguments

--version show program’s version number and exit
-c, --couleur Couleurs de l’horloge, sous la forme “heures=red”. Les paramètres à colorier (avec leur valeur par défaut) sont : - heures : aiguille des heures (noire) ; - minutes : aiguille des minutes (noire) ; - secondes : aiguille des secondes (rouge) ; - fond : couleur de fond (blanc) ; - chiffres : chiffres des heures (noir).
-d, --decalage

Décalage des angles par rapport à leur spécification, seulement si les nombres ne sont pas définis par leurs angles.

Default: 0

-v, --vitesse

Vitesse de l’horloge (défaut 1 ; l’horloge indique alors l’heure).

Default: 1

-t, --taille Taille de l’horloge en pixels.

Cette horloge a été inventée par Jacques Carelman, dans sont « Catalogue des objets introuvables ».

Notes et Références

[Carelman]Jacques Carelman, Catalogue d’objets introuvables, Le Livre de Poche, 1996.