Как сопоставить числа, линейно, между a и b, чтобы перейти между c и d.Math - номера карт
То есть, я хочу, чтобы числа между 2 и 6 отображались на номера от 10 до 20 ... но мне нужен обобщенный случай.
Мой мозг жарится.
Как сопоставить числа, линейно, между a и b, чтобы перейти между c и d.Math - номера карт
То есть, я хочу, чтобы числа между 2 и 6 отображались на номера от 10 до 20 ... но мне нужен обобщенный случай.
Мой мозг жарится.
Разделите, чтобы получить соотношение между размерами двух диапазонов, затем вычтите начальное значение вашего внутреннего диапазона, умножьте на коэффициент и добавьте начальное значение вашего второго диапазона. Другими словами,
R = (20 - 10)/(6 - 2)
y = (x - 2) * R + 10
Это равномерно распространяет числа из первого диапазона во втором диапазоне.
Это не работает. Мой диапазон от 1000000000 до 9999999999, и цифры могут быть от 1 до 999999999. – Dejell 2013-02-19 09:39:27
@Odelya Конечно, это работает. Это достаточно простая математическая трансформация. Вам просто нужно использовать достаточно большой тип номера (bignum или аналогичный). Ваши номера просто слишком велики для 32-битных целых чисел, но, например, будут работать 64-битные целые числа. – 2013-02-19 11:40:01
Они типа двойные. двойной R = (20 - 10)/(6 - 2); \t \t double y = (X - 2) * R + 10; – Dejell 2013-02-19 11:43:23
Если число X падает между А и В, и вы хотели бы Y упасть между C и D, можно применить следующий линейное преобразование:
Y = (XA)/(BA) * (DC) + 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 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);
С проверкой на деление на ноль, конечно.
В стороне, это та же проблема, что и классический конвертировать celcius в farenheit, где вы хотите отобразить диапазон чисел, который равен 0 - 100 (C) - 32 - 212 (F).
В дополнение к @PeterAllenWebb ответ, если вы хотели бы обратить назад результат использовать следующее:
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;
}
Я помещаю этот код здесь в качестве ссылки на будущее себя и может быть, это поможет кому-то.
Двухточечная форма. http://en.wikipedia.org/wiki/Linear_equation#Two-point_form – kennytm 2010-03-06 18:53:49