Математические числа

Как сопоставить числа, линейно, между a и b, чтобы перейти между c и d.

То есть, я хочу, чтобы числа от 2 до 6 отображались на номера от 10 до 20 … но мне нужен обобщенный случай.

Мой мозг жарится.

Если ваше число X падает между A и B, и вы хотите, чтобы Y упал между C и D, вы можете применить следующее линейное преобразование:

Y = (XA) / (BA) * (DC) + C

Это должно дать вам то, что вы хотите, хотя ваш вопрос немного неоднозначен, поскольку вы также можете отобразить интервал в обратном направлении. Просто следите за делением на ноль, и вы должны быть в порядке.

Разделите, чтобы получить соотношение между размерами двух диапазонов, затем вычтите начальное значение вашего внутреннего диапазона, умножьте на коэффициент и добавьте начальное значение вашего второго диапазона. Другими словами,

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

Это равномерно распределяет числа из первого диапазона во втором диапазоне.

Было бы неплохо иметь эту функциональность в classе 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; } 

Я помещаю этот код здесь как ссылку на будущее, и, возможно, это поможет кому-то.

В стороне, это та же проблема, что и classический конвертировать celcius в farenheit, где вы хотите отобразить диапазон чисел, который равен 0 – 100 (C), до 32 – 212 (F).

Каждый единичный интервал в первом диапазоне занимает (dc) / (ba) «пробел» во втором диапазоне.

Псевдо:

 var interval = (dc)/(ba) 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); 

Конечно, с проверкой на деление на ноль.

В дополнение к ответу @PeterAllenWebb, если вы хотите отменить результат, используйте следующее:

 reverseX = (BA)*(YC)/(DC) + A 
Давайте будем гением компьютера.