我尝试搜索,但由于我的问题的性质,我无法找到令人满意的东西。
我的问题如下:我正在尝试将范围从 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)
我认为与其给你一个直接映射的公式,更好的方法是解释它背后的想法:
假设我们要将区间 [0,1] 映射到区间 [1,3],这可以看作是找到 f(x) = Ax + B 的问题,使得从区间 [0,1] 中给出任意 x,将导致 f(x) 成为/导致区间 [1,3]。
从这个角度来看,我们已经知道了一些价值观:
从 (1) 和 (2) 可以得出,将区间 [0,1] 映射到 [1,3] 的函数是 f(x) = 2x + 1。
在您的情况下,您现在应该具备将 [0,2000] 区间映射到 [10,100] 的所有必要知识。
// 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
到x*90/2000+10
。
这可能是映射 x 数据的优化方法,此伪代码向您展示了 map 函数的主要思想:
处理数组映射
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);
}
使用 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)