Я некоторое время осматривался и не могу найти решение этой проблемы. Допустим, у меня есть кубическая кривая Безье (определяемая 4 точками), и я хочу получить набор точек, которые равномерно распределены вдоль кривой. Подумайте о размещении текста вдоль кривой для примера.
Теперь проблема в том, что если я введу t
(значение интерполяции от 0 до 1) с постоянным приращением, точки не будут равномерно распределены. Расстояние вдоль кривой меньше, когда кривая делает поворот, и длиннее, когда кривая прямая.
Итак, как мне разместить точки равномерно по кривой Безье?
interpolation
curves
beziers
Foaly
источник
источник
t
, скажем, на 100 шагов, и измерить расстояния между полученными точками. Затем интерполируйте вдоль этой полилинии по желанию.Ответы:
Это больше математический вопрос. Таким образом, кривая Безье имеет следующую формулу , как в компоненте , так
x
и вy
компоненте.Длина, пройденная
t
по кривойgamma
, определяется как:Нет понятного человеку решения для интеграла, поэтому вы должны приблизиться.
Замените на
gamma(t)
выражение,B(t)
чтобы получить длину,length_B
пройденнуюt
вдоль сегмента Безье. Допустим, он путешествует из0
вL
.Теперь выберите
n
значения между0
иL
которые соответствуют равномерно распределенным точкам. Например, длины формыk*L/n
дляk
от0
доn
.Теперь вам нужно инвертировать функцию
length_B
, чтобы вы могли вычислитьt
спину по длинеl
. Это довольно много математики, и я чертовски ленив, попробуй сделать это сам. Если вы не можете, вы можете перейти к математике стек обмена . Для более полного ответа, вы можете пойти туда в любом случае.Когда у вас есть эта обратная
length_B
функция (или разумное приближение), вы обрабатываете ее довольно просто.l[k]
заданного пути пути от начала координат(P0_x,P1_x)
.t[k]
использованиеlength_B_inverse
.(B_x(t[k]),B_y(t[k]))
.источник
Ну, это было какое-то время ...
Но я наконец-то смог решить эту проблему!
Все, что вам нужно, в этом посте: перемещать корабли между двумя планетами вдоль Безье, пропуская некоторые уравнения для ускорения
источник
Просто чтобы расширить сказанное Марко, обычная техника для этого состоит в том, чтобы идти по кривой с гораздо меньшими приращениями, чем шаги фиксированной длины, которые вы хотите предпринять, и сохранять полученную выходную точку (и, возможно, расстояние?) В таблице.
Затем вы просматриваете таблицу и отбрасываете все записи, кроме тех точек, которые ближе всего к целочисленным кратным расстояниям, которые вы хотите пройти.
Затем у вас остается таблица, которую вы можете очень быстро проиндексировать непосредственно во время выполнения. Если вы хотите перейти к месту, в 5 раз превышающему ваше расстояние, посмотрите в таблицу на индекс [5].
Обратите внимание, что вы могли бы выполнить два шага в одном, и на самом деле не сохранять дополнительные элементы в таблице для начала, но это проще визуализировать и понять в два этапа.
Однажды я видел метод, позволяющий фактически рассчитать это на лету без предварительного вычисления таблицы (он также не использовал итерацию / поиск корня!), Но, к сожалению, я не могу вспомнить детали вообще:
Если я запомню или найду, я опубликую информацию!
источник
Шаг 1 - Генерация N + 1 точек путем интерполяции кривой с шагом 1 / N. N должно быть достаточно большим для хороших визуальных результатов, но достаточно маленьким, чтобы его можно было легко вычислить. Значение 50 должно быть в порядке для большинства ситуаций, но оно должно быть настроено для вашего конкретного случая. Я назову это «интерполированными точками».
В качестве альтернативы вы можете создать короткий список сегментов и рекурсивно разбить каждый сегмент, который длиннее, чем желаемая максимальная длина сегмента (первоначально вы должны сгенерировать как минимум четыре сегмента, чтобы учесть S кривых, где начало очень близко к концу).
Шаг 2 - «Пройдите по линии», используя интерполированные точки и желаемый интервал между каждой точкой.
Я оставлю здесь свой код Unity:
источник
Вот некоторый алгоритм, который дает довольно хорошие результаты:
источник