Как спроецировать линию на поверхность в Python? - PullRequest
1 голос
/ 22 апреля 2019

см. Содержимое изображения I У меня есть график поверхности, созданный из точечных данных, сохраненных в файле CSV.Если я хочу спроецировать линию (которая плавает над поверхностью) на поверхность, созданную в 3D, какой метод?

Я попробовал некоторый код для проецирования линии на плоскость xy-xz-yz.
Я вижу, что она проецирует конечную точку линии на плоскость xy-xz-yz.

, если я хочу проецировать на поверхность, созданную с точечными данными.У меня нет уравнения поверхности.Я создал с доступными точечными данными.

1 Ответ

0 голосов
/ 23 апреля 2019

Давайте создадим общий MCVE, сначала мы импортируем необходимые пакеты:

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

Теперь мы генерируем коллекцию трехмерных точек для поверхности S (обратите внимание, что это неправильная сетка):

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,))

И параметрическая кривая P:

NP = 100
t = np.linspace(-1, 1, NP)
Px = t
Py = t**2 - 0.5
Pz = t**3 + 1

Ключом к решению вашей проблемы является LinearNDInterpolator, который выполняет кусочно-линейную интерполяцию в N измерениях:

PSz = interpolate.LinearNDInterpolator(list(zip(Sx, Sy)), Sz)(list(zip(Px,Py)))

Существует только необходимость изменить данные, чтобы они соответствовали сигнатуре метода из отдельных векторов в матрицу формы (Nsample,Ndims), что можно перевести на:

list(zip(Sx, Sy))

Мы можем проверить данные сверху:

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()

enter image description here

Полный трехмерный результат показан ниже:

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)

enter image description here

axe.view_init(elev=75, azim=-45)

enter image description here

...