2012-10-17 37 views
10

Ho provato a cercare, ma a causa della natura della mia domanda, non sono riuscito a trovare qualcosa di soddisfacente.Algoritmo per mappare un intervallo ad un intervallo più piccolo

Il mio problema è il seguente: sto cercando di mappare numeri compresi tra 0 e 2000 (sebbene idealmente il limite superiore sia regolabile) all'intervallo molto più piccolo che va da 10 a 100. I limiti superiori verrebbero mappati (2000- > 100) e anche i limiti inferiori. Oltre a questo, una voce che è più grande di un'altra voce nell'intervallo [0; 2000] sarebbe idealmente essere più grande di quella voce mappata in [0; 100]

Sto pensando che questa domanda non è linguaggio specifico, ma nel caso ti stia chiedendo, sto lavorando con Javascript oggi.

+0

I tuoi intervalli sono interi o reali/mobili/decimali? Avete bisogno di voci diverse nella sorgente per mappare le diverse voci nella destinazione? – Chowlett

+0

Subito dopo aver scritto questa domanda, ho trovato una soluzione accettabile (per me): ho calcolato il valore percentuale della prima voce nel suo intervallo e poi ho trasposto quella percentuale nel nuovo intervallo. – Zaan

risposta

1

una mappatura lineare semplice sarebbe mappare x-x*90/2000+10.

29
To map 
[A, B] --> [a, b] 

use this formula 
(val - A)*(b-a)/(B-A) + a 

come giustamente menzionato nel altra risposta è mappatura lineare.

Fondamentalmente

y = m*x + c 

c = intersection at y-axis 
m = slope determined by two known point (A, a), (B, b) = (b-a)/(B-A) 
+0

Ho finito per fare qualcosa che sembra abbastanza simile.Una descrizione è al di sopra, ma lo script è qui: (nMinValue è la B, nMaxFontSize è la a) 'var nPercentage = ((modificatore-nMinValue)/(nMaxValue - nMinValue)) * 100; var nFontSize = parseInt ((nBiggestFont-nSmallestFont) * (nPercentage/100) + nSmallestFont); ' – Zaan

+0

sì, sembra a posto. – Nishant

1
// Given a value from intervalA, returns a mapped value from intervalB. 
function intervalicValueMap(intervalA, intervalB, valueIntervalA) { 
    var valueIntervalB = (valueIntervalA - intervalA[0]) * (intervalB[1] - intervalB[0]) 
          /(intervalA[1] - intervalA[0]) + intervalB[0]; 

    valueIntervalB = Math.round(valueIntervalB); // Ommit rounding if not needed. 
    return valueIntervalB; 
} 

var intervalA = [100, 200]; 
var intervalB = [1, 10]; 
var valueIntervalA = 170; 
var valueIntervalB = intervalicValueMap(intervalA, intervalB, valueIntervalA); 

console.log(valueIntervalB); // Logs 7 
0

qui potrebbe essere un modo ottimizzato per mappare i dati x, Questo pseudo codice si mostra l'idea principale per una funzione mappa che:

  • Evitare problemi con i valori di x nell'intervallo di b1 - b2.
  • occupa di mappatura gamma

    function map(var x, var b1, var b2, var s1, var s2) 
    { 
        var i; 
        var result; 
    
        i = 0; 
        while(i < sizeof(s2)) 
         if(x < b1) 
          result[i++] = s1; 
         else if (x > b2) 
          result[i++] = s2; 
         else 
          result[i] = (x - b1)/(b2 - b1) * (s2[i] - s1[i]) + s1[i++]; 
        return (result); 
    } 
    
1

Penso che invece di dare una formula di mappatura diretta, un approccio migliore sarebbe quello di spiegare l'idea alla base:

Supponiamo di voler mappare un intervallo [0,1] all'intervallo [1,3], che può essere visto come il problema di trovare f (x) = Ax + B tale che dare qualsiasi x dall'intervallo [0,1], risulterà in f (x) essendo/risultando in un intervallo [1,3].

Da questo punto di vista, sappiamo già alcuni valori:

  1. x = 0 & f (0) = 1 => f (0) = A * 0 + B = 1 => B = 1
  2. x = 1 & f (1) = 3 => f (1) = A * 1 + B = 3 < => A + 1 = 3 => A = 2

Da (1) e (2), possiamo concludere che la funzione che mappa l'intervallo da [0,1] a [1,3] è f (x) = 2x + 1.

Nel tuo caso, ora dovresti avere tutte le conoscenze necessarie per poter mappare [0,2000] a [10,100].

Problemi correlati