回答:
数値XがAとBの間にあり、YをCとDの間に収めたい場合は、次の線形変換を適用できます。
Y = (X-A)/(B-A) * (D-C) + C
間隔を逆方向にマッピングすることもできるので、質問は少しあいまいですが、これで必要なものが得られます。ゼロによる除算に注意してください。大丈夫です。
Y=f(X)=m*X+b
mおよびBは、以下の2つの制約式から同時に決定されている場合、必要なエンドポイントでXとYの値を代入した結果、その:C=m*A+b
およびD=m*B+b
X=A+(A-B)*t
、このアプローチとピーターの平等を証明するために使用する必要がありました。tは本質的にXの無次元化です。(t=(X-A)/(A-B)
)
2つの範囲のサイズ間の比率を得るために除算してから、初期範囲の開始値を減算し、比率を掛けて、2番目の範囲の開始値を追加します。言い換えると、
R = (20 - 10) / (6 - 2)
y = (x - 2) * R + 10
これにより、最初の範囲の数値が2番目の範囲に均等に分散されます。
これは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);
もちろん、ゼロ除算のチェック付き。
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)