问题
I Have a surface plot created from point data stored in a CSV file. If I want to project a line (which is floating above the surface) on the surface created in 3D. What is the method?
I have tried a code from the following post for projecting a line on xy-xz-yz plane.
I can see that it is projecting the endpoint of line on the xy-xz-yz plane.
If I want to project on the surface created with point data. I don't have an equation of the surface. I have created with point data available.
Here is a mockup image of what I'm trying to achieve:
I have generated a curved surface with given scattered points stored in a CSV file. Now I want to project the line on top of the surface(red line) to the surface(as a green line).
回答1:
Lets build a generic MCVE, first we import required packages:
import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
import matplotlib.tri as mtri
np.random.seed(123456) # Fix the random seed
Now we generate a collection of 3D points for a surface S (notice it is an irregular mesh):
NS = 100
Sx = np.random.uniform(low=-1., high=1., size=(NS,))
Sy = np.random.uniform(low=-1., high=1., size=(NS,))
Sz = -(Sx**2 + Sy**2) + 0.1*np.random.normal(size=(NS,))
And a parametric curve P:
NP = 100
t = np.linspace(-1, 1, NP)
Px = t
Py = t**2 - 0.5
Pz = t**3 + 1
The key to solve your problem is LinearNDInterpolator which performs a piecewise linear interpolation in N dimensions:
PSz = interpolate.LinearNDInterpolator(list(zip(Sx, Sy)), Sz)(list(zip(Px,Py)))
There is just the need to reshape data to fit the method signature from separate vectors to matrix of shape (Nsample,Ndims) which can be translated to:
list(zip(Sx, Sy))
We can check the data from the top:
tri = mtri.Triangulation(Sx, Sy)
fig, axe = plt.subplots()
axe.plot(Sx, Sy, '+')
axe.plot(Px, Py)
axe.triplot(tri, linewidth=1, color='gray')
axe.set_aspect('equal')
axe.grid()
The complete 3D result is shown bellow:
axe = plt.axes(projection='3d')
axe.plot_trisurf(tri, Sz, cmap='jet', alpha=0.5)
axe.plot(Px, Py, Pz)
axe.plot(Px, Py, PSz, linewidth=2, color='black')
axe.scatter(Sx, Sy, Sz)
axe.view_init(elev=25, azim=-45)
axe.view_init(elev=75, azim=-45)
来源:https://stackoverflow.com/questions/55789564/how-to-project-a-line-on-a-surfaceplot