2015-01-01 6 views
6

Я ищу алгоритм упрощения и сглаживания путей для 2D-траекторий. Поэтому у меня есть упорядоченный список двумерных точек. Эти точки должны быть упрощены, например. с алгоритмом Рамера-Дугласа-Пьюкера. Но выход должен быть плавным, поэтому результирующий путь должен быть построен из кривых Безье или сплайнов. Есть ли какая-либо модификация алгоритма Рамера-Дугласа-Пьюкера, который мог бы справиться с этим?Алгоритм упрощения пути и сглаживания 2D-траекторий

Я нашел алгоритм упрощения пути в библиотеке paper.js, который выполняет именно то, что я ищу: http://paperjs.org/examples/path-simplification/ Но я не смог понять алгоритм из недокументированного исходного кода JavaScript.

ответ

10

работа, которую вы хотят делать падения в категорию «подгонка кривой». Существует множество различных алгоритмов для подгонки кривой, но почти все алгоритмы подгонки кривой можно разделить на две разные категории: интерполяцию и приближение. Алгоритмы интерполяции производят кривую, которая точно проходит через все точки данных, в то время как алгоритмы аппроксимации генерируют кривую, которая находится близко к точкам данных. Конечно, существуют и гибридные алгоритмы.

Поскольку вы хотите, чтобы точки данных были сглажены, вы должны искать алгоритмы аппроксимации. Для двух алгоритмов, которые вы упомянули: алгоритм RDP и алгоритм Schneider (тот, что в Paper.js), они оба являются алгоритмами аппроксимации. Таким образом, в основном вы можете использовать любой из них. Для RDP после получения упрощенного пути вы можете использовать создание сплайна Catmull Rom или сплайна Overhauser через вершины упрощенного пути для получения гладкой кривой. Однако у вас нет прямого контроля за отклонение между полученным сплайном и вершинами исходного пути.

Для алгоритма Schneider он начнется с подгонки точек данных кубической кривой Безье с граничными касательными ограничениями. Если отклонение от результирующей кривой слишком велико, то он разделит точки данных на две «области» и поместит каждую область данных с кубическими кривыми Безье с граничными касательными ограничениями. Этот процесс будет повторяться до тех пор, пока отклонение ко всем кривым Безье не будет достаточно маленьким.В результате получается серия кубических кривых Безье, соединенных в лучшем случае с непрерывностью C1 (скорее всего, это только G1). Кроме того, поскольку этот алгоритм оценивает конечные тангенсы от исходных точек данных, шум в точке данных будет влиять на оценку касания конца и, следовательно, на кубическую установку Безье.

Если вы можете потратить время на тему подгонки кривой, вы должны посмотреть на наименьшее квадратное фитинг с кривыми B-сплайнов. Это будет генерировать выходную кривую с высокой непрерывностью (C2 для кубических кривых B-сплайна, например). Если у вас мало времени на проведение, то алгоритм Шнайдера - хороший выбор, который уравновешивает баланс между стоимостью реализации (если вам нужно повторно реализовать его на определенном языке) и качеством полученной кривой.

4

То, что вы, скорее всего, после того, как называется Curve Fitting.

Хотя Ramer-Дуглас-Peucker алгоритм существенно сглаживает «шум» из полилинии путем удаления ненужных точек - алгоритм подбора кривой будет соответствовать Безье кривые через эти точки.

Here - довольно хороший пример на Youtube, а here - это оригинальная статья, описывающая сам алгоритм.


Что касается примера Paper.js:

  • This ссылка Github для этой конкретной функциональности вы упомянули, и это очень хорошо документирован. Исследовательской статьей был использован this.

  • Также here очень короткое обсуждение в списке рассылки о , что было использовано, а что нет (по-видимому, Ramer-Дуглас-Peucker использовали но удалены позже)

Смежные вопросы