Optimisation automatique des échelles de courbes |
Maj : 20/02/22
Introduction Algorithme d’optimisation du pas pour le tracé des ordonnées d’une courbe,
Le principe Les données à traiter sont enregistrées dans un tableau de flottants par exemple de 720 entrées pour des enregistrements sur 24h toutes les 2 minutes ou 360 pour 24h toutes les 4 minutes. Un premier balayage calcule le maximum et le minimum de ces données Une simple différence donne l’espacement (range) que nous transformerons en entier. range = 1.01 * (offMax - offMin) ; // new final rounded range |
void extremumCalculation () // Calculation rounded min / max / range for (int i = 1 ; i < RECORDS_BY_DAY ; i++) // first scan for raw extremum calculation 360 datas if (xdata != ERASE_VALUE) // value after after eeprom erase |
Echelle Y et pas optimisés
Il faut maintenant ramener l’espace des données à traiter dans un espace supérieur à 100 et inférieur à 999,
en calculant un exposant « n », tel qu’en multipliant les données par 10 exp n, on se retrouve dans cet espace 100...999
Cela peut ne pas sembler évident à première vue, mais tout nombre positif peut bien être mis de la forme x * 10 exposant n, avec 100<x<999
La différence entre le maximum et le minimum est toujours positive, même pour des valeurs négatives,
100 <= range < 999.
Maintenant que nos données sont dans cet espace contraint 100..999, un petit algorithme va optimiser le nombre de pas pour avoir les graduations les plus entières et ergonomiques possibles !
Ce que l’on veut éviter c’est par exemple des horreurs comme le mauvais exemple donné :
16 __ 18.11 __ 20.22 ….. 34.99 !
Notre algorithme donnera à la place : 15_ 20_ 25 _ 30 _ 35,
ce qui est beaucoup plus lisible.
Le nombre de pas optimal sera déterminé dans cette simple liste d’espaces entiers (delta) : uint8_t stepsY[] = {200, 150, 100, 50, 25, 20} ;
Quelques exemples :
Delta très grand = 950 -> Découpage en 5 tranches de 200
Delta moyen 200 -> Découpage en 4 tranches de 50
Delta petit 110 -> Découpage en 5 tranches de 25
Utilisation
On passe à la méthode l’amplitude brute = (maximum-minimum), en retour on récupère le pas optimisé qui sera utilisé pour fixer les nouveaux maximum et minimum de la courbe à afficher avec un nombre de marques en ordonnées autour de 6 pour l’ergonomie optimale.
Implantation et exemples :
float minimum = 1234,5678; // Issu des données collectées
float maximum = 56789,01234; // Issu des données collectées
float vStep = vStepCalculation (maximum- minimum) ;
Toutes les données à afficher sont normalisées sous la forme :
<entier> <point décimal><deux chiffres centièmes>
Exemple : 43.21 °C, 12.34 V , 1013.15 hPa…
Mise en œuvre :
int nouveau_minimum = minimum- (minimum %vStep ) ; ---> Arrondi au palier inférieur
Affichage : <nouveau_minimum/100><point décimal>< nouveau_minimum/100>
int nouveau_maximum arrondi = maximum - (maximum %vStep) + vStep ;
Affichage : <nouveau_ maximum /100><point décimal>< maximum /100> ---> Arrondi au palier supérieur
Exemple concret, affichage température
Minimum -4.23°C
Maximum +3.76
Range= maximum- minimum = 7.99
float vStep = vStepCalculation (maximum- minimum) ; >> résultat 1.50
nouveau_minimum = minimum- (minimum %vStep ) = -4.23 -1.23 = -3
nouveau_maximum = maximum - (maximum %vStep) + vStep = 3.76 -0.76 + 1.50 = 4.50
Ce qui donne sur les échelles optimales de la courbe affichée, occupant le maximum d'espace possible : <4.50 .. 3 .. 1.50 .. 0 .. -1.5 .. -3>
Soit 6 horizontales, chiffre optimal.
Avec un pas de 1, il y aurait eu <4 ..3 .. 2 .. 1 .. 0 .. -1 .. -2 .. -3-.. -4 ..-5>, soit 10 horizontales ce qui est trop chargé.
Avec un pas de 2, il y aurait eu <4 .. 2 .. 0 .. -2 .. -4 .. 6> soit aussi 6 horizontales, mais avec beaucoup trop de vide au minimum de la courbe…
Il va de soi qu’au dernier moment, les valeurs optimales calculées seront affectés par le coefficient 10 exp n calculé au début.
Mon algorithme fonctionne quel que soit l'amplitude des données que vous lui soumettez. L'outil de test permet de le vérifier.
Et en prime, dans les logiciels joints, vous avez aussi la version en PHP pour comparer
Tous les détails et logiciels sont dans cette page à jour au : 220511 |