B-spline interpolation with Python

后端 未结 3 1425
小鲜肉
小鲜肉 2021-01-31 21:41

I am trying to reproduce a Mathematica example for a B-spline with Python.

The code of the mathematica example reads

pts = {{0, 0}, {0, 2}, {2, 3}, {4, 0         


        
3条回答
  •  说谎
    说谎 (楼主)
    2021-01-31 22:16

    Use this function i wrote for another question i asked here.

    In my question i was looking for ways to calculate bsplines with scipy (this is how i actually stumbled upon your question).

    After much obsession, i came up with the function below. It'll evaluate any curve up to the 20th degree (way more than we need). And speed wise i tested it for 100,000 samples and it took 0.017s

    import numpy as np
    import scipy.interpolate as si
    
    
    def bspline(cv, n=100, degree=3, periodic=False):
        """ Calculate n samples on a bspline
    
            cv :      Array ov control vertices
            n  :      Number of samples to return
            degree:   Curve degree
            periodic: True - Curve is closed
                      False - Curve is open
        """
    
        # If periodic, extend the point array by count+degree+1
        cv = np.asarray(cv)
        count = len(cv)
    
        if periodic:
            factor, fraction = divmod(count+degree+1, count)
            cv = np.concatenate((cv,) * factor + (cv[:fraction],))
            count = len(cv)
            degree = np.clip(degree,1,degree)
    
        # If opened, prevent degree from exceeding count-1
        else:
            degree = np.clip(degree,1,count-1)
    
    
        # Calculate knot vector
        kv = None
        if periodic:
            kv = np.arange(0-degree,count+degree+degree-1,dtype='int')
        else:
            kv = np.concatenate(([0]*degree, np.arange(count-degree+1), [count-degree]*degree))
    
    
        # Calculate query range
        u = np.linspace(periodic,(count-degree),n)
    
    
        # Calculate result
        return np.array(si.splev(u, (kv,cv.T,degree))).T
    

    Results for both open and periodic curves:

    cv = np.array([[ 50.,  25.],
       [ 59.,  12.],
       [ 50.,  10.],
       [ 57.,   2.],
       [ 40.,   4.],
       [ 40.,   14.]])
    

提交回复
热议问题