我尝试搜索过,但由于我的问题性质,我无法找到令人满意的答案。
我的问题是:我正在尝试将从0到2000(理想情况下上限可调整)的数字映射到范围从10到100的更小间隔。 上限会映射(2000->100),下限也是如此。 除此之外,在区间[0;2000]内,一个条目比另一个条目大,那么在[0;100]中映射的条目也应该更大
我认为这个问题不特定于语言,但以防你想知道,今天我正在使用Javascript。
我尝试搜索过,但由于我的问题性质,我无法找到令人满意的答案。
我的问题是:我正在尝试将从0到2000(理想情况下上限可调整)的数字映射到范围从10到100的更小间隔。 上限会映射(2000->100),下限也是如此。 除此之外,在区间[0;2000]内,一个条目比另一个条目大,那么在[0;100]中映射的条目也应该更大
我认为这个问题不特定于语言,但以防你想知道,今天我正在使用Javascript。
To map
[A, B] --> [a, b]
use this formula
(val - A)*(b-a)/(B-A) + a
正如其他答案所正确提到的,这是线性映射。
基本上
y = m*x + c
c = intersection at y-axis
m = slope determined by two known point (A, a), (B, b) = (b-a)/(B-A)
var nPercentage = ((modifier-nMinValue)/(nMaxValue - nMinValue))*100;
var nFontSize = parseInt((nBiggestFont-nSmallestFont)*(nPercentage/100)+nSmallestFont);
- Marceau// 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
这里可以提供一种优化的方式来映射您的x数据, 这段伪代码展示了一个映射函数的主要思路:
Deals with array mapping
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);
}
x
映射到x*90/2000+10
。使用Python中的Numpy库给出的答案:
import numpy as np
# [A, B]: old interval
# [a, b] new interval
new_value = np.interp(old_value, [A, B], [a, b])
print(new_value)