Вот контурная карта, для которой доступны все полигоны уровней.
Давайте спросим, как сгладить полигоны, сохранив все вершины в их точных местоположениях?
Действительно, контур сделан поверх данных сетки, вы можете предложить затем сгладить данные сетки, и, следовательно, полученный контур будет более гладким. Обратите внимание, что это не работает, как я хочу, так как функция сглаживания, такая как фильтр Гаусса, удалит небольшие пакеты данных и изменит диапазон третьей переменной, например, высоту, которая не разрешена в моем приложении.
На самом деле я ищу кусок кода (желательно на Python ), который может выполнять сглаживание 2D-полигонов (любого типа: выпуклый, вогнутый, самопересекающийся и т. Д.), Достаточно безболезненный (забудьте страницы кодов) и точный.
К вашему сведению, в ArcGIS есть функция , которая прекрасно справляется с этой задачей, но использование сторонних коммерческих приложений не является моим выбором для этого вопроса.
1)
Scipy.interpolate:
Как видите, полученные сплайны (красные) не являются удовлетворительными!
2)
Вот результат, используя код, приведенный здесь . Это не работает хорошо!
3)
Для меня лучшим решением должно быть что-то вроде следующего рисунка, на котором квадрат постепенно сглаживается путем изменения только одного значения. Я надеюсь на похожую концепцию для сглаживания любой формы многоугольников.
Удовлетворяя условию, что сплайн проходит точки:
4)
Вот моя реализация «идеи Вубера» строка за строкой в Python на его данных. Возможно, есть некоторые ошибки, так как результаты не очень хорошие.
K = 2 - это катастрофа и поэтому для k> = 4.
5)
Я удалил одну точку в проблемном месте, и полученный сплайн теперь идентичен сплайну. Но это все еще вопрос, почему метод не работает для всех случаев?
6)
Хорошее сглаживание для данных whuber может быть следующим (нарисованным программным обеспечением векторной графики), в котором плавно добавляется дополнительная точка (сравните с обновлением)
4):
7)
Смотрите результат из Python-версии кода whuber для некоторых иконических фигур:
Обратите внимание, что этот метод не работает для полилиний. Для угла полилинии (контур) зеленый это то, что я хочу, но получил красный. Это необходимо учитывать, поскольку контурные карты всегда являются полилиниями, хотя замкнутые полилинии можно рассматривать как многоугольники, как в моих примерах. Также не то, что проблема, возникшая в обновлении 4, еще не решена.
8) [мой последний]
Вот окончательное решение (не идеальное!):
Помните, что вам придется что-то делать с областью, на которую указывают звезды. Возможно, в моем коде есть ошибка, или предложенный метод нуждается в дальнейшей разработке, чтобы рассмотреть все ситуации и предоставить желаемые результаты.
Ответы:
Большинство методов сплайнования последовательностей чисел сплайн-полигонов. Хитрость заключается в том, чтобы сплайны плавно «закрывались» на конечных точках. Для этого «оберните» вершины вокруг концов. Затем сплайн x- и y-координаты отдельно.
Вот рабочий пример в
R
. Он использует кубическуюspline
процедуру по умолчанию, доступную в пакете базовой статистики. Для большего контроля, замените почти любую процедуру, которую вы предпочитаете: просто убедитесь, что она проходит через числа (то есть интерполирует их), а не просто используя их в качестве «контрольных точек».Чтобы проиллюстрировать его использование, давайте создадим небольшой (но сложный) многоугольник.
Сплайн это, используя предыдущий код. Чтобы сделать сплайн более гладким, увеличьте количество вершин со 100; чтобы сделать его менее плавным, уменьшите количество вершин.
Чтобы увидеть результаты, мы наносим (а) исходный многоугольник пунктирной красной линией, показывая зазор между первой и последней вершинами (т. Е. Не закрывая граничную ломаную); и (b) сплайн серого цвета, еще раз показывающий его зазор. (Поскольку разрыв настолько мал, его конечные точки выделены синими точками.)
источник
Я знаю, что это старая запись, но она появилась в Google для чего-то, что я искал, поэтому я решил опубликовать свое решение.
Я не рассматриваю это как упражнение по подгонке 2D кривой, а скорее как 3D. Рассматривая данные как трехмерные, мы можем гарантировать, что кривые никогда не пересекаются, и можем использовать информацию из других контуров, чтобы улучшить нашу оценку для текущего.
В следующем извлечении iPython используется кубическая интерполяция, предоставляемая SciPy. Обратите внимание, что значения z, которые я вычерчивал, не важны, поскольку все контуры равноудалены по высоте.
Результаты здесь выглядят не лучшим образом, но с таким небольшим количеством контрольных точек они по-прежнему совершенно достоверны. Обратите внимание, как вытянутая зеленая линия вытянута, чтобы следовать более широкому синему контуру.
источник
Я написал почти тот пакет, который вы ищете ... но он был на Perl и был более десяти лет назад: GD :: Polyline . Он использовал 2D кубические кривые Безье и «сгладил» произвольный многоугольник или «полилинию» (тогда меня называли тем, что сейчас обычно называют «LineString»).
Алгоритм состоял из двух шагов: учитывая точки в многоугольнике, добавьте две контрольные точки Безье между каждой точкой; затем вызовите простой алгоритм, чтобы сделать кусочную аппроксимацию сплайна.
Вторая часть проста; первая часть была немного искусства. Здесь было прозрение: рассмотреть «сегмент управления» вершинного N:
vN
. Сегмент управления было три коллинеарных точки:[cNa, vN, cNb]
. Центральной точкой была вершина. Наклон этого контрольного сегмента был равен наклону от вершины N-1 до вершины N + 1. Длина левой части этого сегмента составляла 1/3 длины от вершины N-1 до вершины N, а длина правой части этого сегмента составляла 1/3 длины от вершины N до вершины N + 1.Если исходная кривая была четыре вершины:
[v1, v2, v3, v4]
то каждая вершина теперь получить сегмент управления в виде:[c2a, v2, c2b]
. Соедините их вместе вот так:[v1, c1b, c2a, v2, c2b, c3a, v3, c3b, c4a, v4]
и жуйте их по четыре за четыре точки Безье:[v1, c1b, c2a, v2]
затем[v2, c2b, c3a, v3]
, и так далее. Поскольку[c2a, v2, c2b]
были коллинеарны, результирующая кривая будет гладкой в каждой вершине.Таким образом, это также соответствует вашему требованию для параметризации «плотности» кривой: используйте меньшее значение, чем 1/3, для «более жесткой» кривой, большее значение для «более плотной» подгонки. В любом случае результирующая кривая всегда проходит через исходные заданные точки.
Это привело к плавной кривой, которая «описала» исходный полигон. У меня также был какой-то способ «вписать» плавную кривую ... но я не вижу этого в коде CPAN.
Во всяком случае, в настоящее время у меня нет версии, доступной на Python, и у меня нет цифр. НО ... если / когда я перенесу это на Python, я обязательно опубликую здесь.
источник