Solution for Fastest way to interpolate xy values for a given z on a 3d line
is Given Below:
I have a series of lines in 3d of which I know for each one of them the vertices x and z that compose them.
What I need is to get for each line the xy coordinates given a z coordinate contained in that line. Numerically I know how to solve it, however I would like to find in python the fastest / most efficient way to carry out this task.
For example, given a line whose xyz values I have stored in the following way:
>>> arr = array([[ 6.04691088e+05, 4.11484364e+06, -7.35610000e+00], [ 6.04671604e+05, 4.11484372e+06, -7.00000000e+00], [ 6.04665386e+05, 4.11484374e+06, -6.83720000e+00], [ 6.04659607e+05, 4.11484376e+06, -6.69120000e+00], [ 6.04633141e+05, 4.11484387e+06, -6.00000000e+00], [ 6.04615502e+05, 4.11484394e+06, -5.41870000e+00], [ 6.04604279e+05, 4.11484398e+06, -5.00000000e+00], [ 6.04599722e+05, 4.11484400e+06, -4.69160000e+00], [ 6.04585486e+05, 4.11484406e+06, -4.00000000e+00], [ 6.04585333e+05, 4.11484406e+06, -3.99290000e+00], [ 6.04584247e+05, 4.11484406e+06, -3.93210000e+00], [ 6.04567577e+05, 4.11484413e+06, -3.00000000e+00], [ 6.04558717e+05, 4.11484416e+06, -2.41210000e+00], [ 6.04553510e+05, 4.11484419e+06, -2.06660000e+00], [ 6.04552563e+05, 4.11484419e+06, -2.00000000e+00], [ 6.04552018e+05, 4.11484419e+06, -1.96420000e+00], [ 6.04537647e+05, 4.11484425e+06, -1.00000000e+00], [ 6.04530721e+05, 4.11484428e+06, -5.93300000e-01], [ 6.04519556e+05, 4.11484432e+06, 0.00000000e+00], [ 6.04519355e+05, 4.11484432e+06, 0.00000000e+00], [ 6.04518720e+05, 4.11484432e+06, 0.00000000e+00], [ 6.04518556e+05, 4.11484432e+06, 0.00000000e+00], [ 6.04518296e+05, 4.11484433e+06, 0.00000000e+00], [ 6.04516286e+05, 4.11484433e+06, 5.36200000e-01], [ 6.04514899e+05, 4.11484434e+06, 8.77000000e-01], [ 6.04514371e+05, 4.11484434e+06, 1.00000000e+00], [ 6.04513926e+05, 4.11484434e+06, 1.12940000e+00], [ 6.04511400e+05, 4.11484435e+06, 2.00000000e+00], [ 6.04509132e+05, 4.11484436e+06, 2.38240000e+00], [ 6.04508615e+05, 4.11484436e+06, 2.50000000e+00], [ 6.04507578e+05, 4.11484437e+06, 2.68050000e+00], [ 6.04506375e+05, 4.11484437e+06, 2.91140000e+00]])
I want to obtain the interpolated xy coordinates for any z, for example 1.38, so that:
>>> intrp3line(arr,z_value=1.38) [[x1,y1],[x2,y2],...,[xn,yn]]
It should return a list with all pairs of xy coordinates interpolated to achieve the given z.
Almost all the information I have found on interpoolation is to solve the opposite problem, that is, interpolate the coordinate z a for a given xy, but very little relative to the problem I pose. On the other hand, considering that I have the N lines with their xyz coordinates and a list of N z values (one for each line), I would also like to know if there is any way to optimize the interpolation by treating the set of lines instead to iterate one by one.
One way of doing this is using scikit-learn’s LinearRegression like so.
from sklearn.linear_model import LinearRegression line = LinearRegression().fit(arr[:,2].reshape(-1, 1), arr[:,0:2])
To now obtain points you can just use
z = np.linspace(-8,2,10**5) xy = line.predict(z.reshape(-1, 1))
This takes ~1.26ms for 10^5
z values and seems to scale approximately linearly.
And you can plot it too.
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = Axes3D(fig, auto_add_to_figure=False) fig.add_axes(ax) ax.view_init(elev=0, azim=0)# ax.scatter(arr[:,0],arr[:,1],arr[:,2]) ax.plot(xy[:,0], xy[:,1], z)