Линейная интерполяция между двумя числами с шагом

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

Допустим, я хочу интерполировать от 4 до 22 с 8 промежуточными шагами, например: Пример

Легко понять, что здесь x+2. Но что, если начальное значение равно 5, а конечное значение равно 532 с 12 промежуточными шагами? (В моем особом случае мне понадобится начальное и конечное значение с 16 шагами между ними)

Как вы получили x+2? Можете ли вы решить свой второй пример вручную?

Code-Apprentice 09.04.2019 22:00

Это дало бы что-то уродливое @ кодовый ученик, но: 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 09.04.2019 22:04

@Pouissante Что ты хочешь вместо этого?

Code-Apprentice 09.04.2019 22:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
3
3 029
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Если у вас есть два столба забора и вы помещаете между ними 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 07.06.2019 18:01

@Pouissante Ваши «шаги» на самом деле являются сообщениями в моем примере. Если вы думаете о «шагах» как о пространстве между постами, ваш новый способ мышления — пренебрегать шагом от последнего промежуточного поста до самого правого поста. Если есть первый шаг, последний шаг и N промежуточных шагов, чтобы перейти от первого к последнему (начиная с первого) означает, что вам нужно сделать (N + 2) - 1 шагов; +2, потому что N промежуточных шагов + 1 начальный шаг + 1 последний шаг; -1, потому что предполагается, что вы уже находитесь на начальном шаге, поэтому не нужно делать шаг, чтобы коснуться его.

Patrick87 07.06.2019 22:19

Для выполнения линейной интерполяции используйте 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; }

Спасибо за пример. Если шаг не целое число, я его приведу, мне не нужны плавающие точки.

Pouissante 09.04.2019 22:19

На самом деле я намерен опубликовать второй ответ, потому что это совсем другая методология, которая может лучше соответствовать вашим потребностям.

VPellen 09.04.2019 22:23

Ммм, оглядываясь назад, мне трудно понять, почему у него 9 шагов, поскольку мне нужно «обнаружить» 8 чисел.

Pouissante 07.06.2019 17:59

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

VPellen 08.06.2019 04:48

Я не решаюсь дать два отдельных ответа, но я чувствую, что эта методология достаточно уникальна по сравнению с другой. Есть полезная функция, которая может быть именно тем, что вам нужно, и она называется 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);
}

Другие вопросы по теме