我試過搜索,但由於我的問題的性質,我無法找到滿意的結果。將間隔映射到較小間隔的算法
我的問題如下:我試圖將範圍從0到2000(儘管理想情況下上限可調整)的數字映射到範圍從10到100的小得多的區間。上限將映射(2000- > 100)以及下限。除此之外,大於區間[0; 2000]中另一個條目的條目理想情況下會大於[0; 100]中的映射條目
我在想這個問題不是特定於語言的,但如果你想知道,我今天正在使用Javascript。
我試過搜索,但由於我的問題的性質,我無法找到滿意的結果。將間隔映射到較小間隔的算法
我的問題如下:我試圖將範圍從0到2000(儘管理想情況下上限可調整)的數字映射到範圍從10到100的小得多的區間。上限將映射(2000- > 100)以及下限。除此之外,大於區間[0; 2000]中另一個條目的條目理想情況下會大於[0; 100]中的映射條目
我在想這個問題不是特定於語言的,但如果你想知道,我今天正在使用Javascript。
簡單的線性映射將映射x
到x*90/2000+10
。
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)
// 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數據, 這個僞代碼顯示了地圖功能 的主要思路:
涉及陣列映射
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);
}
我認爲這不是給你直接映射的一個公式,一個更好的方法是解釋它背後的理念:
假設我們要將區間[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]。
你的範圍是整數還是實數/浮點數/小數?您是否需要源中的不同條目映射到目標中的不同條目? – Chowlett
剛剛輸入這個問題後,我想出了一個(對我來說)可接受的解決方案:我計算了其間隔中第一個條目的百分比值,然後將該百分比轉換爲新的間隔。 – Zaan