У меня небольшие проблемы с тем, как линейно интерполировать между двумя числами с определенным количеством промежуточных шагов.
Допустим, я хочу интерполировать от 4 до 22 с 8 промежуточными шагами, например: Пример
Легко понять, что здесь x+2. Но что, если начальное значение равно 5, а конечное значение равно 532 с 12 промежуточными шагами? (В моем особом случае мне понадобится начальное и конечное значение с 16 шагами между ними)
Это дало бы что-то уродливое @ кодовый ученик, но: 45.53846154 86.07692308 126.6153846 167.1538462 207.6923077 248.2307692 288.7692308 329.3076923 369.8461538 410.3846154 450.9230769 491.4615385
@Pouissante Что ты хочешь вместо этого?
Если у вас есть два столба забора и вы помещаете между ними k столбов забора, вы создаете k + 1 пробелов. Например:
| |
post1 post2
adding one posts creates two spaces
| | |
post1 post2
Если вы хотите, чтобы эти k + 1 пробелы были равны, вы можете разделить общее расстояние на k + 1, чтобы получить расстояние между соседними постами.
d = 22 - 4 = 18
k = 8
e = d / (k + 1) = 18 / 9 = 2
В вашем другом примере ответ
d = 532 - 5 = 527
k = 12
e = d / (k + 1) = 527 / 13 ~ 40.5
Ммм, оглядываясь назад, мне трудно понять, почему у него 9 шагов, поскольку мне нужно «обнаружить» 8 чисел. Если я возьму пример с вашими сообщениями, я могу только понять, что я разместил 7 сообщений между началом и концом, поэтому k + 1 будет 8?
@Pouissante Ваши «шаги» на самом деле являются сообщениями в моем примере. Если вы думаете о «шагах» как о пространстве между постами, ваш новый способ мышления — пренебрегать шагом от последнего промежуточного поста до самого правого поста. Если есть первый шаг, последний шаг и N промежуточных шагов, чтобы перейти от первого к последнему (начиная с первого) означает, что вам нужно сделать (N + 2) - 1 шагов; +2, потому что N промежуточных шагов + 1 начальный шаг + 1 последний шаг; -1, потому что предполагается, что вы уже находитесь на начальном шаге, поэтому не нужно делать шаг, чтобы коснуться его.
Для выполнения линейной интерполяции используйте Mathf.MoveTowards()
.
Чтобы определить максимальную дельту (т. е. величину, на которую вы хотите, чтобы она перемещалась на каждом шаге), возьмите разницу, а затем разделите ее на количество желаемых шагов.
var start = 4;
var end = 22;
var distance = end - start;
var steps = 9; // Your example technically has 9 steps, not 8
var delta = distance / steps;
Обратите внимание, что это удобно предполагает, что ваш distance
является чистым кратным steps
. Если вы не знаете, что это так, и важно, чтобы вы никогда не превышали это количество шагов, вы можете явно проверить это. Вот грубый пример для целого числа. Методы с плавающей запятой могут быть более сложными:
if (distance % delta > 0) { delta += 1; }
Спасибо за пример. Если шаг не целое число, я его приведу, мне не нужны плавающие точки.
На самом деле я намерен опубликовать второй ответ, потому что это совсем другая методология, которая может лучше соответствовать вашим потребностям.
Ммм, оглядываясь назад, мне трудно понять, почему у него 9 шагов, поскольку мне нужно «обнаружить» 8 чисел.
Это зависит от того, считаете ли вы свое начальное значение шагом или считаете шаги актом перехода от одного значения к другому.
Я не решаюсь дать два отдельных ответа, но я чувствую, что эта методология достаточно уникальна по сравнению с другой. Есть полезная функция, которая может быть именно тем, что вам нужно, и она называется Mathf.Lerp()
.
var start = 5;
var end = 532;
var steps = 13;
for (int i = 0; i <= steps; i++) {
// The type conversion is necessary because both i and steps are integers
var value = Mathf.Lerp(start, end, i / (float)steps);
Debug.Log(value);
}
Как вы получили
x+2
? Можете ли вы решить свой второй пример вручную?