Math 数学映射数

Math 数学映射数,math,numbers,mapping,interpolation,linear-algebra,Math,Numbers,Mapping,Interpolation,Linear Algebra,如何将a和b之间的数字线性映射到c和d之间 也就是说,我希望2到6之间的数字映射到10到20之间的数字。。。但我需要广义的情况 我的大脑被炸了。除以两个范围大小之间的比率,然后减去初始范围的起始值,乘以该比率,再加上第二个范围的起始值。换句话说, R = (20 - 10) / (6 - 2) y = (x - 2) * R + 10 这会将第一个范围内的数字均匀分布在第二个范围内。如果数字X位于A和B之间,并且希望Y位于C和D之间,则可以应用以下线性变换: Y = (X-A)/(B-A) *

如何将a和b之间的数字线性映射到c和d之间

也就是说,我希望2到6之间的数字映射到10到20之间的数字。。。但我需要广义的情况


我的大脑被炸了。

除以两个范围大小之间的比率,然后减去初始范围的起始值,乘以该比率,再加上第二个范围的起始值。换句话说,

R = (20 - 10) / (6 - 2)
y = (x - 2) * R + 10

这会将第一个范围内的数字均匀分布在第二个范围内。

如果数字X位于A和B之间,并且希望Y位于C和D之间,则可以应用以下线性变换:

Y = (X-A)/(B-A) * (D-C) + C

虽然你的问题有点模棱两可,但这应该会给你你想要的,因为你也可以将时间间隔映射到相反的方向。只要注意被零除,你就可以了。

第一个量程上的每个单位间隔占用第二个量程上的(d-c)/(b-a)“空间”

伪:

var interval = (d-c)/(b-a)
for n = 0 to (b - a)
    print c + n*interval
如何处理舍入取决于您。

int srcMin=2,srcMax=6;
int srcMin = 2, srcMax = 6;
int tgtMin = 10, tgtMax = 20;

int nb = srcMax - srcMin;
int range = tgtMax - tgtMin;
float rate = (float) range / (float) nb;

println(srcMin + " > " + tgtMin);
float stepF = tgtMin;
for (int i = 1; i < nb; i++)
{
  stepF += rate;
  println((srcMin + i) + " > " + (int) (stepF + 0.5) + " (" + stepF + ")");
}
println(srcMax + " > " + tgtMax);
int-tgtMin=10,tgtMax=20; int nb=srcMax-srcMin; int range=tgtMax-tgtMin; 浮动率=(浮动)范围/(浮动)nb; println(srcMin+“>”+tgtMin); 浮动步长f=tgtMin; 对于(int i=1;i”+(int)(stepF+0.5)+“(“+stepF+”)); } println(srcMax+“>”+tgtMax);

当然,对于除数为零的检查。

这与经典的convert celcius to farenheit(将celcius转换为farenheit)是同一个问题,在这里,您要映射一个等于0-100(C)到32-212(F)的数字范围。

除了@PeterAllenWebb answer之外,如果您想反转结果,请使用以下命令:

reverseX = (B-A)*(Y-C)/(D-C) + A

java.lang.Math
类中拥有此功能将是一件好事,因为这是一个广泛需要的函数,并且在其他语言中也可用。 下面是一个简单的实现:

final static double EPSILON = 1e-12;

public static double map(double valueCoord1,
        double startCoord1, double endCoord1,
        double startCoord2, double endCoord2) {

    if (Math.abs(endCoord1 - startCoord1) < EPSILON) {
        throw new ArithmeticException("/ 0");
    }

    double offset = startCoord2;
    double ratio = (endCoord2 - startCoord2) / (endCoord1 - startCoord1);
    return ratio * (valueCoord1 - startCoord1) + offset;
}
最终静态双ε=1e-12;
公共静态双映射(双值坐标1,
双起点1,双终点1,
双星CORD2,双端CORD2){
if(Math.abs(endCoord1-startcord1)

我把这段代码放在这里作为将来我自己的参考,也许它会帮助别人。

如果你的范围是从[a到b],你想把它映射到[c到d],其中x是你想映射的值 使用此公式(线性映射)


其中,X是从A-B映射到C-D的数字,Y是结果: 取线性插值公式lerp(a,b,m)=a+(m*(b-a)),并将CD替换a和b,得到Y=C+(m*(D-C)。然后,代替m,放置(X-A)/(B-A)得到Y=C+((X-A)/(B-A)*(D-C)。这是一个不错的映射函数,但可以简化。拿(D-C)块,将其放入红利中,得到Y=C+(((X-A)*(D-C)/(B-A)。这给了我们另一个我们可以简化的部分,(X-A)*(D-C),它等同于(X*D)-(X*C)(A*D)+(A*C)。把它打开,你会得到Y=C+((X*D)-(X*C)-(A*D)+(A*C)/(B-A)。接下来需要做的是添加+C位。为此,您将C乘以(B-A)得到(B*C)-(A*C),然后将其移动到股息中,得到Y=(((X*D)-(XC)-(A*D)+(A*C)+(B*C)-(A*C)/(B-A)。这是多余的,既包含A+(A*C)又包含A-(A),它们相互抵消。删除它们,您将得到以下最终结果:Y=(X*D)-(X*C)-(a*D)+(B*C)/(B-a


TL;DR:标准的map函数,Y=C+((X-A)/(B-A)*(D-C)可以简化为Y=(X-D)(X-C)-(A*D)+(B*C)/(B-A

两点形式。这不起作用。我的范围是100000000到9999999999,数字可以是1到9999999。@Odelya当然可以。这是一个足够简单的数学转换。你只需要使用足够大的数字类型(bignum或类似类型)。你的数字对于32位整数来说太大了
double R = (d-c)/(b-a)
double y = c+(x*R)+R
return(y)
[a1, a2] => [b1, b2]

if s in range of [a1, a2]

then t which will be in range of [b1, b2]

t= b1 + ((s- a1) * (b2-b1))/ (a2-a1)