Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

Y = (X-A)/(B-A) * (D-C) + C

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

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

Каждый единичный интервал в первом диапазоне занимает (d-c)/(b-a) "пробел" во втором диапазоне.

Псевдо:

var interval = (d-c)/(b-a)
for n = 0 to (b - a)
    print c + n*interval

Как вы справляетесь с округлением, зависит от вас.

Ответ 6

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);

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

Ответ 7

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

reverseX = (B-A)*(Y-C)/(D-C) + A

Ответ 8

если ваш диапазон от [a до b] и вы хотите отобразить его в [c до d], где x - это значение, которое вы хотите отобразить, используйте эту формулу (линейное отображение)

double R = (d-c)/(b-a)
double y = c+(x*R)+R
return(y)