如何在a和b之间线性映射数字以在c和d之间移动。
也就是说,我希望2到6之间的数字映射到10到20之间的数字...但是我需要广义的情况。
我的大脑炸了。
Answers:
如果您的数字X介于A和B之间,并且您希望Y介于C和D之间,则可以应用以下线性变换:
Y = (X-A)/(B-A) * (D-C) + C
尽管您的问题有点模棱两可,但这应该可以为您提供所需的内容,因为您还可以反向绘制区间。只要当心被零除,就可以了。
Y=f(X)=m*X+b
,其中m和b是由以下两个约束方程同时确定的,这些方程由将X和Y的值替换为所需的端点C=m*A+b
D=m*B+b
X=A+(A-B)*t
证明该方法与Peter的方法相同。t本质上是X的无量纲。(t=(X-A)/(A-B)
)
除以得到两个范围的大小之间的比率,然后减去初始范围的起始值,再乘以该比率,然后加上第二个范围的起始值。换一种说法,
R = (20 - 10) / (6 - 2)
y = (x - 2) * R + 10
这样可以将第二个范围内的数字从第一个范围平均分布。
最好在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;
}
我将这段代码放在这里,以供将来参考,可能对某人有帮助。
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);
当然要进行除以零的检查。
如果您的范围是从[a到b],并且想要将其映射到[c到d],其中x是您要映射的值,请使用此公式(线性映射)
double R = (d-c)/(b-a)
double y = c+(x*R)+R
return(y)
https://rosettacode.org/wiki/Map_range
[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)