Мотивация
Поздний ответ, мне просто нужно было сделать то же самое, и я нашел другой способ сделать это в некоторой степени. Так что я разделяю эту другую точку зрения.
Этот пост не отвечает: (1) Как построить любую неявную функцию F(x,y,z)=0
? Но отвечает ли: (2) Как построить параметрические поверхности (не все неявные функции, но некоторые из них), используя сетку с matplotlib
?
@ Метод Пола имеет то преимущество, что он непараметрический, поэтому мы можем построить практически все, что захотим, используя контурный метод на каждом топоре, он полностью учитывает (1). Но matplotlib
не может легко построить меш из этого метода, поэтому мы не можем напрямую получить поверхность из него, вместо этого мы получаем плоские кривые во всех направлениях. Это то, что мотивировало мой ответ, я хотел обратиться (2).
Рендеринг сетки
Если мы можем параметризовать (это может быть сложно или невозможно), используя не более 2 параметров, поверхность, которую мы хотим построить, то мы можем построить ее с помощью метода matplotlib.plot_trisurf
.
То есть из неявного уравнения F(x,y,z)=0
, если нам удастся получить параметрическую систему S={x=f(u,v), y=g(u,v), z=h(u,v)}
, то мы можем легко построить ее с помощью matplotlib
, не прибегая к contour
.
Затем рендеринг такой трехмерной поверхности сводится к:
# Render:
ax = plt.axes(projection='3d')
ax.plot_trisurf(x, y, z, triangles=tri.triangles, cmap='jet', antialiased=True)
Где (x, y, z)
- векторы (не meshgrid
, см. ravel
), функционально вычисленные из параметров (u, v)
, а параметр triangles
- это триангуляция, полученная из (u,v)
параметров для построения сетки.
Импорт
Требуемый импорт:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
from matplotlib.tri import Triangulation
Некоторые поверхности
Позволяет параметризовать некоторые поверхности ...
сфера
# Parameters:
theta = np.linspace(0, 2*np.pi, 20)
phi = np.linspace(0, np.pi, 20)
theta, phi = np.meshgrid(theta, phi)
rho = 1
# Parametrization:
x = np.ravel(rho*np.cos(theta)*np.sin(phi))
y = np.ravel(rho*np.sin(theta)*np.sin(phi))
z = np.ravel(rho*np.cos(phi))
# Triangulation:
tri = Triangulation(np.ravel(theta), np.ravel(phi))
шишка
theta = np.linspace(0, 2*np.pi, 20)
rho = np.linspace(-2, 2, 20)
theta, rho = np.meshgrid(theta, rho)
x = np.ravel(rho*np.cos(theta))
y = np.ravel(rho*np.sin(theta))
z = np.ravel(rho)
tri = Triangulation(np.ravel(theta), np.ravel(rho))
торус
a, c = 1, 4
u = np.linspace(0, 2*np.pi, 20)
v = u.copy()
u, v = np.meshgrid(u, v)
x = np.ravel((c + a*np.cos(v))*np.cos(u))
y = np.ravel((c + a*np.cos(v))*np.sin(u))
z = np.ravel(a*np.sin(v))
tri = Triangulation(np.ravel(u), np.ravel(v))
Лента Мёбиуса
u = np.linspace(0, 2*np.pi, 20)
v = np.linspace(-1, 1, 20)
u, v = np.meshgrid(u, v)
x = np.ravel((2 + (v/2)*np.cos(u/2))*np.cos(u))
y = np.ravel((2 + (v/2)*np.cos(u/2))*np.sin(u))
z = np.ravel(v/2*np.sin(u/2))
tri = Triangulation(np.ravel(u), np.ravel(v))
Ограничение
В большинстве случаев Triangulation
требуется для координации построения сетки метода plot_trisurf
, и этот объект принимает только два параметра, поэтому мы ограничены двумерными параметрическими поверхностями. Маловероятно, что мы могли бы представить Путаницу Гурса этим методом.