Обрезать половину тора на земельном участке - PullRequest
0 голосов
/ 13 января 2019

Я пытаюсь построить только половину тора, используя matplotlib.

Это мой подход до сих пор:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

n = 100

# theta: poloidal angle; phi: toroidal angle
theta = np.linspace(0, 2.*np.pi, n)
phi   = np.linspace(0, 2.*np.pi, n)
theta, phi = np.meshgrid(theta, phi)

# R0: major radius; a: minor radius
R0, a = 2., 1.

# torus parametrization
x = (R0 + a*np.cos(theta)) * np.cos(phi)
y = (R0 + a*np.cos(theta)) * np.sin(phi)
z = a * np.sin(theta)

# "cut-off" half of the torus
x[x>0] = np.nan

fig = plt.figure()
ax1 = fig.add_subplot(111, projection='3d')
ax1.set_zlim(-3,3)
ax1.plot_surface(x, y, z, rstride=5, cstride=5,)

# elev: elevation angle in z-plane
# azim: azimuth angle in x,y plane
ax1.view_init(elev=15, azim=0)

plt.show()

Это дает мне действительно половину тора, но одна из поверхностей среза нечеткая, как видно на рисунке (здесь проблемная левая поверхность среза). enter image description here

Есть идеи, как сделать чистую поверхность среза?

1 Ответ

0 голосов
/ 13 января 2019

Обрезка поверхностей с помощью nan s обычно делает это. Это связано с тем, что участки поверхности нарисованы с использованием линейной интерполяции по подмножеству входных данных, и наличие nan s на границе приведет к nan результатам для значений для некоторых участков края.

В вашем конкретном случае вы можете ограничить свой тороидальный угол до половины тора:

theta = np.linspace(0, 2*np.pi, n) 
phi   = np.linspace(0, np.pi, n) 

Вам также нужно будет установить ручные ограничения по x / y для хорошего соотношения сторон:

ax1.axis([-3, 3]*2)

result

Существует очень общая, но практическая альтернатива, передавая явный массив от facecolors до plot_surface и манипулируя прозрачностью значений внутри. Это будет намного хуже, чем по умолчанию, если вы не будете усердно работать, так как затенение будет отсутствовать с плоскими цветами Вот очень простой (и ужасный) пример того, что я имею в виду:

import numpy as np 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 

n = 100 

# theta: poloidal angle; phi: toroidal angle 
theta = np.linspace(0, 2*np.pi, n) 
phi   = np.linspace(0, 2*np.pi, n) 
theta, phi = np.meshgrid(theta, phi) 

# R0: major radius; a: minor radius 
R0, a = 2., 1. 

# torus parametrization 
x = (R0 + a*np.cos(theta)) * np.cos(phi) 
y = (R0 + a*np.cos(theta)) * np.sin(phi) 
z = a * np.sin(theta) 

# "cut-off" half of the torus using transparent colors 
c = np.full(x.shape + (4,), [0, 0, 0.85, 1])  # shape (nx, ny, 4)
c[x>0, -1] = 0 # set these to transparent 

fig = plt.figure() 
ax1 = fig.add_subplot(111, projection='3d') 
ax1.set_zlim(-3,3) 
ax1.plot_surface(x, y, z, facecolors=c, rstride=5, cstride=5,)

# elev: elevation angle in z-plane 
# azim: azimuth angle in x,y plane 
ax1.view_init(elev=15, azim=0) 

plt.show() 

facecolors example result

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...