Smooth spline representation of an arbitrary contour, f(length) --> x,y

后端 未结 2 1594
生来不讨喜
生来不讨喜 2020-12-02 19:24

Suppose I have a set of x,y coordinates that mark points along contour. Is there a way that I can build a spline representation of the contour that I can evaluate at a parti

相关标签:
2条回答
  • 2020-12-02 19:48

    You want to use a parametric spline, where instead of interpolating y from the x values, you set up a new parameter, t, and interpolate both y and x from the values of t, using univariate splines for both. How you assign t values to each point affects the result, and using distance, as your question suggest, may be a good idea:

    from __future__ import division
    import numpy as np
    import matplotlib.pyplot as plt
    import scipy.interpolate
    
    x = np.array([ 2.,  1.,  1.,  2.,  2.,  4.,  4.,  3.])
    y = np.array([ 1.,  2.,  3.,  4.,  2.,  3.,  2.,  1.])
    plt.plot(x,y, label='poly')
    
    t = np.arange(x.shape[0], dtype=float)
    t /= t[-1]
    nt = np.linspace(0, 1, 100)
    x1 = scipy.interpolate.spline(t, x, nt)
    y1 = scipy.interpolate.spline(t, y, nt)
    plt.plot(x1, y1, label='range_spline')
    
    t = np.zeros(x.shape)
    t[1:] = np.sqrt((x[1:] - x[:-1])**2 + (y[1:] - y[:-1])**2)
    t = np.cumsum(t)
    t /= t[-1]
    x2 = scipy.interpolate.spline(t, x, nt)
    y2 = scipy.interpolate.spline(t, y, nt)
    plt.plot(x2, y2, label='dist_spline')
    
    plt.legend(loc='best')
    plt.show()
    

    enter image description here

    0 讨论(0)
  • 2020-12-02 20:09

    Here is an example using splprep and splev:

    import numpy as np
    import scipy.interpolate
    from matplotlib.pyplot import plot
    
    # x,y coordinates of contour points, not monotonically increasing
    x = np.array([2.,  1.,  1.,  2.,  2.,  4.,  4.,  3.])
    y = np.array([1.,  2.,  3.,  4.,  2.,  3.,  2.,  1.])
    
    # f: X --> Y might not be a 1:1 correspondence
    plot(x, y, '-o')
    
    # get the cumulative distance along the contour
    dist = np.sqrt((x[:-1] - x[1:])**2 + (y[:-1] - y[1:])**2)
    dist_along = np.concatenate(([0], dist.cumsum()))
    
    # build a spline representation of the contour
    spline, u = scipy.interpolate.splprep([x, y], u=dist_along, s=0)
    
    # resample it at smaller distance intervals
    interp_d = np.linspace(dist_along[0], dist_along[-1], 50)
    interp_x, interp_y = scipy.interpolate.splev(interp_d, spline)
    plot(interp_x, interp_y, '-o')
    

    0 讨论(0)
提交回复
热议问题