Skip to content

Instantly share code, notes, and snippets.

@jmbr
Last active May 14, 2022 04:40
Show Gist options
  • Save jmbr/1345f9be5fac48edd86ccab63d44f746 to your computer and use it in GitHub Desktop.
Save jmbr/1345f9be5fac48edd86ccab63d44f746 to your computer and use it in GitHub Desktop.
Reparameterize a curve by its arc-length.
"""Numerically reparameterize a curve by its arc-length.
"""
from typing import Optional
import numpy as np
import scipy
import scipy.interpolate
def reparameterize(X: np.ndarray, num_steps: Optional[int] = None) \
-> np.ndarray:
"""Reparameterize a closed curve by its arc-length.
Parameters
----------
X: np.ndarray
An array of shape (num_points, 2) containing the points of the curve.
num_steps: int or None
Number of steps for the reparameterized curve. If set to None, the
resulting curve contains the same number of points as the original
curve.
Returns
-------
Y: np.ndarray
An array containing the points of the reparameterized curve.
"""
def interpolator(x, y):
return scipy.interpolate.PchipInterpolator(x, y, extrapolate=True)
n = X.shape[0]
t = np.linspace(0, 1, n)
x1, x2 = interpolator(t, X[:, 0]), interpolator(t, X[:, 1])
dx1, dx2 = x1.derivative(), x2.derivative()
s = np.cumsum(np.sqrt(dx1(t)**2 + dx2(t)**2))
tau = interpolator(s, t)
ss = np.linspace(s[0], s[-1], num_steps or n)
return np.c_[x1(tau(ss)), x2(tau(ss))]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment