Информация об изменениях

Сообщение Re[2]: Подскажите либу для сплайна от 27.09.2023 15:11

Изменено 27.09.2023 17:25 Chorkov

Re[2]: Подскажите либу для сплайна
Здравствуйте, 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()
Re[2]: Подскажите либу для сплайна
Здравствуйте, 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()