Interpolación local de orden superior de curvas implícitas en Python
Dado un conjunto de puntos que describen alguna trayectoria en el plano 2D, me gustaría proporcionar una representación fluida de esta trayectoria con interpolación local de alto orden.
Por ejemplo, supongamos que definimos un círculo en 2D con 11 puntos en la figura a continuación. Me gustaría agregar puntos entre cada par de puntos consecutivos en orden o producir una traza suave. Agregar puntos en cada segmento es bastante fácil, pero produce discontinuidades de pendiente típicas de una "interpolación lineal local". Por supuesto, no es una interpolación en el sentido clásico, porque
la función puede tener múltiplesy
valores para un determinadox
simplemente agregar más puntos en la trayectoria estaría bien (no se necesita una representación continua).así que no estoy seguro de cuál sería el vocabulario adecuado para esto.
El código para producir esta figura se puede encontrar a continuación. La interpolación lineal se realiza con ellin_refine_implicit
función. Estoy buscando una solución de orden superior para producir un trazado suave y me preguntaba si hay una manera de lograrlo con las funciones clásicas en Scipy. He tratado de usar varias interpolaciones 1D descipy.interpolate
sin mucho éxito (de nuevo debido a múltiplesy
valores para un determinadox
)
El objetivo final es utilizar este método para proporcionar una trayectoria de GPS suave a partir de mediciones discretas, por lo que creo que esto debería tener una solución clásica en algún lugar.
import numpy as np
import matplotlib.pyplot as plt
def lin_refine_implicit(x, n):
"""
Given a 2D ndarray (npt, m) of npt coordinates in m dimension, insert 2**(n-1) additional points on each trajectory segment
Returns an (npt*2**(n-1), m) ndarray
"""
if n > 1:
m = 0.5*(x[:-1] + x[1:])
if x.ndim == 2:
msize = (x.shape[0] + m.shape[0], x.shape[1])
else:
raise NotImplementedError
x_new = np.empty(msize, dtype=x.dtype)
x_new[0::2] = x
x_new[1::2] = m
return lin_refine_implicit(x_new, n-1)
elif n == 1:
return x
else:
raise ValueError
n = 11
r = np.arange(0, 2*np.pi, 2*np.pi/n)
x = 0.9*np.cos(r)
y = 0.9*np.sin(r)
xy = np.vstack((x, y)).T
xy_highres_lin = lin_refine_implicit(xy, n=3)
plt.plot(xy[:,0], xy[:,1], 'ob', ms=15.0, label='original data')
plt.plot(xy_highres_lin[:,0], xy_highres_lin[:,1], 'dr', ms=10.0, label='linear local interpolation')
plt.legend(loc='best')
plt.plot(x, y, '--k')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('GPS trajectory')
plt.show()