2016-04-15 26 views
1

指定されたポイントでその関数値と派生関数によって定義される3次多項式を計算したいと思います。私はscipyのダウンロードの補間方法を知っている立方体射影補間補間Python

https://en.wikipedia.org/wiki/Cubic_Hermite_spline

。具体

splprepその誘導体eveluateするN次元スプライン とsplevを補間します。

関数をとるPythonのルーチンがあり、値XF(X)および誘導体F '(x)は対応する値と与えられたデータにフィットスプライン表現を算出します。

例を与えるために:
私はこれらの位置での座標X、Y、Z私は知っている速度X「Y」、Z」オブジェクトのによって規定される空間内の2つのオブジェクトの位置を有します。これで、オブジェクトが時間tに渡って2つのポイント間で取るパスを補間できますか?与えられたすべてのパラメータを考慮に入れます。

答えて

2

BPoly.from_derivativesを使用できます。結果は、バーンスタインベースの多項式です。

1

ev-br's answerを延長すると、BPoly.from_derivativesを使用して、nディメンションの点間を補間する使用例を示すサンプルコードです。

import numpy as np 
from scipy import interpolate 

def sampleCubicSplinesWithDerivative(points, tangents, resolution): 
    ''' 
    Compute and sample the cubic splines for a set of input points with 
    optional information about the tangent (direction AND magnitude). The 
    splines are parametrized along the traverse line (piecewise linear), with 
    the resolution being the step size of the parametrization parameter. 
    The resulting samples have NOT an equidistant spacing. 

    Arguments:  points: a list of n-dimensional points 
        tangents: a list of tangents 
        resolution: parametrization step size 
    Returns:  samples 

    Notes: Lists points and tangents must have equal length. In case a tangent 
      is not specified for a point, just pass None. For example: 
        points = [[0,0], [1,1], [2,0]] 
        tangents = [[1,1], None, [1,-1]] 

    ''' 
    resolution = float(resolution) 
    points = np.asarray(points) 
    nPoints, dim = points.shape 

    # Parametrization parameter s. 
    dp = np.diff(points, axis=0)     # difference between points 
    dp = np.linalg.norm(dp, axis=1)    # distance between points 
    d = np.cumsum(dp)       # cumsum along the segments 
    d = np.hstack([[0],d])      # add distance from first point 
    l = d[-1]         # length of point sequence 
    nSamples = int(l/resolution)     # number of samples 
    s,r = np.linspace(0,l,nSamples,retstep=True) # sample parameter and step 

    # Bring points and (optional) tangent information into correct format. 
    assert(len(points) == len(tangents)) 
    data = np.empty([nPoints, dim], dtype=object) 
    for i,p in enumerate(points): 
     t = tangents[i] 
     # Either tangent is None or has the same 
     # number of dimensions as the point p. 
     assert(t is None or len(t)==dim) 
     fuse = list(zip(p,t) if t is not None else zip(p,)) 
     data[i,:] = fuse 

    # Compute splines per dimension separately. 
    samples = np.zeros([nSamples, dim]) 
    for i in range(dim): 
     poly = interpolate.BPoly.from_derivatives(d, data[:,i]) 
     samples[:,i] = poly(s) 
    return samples 

この機能の使用方法を示すために、ポイントと接線を指定します。この例では、接線の「大きさ」が変更された場合の効果をさらに示しています。

# Input. 
points = [] 
tangents = [] 
resolution = 0.2 
points.append([0.,0.]); tangents.append([1,1]) 
points.append([3.,4.]); tangents.append([1,0]) 
points.append([5.,2.]); tangents.append([0,-1]) 
points.append([3.,0.]); tangents.append([-1,-1]) 
points = np.asarray(points) 
tangents = np.asarray(tangents) 

# Interpolate with different tangent lengths, but equal direction. 
scale = 1. 
tangents1 = np.dot(tangents, scale*np.eye(2)) 
samples1 = sampleCubicSplinesWithDerivative(points, tangents1, resolution) 
scale = 2. 
tangents2 = np.dot(tangents, scale*np.eye(2)) 
samples2 = sampleCubicSplinesWithDerivative(points, tangents2, resolution) 
scale = 0.1 
tangents3 = np.dot(tangents, scale*np.eye(2)) 
samples3 = sampleCubicSplinesWithDerivative(points, tangents3, resolution) 

# Plot. 
import matplotlib.pyplot as plt 
plt.scatter(samples1[:,0], samples1[:,1], marker='o', label='samples1') 
plt.scatter(samples2[:,0], samples2[:,1], marker='o', label='samples2') 
plt.scatter(samples3[:,0], samples3[:,1], marker='o', label='samples3') 
plt.scatter(points[:,0], points[:,1], s=100, c='k', label='input') 
plt.axis('equal') 
plt.title('Interpolation') 
plt.legend() 
plt.show() 

これは、次のグラフのような結果になります。 Cubic splines for different tangent magnitudes

3つのことに注意する:

  • 次も二つ以上のディメンションに適用することができます。
  • サンプル間の間隔は固定されていません。等間隔サンプリングを達成する1つの簡単な方法は、this postで論じられているように、返されたsamplesの間を直線的に補間することです。
  • 接線の指定は任意ですが、BPoly.from_derivativesは、この位置でスプライン間のスムーズな移行を保証しません。上記のサンプルの例tangents[1]ためNonesampleCubicSplinesWithDerivative(points, tangents, resolution)に設定されている場合、結果は次のようになります。 Cubic splines with only some tangents being prescribed