0
votes

I'm looking for a function which mimics MATLAB's cscvn function in their Curve Fitting Toolbox, suitable for points in 3D space. The closest function I've found has been scipy.interpolate.splprep, which is capable of computing 3 dimensions but loses its accuracy with fewer data points. If smoothness is reduced to a point of fitting the points, the curve has kinks.

I have a discrete dataset made up of physical points (elevation data) that I'm looking to model, so the spline must pass through those points. There is a finite number of points at varying chord lengths from one another.

Here's a sample of the quick test function I've written to test Python splines. Unfortunately, I can't share my MATLAB code, but the cscvn function splines smoothly and passes through all data points.

import scipy as sp
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import splprep, splev, interp2d

x = np.linspace(0, 10, num = 20)   #list of known x coordinates
y = 2*x   #list of known y coordinates
z = x*x   #list of known z coordinates
## Note: You must have more points than degree of the spline. if k = 3, must have 4 points min.

print([x,y,z])

tck, u = splprep([x,y,z], s = 26)  # Generate function out of provided points, default k = 3
newPoints = splev(u, tck)          # Creating spline points
print(newPoints)

ax = plt.axes(projection = "3d")
ax.plot3D(x, y, z, 'go')     # Green is the actual 3D function
ax.plot3D(newPoints[:][0], newPoints[:][1], newPoints[:][2], 'r-')   # Red is the spline
plt.show()

Here is an example of many points creating a smooth curve (red), but the line doesn't align with the physical data points (green).

Lots of Points, Spline Misses

Here is an example of kinks in the spline (red) created by too few data points (green). This is more akin to what my dataset looks like.

Too few points, Spline Kinks

1
Welcome to StackOverflow, what have you done so far? Could you share your code?Manu
I added some additional detailSpaceJam
@SardarUsama Code is shared in text formSpaceJam

1 Answers

-1
votes

Change your U for:

unew = np.arange(0, 1.00, 0.005)