C ve d arasında gitmek için a ve b arasındaki sayıları doğrusal olarak nasıl eşlerim.
Yani, 2 ile 6 arasındaki sayıların 10 ile 20 arasındaki sayılarla eşleşmesini istiyorum ... ama genelleştirilmiş duruma ihtiyacım var.
Beynim kızarmış.
C ve d arasında gitmek için a ve b arasındaki sayıları doğrusal olarak nasıl eşlerim.
Yani, 2 ile 6 arasındaki sayıların 10 ile 20 arasındaki sayılarla eşleşmesini istiyorum ... ama genelleştirilmiş duruma ihtiyacım var.
Beynim kızarmış.
Yanıtlar:
X numaranız A ile B arasına denk geliyorsa ve Y'nin C ile D arasında kalmasını istiyorsanız, aşağıdaki doğrusal dönüşümü uygulayabilirsiniz:
Y = (X-A)/(B-A) * (D-C) + C
Bu size istediğinizi vermelidir, ancak sorunuz biraz belirsizdir, çünkü aralığı ters yönde de haritalayabilirsiniz. Sadece sıfıra bölmeye dikkat edin ve iyi olmalısınız.
Y=f(X)=m*X+b
, m ve b'nin gerekli uç noktalarda X ve Y değerlerinin ikame edilmesinden kaynaklanan aşağıdaki iki kısıt denkleminden eşzamanlı olarak belirlendiği bir çizginin denklemi olmalıdır : C=m*A+b
veD=m*B+b
X=A+(A-B)*t
bu yaklaşımla Peter'ın eşitliğini kanıtlamak için kullanma ihtiyacım da oldu . t esasen X'in boyutsuzlaştırılmasıdır. ( t=(X-A)/(A-B)
)
İki aralığın boyutları arasındaki oranı elde etmek için bölün, ardından başlangıç aralığınızın başlangıç değerini çıkarın, oranla çarpın ve ikinci aralığınızın başlangıç değerini ekleyin. Diğer bir deyişle,
R = (20 - 10) / (6 - 2)
y = (x - 2) * R + 10
Bu, ikinci aralıktaki ilk aralıktaki sayıları eşit olarak dağıtır.
java.lang.Math
Sınıfta bu işlevselliğe sahip olmak güzel olurdu , çünkü bu çokça gerekli bir işlevdir ve diğer dillerde mevcuttur. İşte basit bir uygulama:
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;
}
Bu kodu buraya kendim için referans olarak koyuyorum ve belki birine yardımcı olabilir.
Bir kenara olarak, bu, 0 - 100 (C) ile 32 - 212 (F) arasında bir sayı aralığını eşleştirmek istediğinizde, klasik celcius'u farenheit'e dönüştürmeyle aynı problemdir.
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)
İlk aralıktaki her birim aralığı, ikinci aralıkta (dc) / (ba) "boşluk" kaplar.
Sözde:
var interval = (d-c)/(b-a)
for n = 0 to (b - a)
print c + n*interval
Yuvarlamayı nasıl idare edeceğiniz size kalmış.
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);
Elbette, sıfıra bölme kontrolleri ile.
[a - b] aralığınız varsa ve [c - d] ile eşlemek istiyorsanız, burada x eşlemek istediğiniz değerdir, bu formülü kullanın (doğrusal eşleme)
double R = (d-c)/(b-a)
double y = c+(x*R)+R
return(y)
Burada X, eşlemek için sayıdır , A - B için C - D ve Y, sonuç: lineer interpolasyon formülü LERP (al a , b , m ) = bir + ( m, * ( b - a )), ve koymak C ve D yerine bir ve b için Y = C + ( m * ( D - C )). Sonra m yerine ( X -A ) / ( B - A ) elde etmek için Y, = C + ((( X - Bir ) / ( B - A * ()) D - Cı )). Bu iyi bir harita işlevidir, ancak basitleştirilebilir. ( D - C ) parçasını alın ve Y = C + ((( X - A ) * ( D - C )) / ( B - A )) elde etmek için kar payının içine koyun . Bu bize basitleştirebileceğimiz başka bir parça verir, ( X - A ) * ( D- C ), yani ( X * D ) - ( X * C ) - ( A * D ) + ( A * C ) ' ye eşittir . Açın ve Y = C + ((( X * D ) - ( X * C ) - ( A * D ) + ( A * C )) / ( B - A )) elde edin. Yapmanız gereken bir sonraki şey, + C bitini eklemek . Bunu yapmak için, C'yi ( B - A) (( B * C ) - ( A * C )) elde etmek için ve Y = ((( X * D ) - ( X * C ) - ( A * D ) + ( A * C ) + ( B * C ) - ( A * C )) / ( B - A )). Bu , birbirini iptal eden hem a + ( A * C ) hem de a - ( A * C ) içeren fazlalıktır . Bunları kaldırırsanız şunların nihai sonucunu alırsınız:Y = (( X * D ) - ( X * C ) - ( A * D ) + ( B * C )) / ( B - A )
TL; DR: Standart harita fonksiyonu, Y = C + ((( X - A ) / ( B - A )) * ( D - C )), Y = (( X * D ) - ( X * C ) - ( A * D ) + ( B * C )) / ( B - A )