Нахождение длины кубического B-сплайна

Используя функцию scipy interpolate.splprep, получите параметрический сплайн по параметру u, но область u не является линейным интегралом сплайна, это кусочно-линейное соединение входных координат. Я пробовал integrate.splint, но это дает только отдельные интегралы более u. Очевидно, я могу численно интегрировать кучу декартовых дифференциальных расстояний, но мне было интересно, существует ли метод замкнутой формы для получения длины сплайна или сегмента сплайна (с использованием scipy или numpy), на который я не обращал внимания.

Изменить: я ищу решение в закрытой форме или очень быстрый способ перейти к ответу с машинной точностью. Я почти отказался от численных методов поиска корня и теперь в первую очередь ищу ответ в закрытой форме. Если у кого-то есть опыт интеграции эллиптических функций или кто-то может указать мне хороший ресурс (кроме Wolfram), это было бы здорово.

Я собираюсь попробовать Maxima, чтобы попытаться получить неопределенный интеграл того, что, по моему мнению, является функцией для одного сегмента сплайна: я разместил это на MathOverflow


person Paul    schedule 02.02.2010    source источник


Ответы (2)


Поскольку оба x и y являются кубическими параметрическими функциями, не существует закрытого решения в терминах простых функций. Численное интегрирование - это лучший способ. Либо интегрирование выражения длины дуги, либо просто добавление длин отрезков линии - зависит от требуемой точности и от того, сколько усилий вы хотите приложить.

Точный и быстрый метод добавления отрезков линии:

Использование рекурсивного подразделения (разновидность алгоритма де Кастельо) для генерации точек может дать вам очень точное представление с минимальным количеством точек. Подразделяйте подразделения только в том случае, если они не соответствуют критериям. Обычно критерии основываются на длине, соединяющей контрольные точки (корпус или клеть). Для кубики обычно сравнивают близость P0P1 + P1P2 + P2P3 к P0P3, где P0, P1, P2 и P3 - контрольные точки, которые определяют ваш Безье.

Вы можете найти здесь код Delphi: текст ссылки

Преобразование в Python должно быть относительно простым. Это будет генерировать очки. Код уже вычисляет длину сегментов, чтобы проверить критерии. Вы можете просто накапливать эти значения длины по пути.

person symmetry    schedule 02.02.2010
comment
Это решение хорошо подходит для приближений, но я должен был указать в своем вопросе, что мне нужен точный или машинный ответ. Это похоже на решение ромберга EOL, но мне пришлось бы повторять его на чистом питоне. - person Paul; 04.02.2010
comment
Поскольку общее аналитическое решение включает эллиптические интегралы, вы будете численно интегрировать, независимо от того, какой подход вы выберете. Описанный мною метод не интегрирует напрямую выражение длины дуги, но также представляет собой числовое интегрирование. Все, что имеет значение, - это то, что метод сходится к желаемой точности за желаемое время. - person symmetry; 04.02.2010
comment
Чтобы быть более точным в отношении тех длин, которые я имел в виду, вы будете накапливаться по пути ... посмотрите здесь: steve.hollasch.net/cgindex/curves/cbezarclen.html Используйте среднее значение длины корпуса (L1) и длины хорды (L0), чтобы приблизительно определить длину дуги отдельные подсегменты. - person symmetry; 04.02.2010

Вы можете интегрировать функцию sqrt(x'(u)**2+y'(u)**2) через u, где вы вычисляете производные x' и y' ваших координат с помощью scipy.interpolate.splev. Интеграцию можно выполнить с помощью одной из подпрограмм из scipy.integrate (quad точно [Кленшоу-Кертис], romberg обычно быстрее). Это должно быть более точным и, вероятно, быстрее, чем сложение множества небольших расстояний (что эквивалентно интеграции с правилом прямоугольника).

person Eric O Lebigot    schedule 02.02.2010
comment
Мне нравится это решение, так как вы можете установить желаемую точность, но, к сожалению, я предпочитаю точность машинного типа. Я реализовал ваше предложение, но QUADPACK (каким бы классным он ни был) не соответствует моим требованиям к производительности. В настоящее время я ищу решение в закрытой форме и разместил перекрестные сообщения на MathOverflow. Кстати: Кленшоу-Кертис точен только для многочленов. Длина этого сплайна является эллиптической функцией. - person Paul; 04.02.2010