Подскажите либу для сплайна
От: Serpuh фотомер.рф
Дата: 27.09.23 09:31
Оценка:
Посоветуйте либу. Есть точки в пространстве xyz, сплайн визуально на них хорошо ложится. Цель — получить ур-е плоскости в пространстве перпендкулярное сплайну в заданной точке. Или упрошенный вариант — ур-е перпедикулярной прямой для 2d сплайна xy в заданной точке. Среда разработки Линукс.
Re: Подскажите либу для сплайна
От: velkin Удмуртия http://blogs.rsdn.org/effective/
Дата: 27.09.23 09:49
Оценка:
Здравствуйте, Serpuh, Вы писали:

S>Посоветуйте либу. Есть точки в пространстве xyz, сплайн визуально на них хорошо ложится. Цель — получить ур-е плоскости в пространстве перпендкулярное сплайну в заданной точке. Или упрошенный вариант — ур-е перпедикулярной прямой для 2d сплайна xy в заданной точке. Среда разработки Линукс.


Работа с геометрией OpenCascade.
Re[2]: Подскажите либу для сплайна
От: Serpuh фотомер.рф
Дата: 27.09.23 10:40
Оценка:
Здравствуйте, velkin, Вы писали:
V>Работа с геометрией OpenCascade.

Спасибо, но несколько не то, нужна либа типа Eigen. Там есть сплайны, но пока не понял как касательные получать.
Re: Подскажите либу для сплайна
От: kov_serg Россия  
Дата: 27.09.23 11:42
Оценка:
Здравствуйте, Serpuh, Вы писали:

S>Цель — получить ур-е плоскости в пространстве перпендкулярное сплайну в заданной точке. Или упрошенный вариант — ур-е перпедикулярной прямой для 2d сплайна xy в заданной точке. Среда разработки Линукс.



Это ж элементарно:

Rxyz=F(t) — сплайн Rx=Fx(t), Ry=Fy(t), Rz=Fz(t)
t=[0..1]

Fdot(t) — производная от F -- Fdot(t) = (F(t+dt)-F(t)) / dt при dt->0

( r — F(t) , Fdot(t) )=0 -- уравнение плоскости перпендикулярной сплайну, r точка плоскости

или если расписать
(x-Fx(t))*Fdotx(t) + (y-Fy(t))*Fdoty(t) + (z-Fz(t))*Fdotz(t)) = 0

F — зависит от типа сплайна, но обычно это просто полином или много полиномов на разных кусках интервала от 0..1

Для 2d тоже самое только без z координаты
Re[2]: Подскажите либу для сплайна
От: Chorkov Россия  
Дата: 27.09.23 15:11
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Здравствуйте, Serpuh, Вы писали:


S>>Цель — получить ур-е плоскости в пространстве перпендкулярное сплайну в заданной точке. Или упрошенный вариант — ур-е перпедикулярной прямой для 2d сплайна xy в заданной точке. Среда разработки Линукс.


_>

_>Это ж элементарно:

_>Rxyz=F(t) — сплайн Rx=Fx(t), Ry=Fy(t), Rz=Fz(t)

_>t=[0..1]

_>Fdot(t) — производная от F -- Fdot(t) = (F(t+dt)-F(t)) / dt при dt->0


_>( r — F(t) , Fdot(t) )=0 -- уравнение плоскости перпендикулярной сплайну, r точка плоскости


_>или если расписать

_>(x-Fx(t))*Fdotx(t) + (y-Fy(t))*Fdoty(t) + (z-Fz(t))*Fdotz(t)) = 0

_>F — зависит от типа сплайна, но обычно это просто полином или много полиномов на разных кусках интервала от 0..1


_>Для 2d тоже самое только без z координаты


Это элементарно, если есть физический параметр (типа, пройденной дистанции) по которому кривая праметризуется "естественным" образом.
Если есть только точки и они неоднородно распределены в пространстве — то проблема.

Берем точки на окружности, но распределенные неравномерно, (две рядом), и пытаемся применить ваш алгоритм:



  Исходник на питоне
import numpy
import scipy
import matplotlib.pyplot as plt


dt = 0.05
real_t = numpy.array( [0., 1., 2., 2.+dt, 3.+dt, 4.+dt] )
assumed_t = numpy.array( [0., 1., 2., 3., 4., 5.] )
x = numpy.sin( real_t )
y = numpy.cos( real_t )


plt.plot(x, y, 'o', label='input points')
plt.plot(numpy.sin( numpy.linspace( 0., 4.+dt, 100 ) ),
         numpy.cos( numpy.linspace( 0., 4.+dt, 100 ) ), '--', label='cirle')

t_test_plonts = numpy.linspace( min(assumed_t), max(assumed_t), 200 )

for alg, name in  zip([scipy.interpolate.CubicSpline, scipy.interpolate.KroghInterpolator,
                       scipy.interpolate.PchipInterpolator, scipy.interpolate.Akima1DInterpolator],
                      ["Cubic", "Krogh", "Pchip", "Akima1D"]):
    x_spline = alg(assumed_t, x)(t_test_plonts)
    y_spline = alg(assumed_t, y)(t_test_plonts)
    plt.plot(x_spline, y_spline, '-', label=name)

plt.xlim([-1.2, 1.2])
plt.ylim([-1.2, 1.2])
plt.legend()
plt.show()
Отредактировано 27.09.2023 17:25 Chorkov . Предыдущая версия .
Re[3]: Подскажите либу для сплайна
От: kov_serg Россия  
Дата: 27.09.23 17:27
Оценка:
Здравствуйте, Chorkov, Вы писали:

C> Это элементарно, если у есть физический параметр (типа, пройденной дистанции) по которому кривая праметризуется "естественным" образом.

Сплайнфй однопараметрические кривые, в доль этого параметра и строить.

C> Если есть только точки и они неоднородно распределены в пространстве — то проблема.

C>Берем точки на окружности, но распределенные неравномерно, (две рядом), и пытаемся применить ваш алгоритм:
Какой ещё алгоритм?

То что ваши входные данные гавно вырождены и по ним вы построили кривые которые вас не устраивают.
Совершенно не мешает по ним строить касательную и уравнение плоскости для любой точки вдоль них.
Re[4]: Подскажите либу для сплайна
От: Chorkov Россия  
Дата: 28.09.23 10:12
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Здравствуйте, Chorkov, Вы писали:


C>> Это элементарно, если у есть физический параметр (типа, пройденной дистанции) по которому кривая праметризуется "естественным" образом.

_>Сплайнфй однопараметрические кривые, в доль этого параметра и строить.

C>> Если есть только точки и они неоднородно распределены в пространстве — то проблема.

C>>Берем точки на окружности, но распределенные неравномерно, (две рядом), и пытаемся применить ваш алгоритм:
_>Какой ещё алгоритм?

Вот этот:

Rxyz=F(t) — сплайн Rx=Fx(t), Ry=Fy(t), Rz=Fz(t)
t=[0..1]


Поскольку выбор t не описан, я полагаю, что вы выбрали его просто по номерам точек.

_>То что ваши входные данные гавно вырождены и по ним вы построили кривые которые вас не устраивают.

_>Совершенно не мешает по ним строить касательную и уравнение плоскости для любой точки вдоль них.

Никакого вырождения нет: решение устойчиво к небольшим вариациям входных данных.
Число обусловленности (при решении СЛУ на коэффициенты кубического полинома) меньше 100.
Легко придумать пример для числа обусловленности 5, но тогда петля не такая выразительная.
Это баг, связанный с тем, что изменение координат считаются независимыми процессами.

Кроме того, метод чувствителен к выбору направления осей координат.
Для решения этой проблемы изобрели кривые Безье.
Re[5]: Подскажите либу для сплайна
От: kov_serg Россия  
Дата: 28.09.23 13:02
Оценка:
Здравствуйте, Chorkov, Вы писали:

_>>Какой ещё алгоритм?

C>Вот этот:
C>

C>Rxyz=F(t) — сплайн Rx=Fx(t), Ry=Fy(t), Rz=Fz(t)
C>t=[0..1]

Блин это не алгоритм это общая запись любого сплайна

C>Поскольку выбор t не описан, я полагаю, что вы выбрали его просто по номерам точек.

Тут вы сами себе злобный буратино.
C>Никакого вырождения нет: решение устойчиво к небольшим вариациям входных данных.
C>Число обусловленности (при решении СЛУ на коэффициенты кубического полинома) меньше 100.
C>Легко придумать пример для числа обусловленности 5, но тогда петля не такая выразительная.
C>Это баг, связанный с тем, что изменение координат считаются независимыми процессами.
Это не баг. Это неправильно выбранный базис:

  нулевое приближение
import numpy
import math
import scipy
import matplotlib.pyplot as plt

dt = 0.05
real_t = numpy.array( [0., 1., 2., 2.+dt, 3.+dt, 4.+dt] )
assumed_t = numpy.array( [0., 1., 2., 3., 4., 5.] )

x = numpy.sin( real_t )
y = numpy.cos( real_t )

S=[0]
for i in range(1,len(x)):
    ds=math.hypot(x[i-1]-x[i],y[i-1]-y[i])
    S.append(S[i-1]+ds)
assumed_t = numpy.array( S )


plt.plot(x, y, 'o', label='input points')
plt.plot(numpy.sin( numpy.linspace( 0., 4.+dt, 100 ) ),
         numpy.cos( numpy.linspace( 0., 4.+dt, 100 ) ), '--', label='cirle')

t_test_plonts = numpy.linspace( min(assumed_t), max(assumed_t), 200 )

t_p_plonts = numpy.linspace( min(assumed_t), max(assumed_t), 8 )

for alg, name in  zip([scipy.interpolate.CubicSpline, scipy.interpolate.KroghInterpolator,
                       scipy.interpolate.PchipInterpolator, scipy.interpolate.Akima1DInterpolator],
                      ["Cubic", "Krogh", "Pchip", "Akima1D"]):
    x_spline = alg(assumed_t, x)(t_test_plonts)
    y_spline = alg(assumed_t, y)(t_test_plonts)
    plt.plot(x_spline, y_spline, '-', label=name)

for alg, name in  zip([scipy.interpolate.CubicSpline],
                      ["nCubic"]):
    fx=alg(assumed_t, x)
    fy=alg(assumed_t, y)
    x0 = fx(t_p_plonts)
    y0 = fy(t_p_plonts)
    xdot = fx.derivative(1)(t_p_plonts)
    ydot = fy.derivative(1)(t_p_plonts)
    for k in range(len(x0)):
        dl=numpy.array([xdot[k],ydot[k]])
        dl=dl/numpy.linalg.norm(dl)
        dn=numpy.array([dl[1],-dl[0]])*0.1
        px=[ x0[k]-dn[0] , x0[k]+dn[0] ]
        py=[ y0[k]-dn[1] , y0[k]+dn[1] ]
        name_k="%s%d"%(name,k)
        plt.plot(px,py,'-')

plt.xlim([-1.2, 1.2])
plt.ylim([-1.2, 1.2])
plt.legend()
plt.gca().set_aspect('equal', adjustable='box')
plt.show()
Отредактировано 28.09.2023 13:23 kov_serg . Предыдущая версия . Еще …
Отредактировано 28.09.2023 13:03 kov_serg . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.