Anthias
mail

Optimisation automatique

des échelles de courbes

ili

Maj : 20/02/22

Introduction

Algorithme d’optimisation du pas pour le tracé des ordonnées d’une courbe,
dont le minimum et le maximum sont de dimensions quelconques (en flottant).

 

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.
Le facteur 1.01 évitera le cas marginal de 999 <range (flottant) <1000 !

range = 1.01 * (offMax - offMin) ; // new final rounded range

void extremumCalculation () // Calculation rounded min / max / range
{
float xdata = BufEep360[RECORDS_BY_DAY-1] ; // Init values
float offMin = xdata ;
float offMax = offMin ; // Offmax internal

for (int i = 1 ; i < RECORDS_BY_DAY ; i++) // first scan for raw extremum calculation 360 datas
{
xdata = BufEep360[i] ;

if (xdata != ERASE_VALUE) // value after after eeprom erase
{
if (xdata < offMin)
offMin = xdata ;
if (xdata > offMax)
offMax = xdata ;
}

Haut de page

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

ili

Echelle optimisée

Gradhs

Horreur non optimisée

Haut de page

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

eclate

Haut de page

© Christian Couderc 1999-2022     Toute reproduction interdite sans mon autorisation


* Page vue   9924   fois       IP : 3.223.3.251

 Haut de page         Dernière retouche le 20 Février 2022 à 17 h         Retour page précédente

   Collector