web-dev-qa-db-fra.com

Normalisation de [0.5 - 1] à [0 - 1]

Je suis un peu coincé ici, je suppose que c'est un peu un casse-tête. Si j'ai des nombres compris entre 0,5 et 1, comment puis-je le normaliser pour qu'il soit compris entre 0 et 1?

Merci pour toute aide, peut-être que je suis juste un peu lent depuis que je travaille depuis 24 heures d'affilée O_O

27
tweetypi

D'autres vous ont fourni la formule, mais pas le travail. Voici comment vous abordez un problème comme celui-ci. Vous trouverez peut-être cela beaucoup plus utile que de simplement connaître la réponse.

Pour mapper [0.5, 1] à [0, 1], nous rechercherons une carte linéaire de la forme x -> ax + b. Nous demanderons que les noeuds finaux soient mappés sur ceux-ci et que leur ordre soit préservé. 

Première méthode: L'exigence voulant que les noeuds finaux soient mappés sur ceux-ci et que leur ordre soit préservé implique que 0.5 est mappé sur 0 et que 1 est mappé sur 1.

a * (0.5) + b = 0 (1)
a * 1 + b = 1     (2)

Il s'agit d'un système simultané d'équations linéaires qui peut être résolu en multipliant l'équation (1) par -2 et en ajoutant l'équation (1) à l'équation (2). Ce faisant, nous obtenons b = -1 et en substituant ceci dans l'équation (2), nous obtenons ce a = 2. Ainsi, la carte x -> 2x - 1 fera l'affaire.

Méthode deux: La pente d'une ligne passant par deux points (x1, y1) et (x2, y2) est

(y2 - y1) / (x2 - x1).

Ici, nous allons utiliser les points (0.5, 0) et (1, 1) pour répondre à l'exigence voulant que les noeuds finaux soient mappés sur des noeuds finaux et que la carte préserve les commandes. Donc la pente est

m = (1 - 0) / (1 - 0.5) = 1 / 0.5 = 2.

Nous avons que (1, 1) est un point sur la ligne et donc, par la forme de pente d'une équation d'une ligne, nous avons:

y - 1 = 2 * (x - 1) = 2x - 2

pour que

y = 2x - 1.

Une fois encore, nous voyons que x -> 2x - 1 est une carte qui fera l'affaire.

65
jason

Soustrayez 0.5 (en vous donnant une nouvelle plage de 0 à 0.5), puis multipliez par 2.

double normalize( double x )
{
    // I'll leave range validation up to you
    return (x - 0.5) * 2;
}
31
Bill the Lizard

Pour ajouter une autre réponse générique.

Si vous souhaitez mapper la plage linéaire [A..B] à [C..D], vous pouvez appliquer les étapes suivantes:

Décale la plage pour que la borne inférieure soit 0. (sous-extraire A des deux bornes:

[A..B] -> [0..B-A]

Échelle la plage pour qu'il soit [0..1]. (diviser par la limite supérieure):

[0..B-A] -> [0..1]

Échellez la plage pour qu'elle ait la longueur de la nouvelle plage, à savoir D-C. (multiplier par D-C):

[0..1] ->  [0..D-C]

Décalez la plage pour que la limite inférieure soit C. (ajoutez C aux limites):

[0..D-C] -> [C..D]

En combinant cela à une seule formule, nous obtenons:

       (D-C)*(X-A)
X' =   -----------  + C
          (B-A)

Dans votre cas, A = 0.5, B = 1, C = 0, D = 1 vous obtenez:

       (X-0.5)
X' =   ------- = 2X-1
        (0.5)

Notez que si vous devez convertir beaucoup de X en X ', vous pouvez changer la formule en:

       (D-C)         C*B - A*D
X' =   ----- * X  +  ---------  
       (B-A)           (B-A)

Il est également intéressant de jeter un regard sur les plages non linéaires. Vous pouvez suivre les mêmes étapes, mais vous avez besoin d’une étape supplémentaire pour transformer la plage linéaire en une plage non linéaire.

24
Toon Krijthe

× 2 - 1

devrait faire l'affaire

15
Glenner003

Réponse de Lazyweb: Pour convertir une valeur x de [minimum..maximum] en [floor..ceil]:

Cas général:

normalized_x = ((ceil - floor) * (x - minimum))/(maximum - minimum) + floor

Pour normaliser à [0..255]:

normalized_x = (255 * (x - minimum))/(maximum - minimum)

Pour normaliser à [0..1]:

normalized_x = (x - minimum)/(maximum - minimum)
14
meetar

Vous pouvez toujours utiliser clamp ou saturer dans vos calculs pour vous assurer que votre valeur finale est comprise entre 0 et 1. Certains saturent à la fin, mais je l’ai aussi vu lors d’un calcul. 

0
Whitney Imura