RSS

Petite histoire d’une formule mathématique discrète

lun, fév 2, 2009

ActionScript, JavaScript, Open Source

Petite histoire d’une formule mathématique discrète

Lors de deux projets récents, j’ai été confronté à des problématiques similaires. J’ai d’abord eu à construire une réglette en ActionScript 3, puis un navigateur de produits, semblable à celui du site de Apple, en JavaScript.

Dans les deux cas, il fallait pouvoir récupérer, depuis la position du curseur sur sa réglette, des valeurs par paliers. La question était donc celle-ci : Comment récupérer une valeur discrète sur une échelle continue ?

Valeurs continues

Tout d’abord pour récupérer une valeur continue sur une réglette, une simple règle de trois suffit :

AS3 : récupération d’une valeur continue sur une réglette arbitraire

/**
 * min :        valeur minimum de la réglette
 * max :        valeur maximum de la réglette
 * width :      largeur de la réglette
 * position :   position du curseur sur la réglette
 */

var continuous = min + (max - min) * position / width

Arrondi au multiple le plus proche

Supposons maintenant que je décide d’ajouter la notion de pas sur ma réglette. Je ne souhaite alors récupérer que les valeurs multiples de ce pas. Par exemple, si mon pas est de 3 j’obtiendrais la série suivante :

0, 3, 6, 9, 12...

Voici la formule qui me permet d’obtenir ce résultat.

AS3 : formule retournant une valeur discrète à partir d’une échelle continue

/**
 * step :       pas de mon échelle
 * continuous : valeur continue sur mon échelle
 */

var discrete = step * Math.floor((continuous + step / 2) / step );

Cette formule, renvoie donc une valeur discrète (arrondie) quand on lui fournit le pas à respecter (step) et une valeur continue (value).

Il subsiste encore un problème, la formule précédente ne prend pas en compte la valeur minimum de ma réglette. En reprenant l’exemple précédent, lorsque je récupère des valeurs avec un pas de 3 mais ne commençant pas à 0… disons à 2, je souhaiterais obtenir la série suivante :

2, 5, 8, 11, 14...

Or avec la formule précédente, je n’obtiens que des arrondis de multiples du pas mais 2, 5, 8, 11, 14 ne sont pas des multiples de 3.

Valeurs discrètes et minimum d’échelle

Pour résoudre le problème, il faut donc modifier les 2 formules précédentes en décalant l’échelle de la valeur minimum avant d’utiliser la fonction d’arrondi puis en la corrigeant à nouveau après.
En plus clair :

  1. Retrancher la valeur minimum à la valeur continue (pour que l’échelle de la réglette parte de 0 et pas de la valeur minimum)
  2. Puis ajouter cette même valeur minimum à la valeur arrondie pour corriger le décalage introduit précédemment

AS3 : Comparaison des formules

// Formules précédentes
var continuous =  min + (max - min) * position / width;
var discrete = step * Math.floor((continuous + step / 2) / step);

// Formules corrigées
var continuous =  (max - min) * position / width;
var discrete =
    step * Math.floor((continuous + step / 2) / step) + mini;

Pour tester la formule, voici un exemple des réglettes faites en AS3. L’une retourne des valeurs continues l’autre des valeurs par paliers. Les valeurs minimum et maximum ainsi que le pas de la deuxième réglette sont paramétrables.

Le plugin Flash est requis pour visualiser cet objet.

Cet article a été écrit par :

Stéphane Roucheray - a déjà écrit 7 article(s) sur Pims Labs.