注釈
Go to the end をクリックすると完全なサンプルコードをダウンロードできます.
マーチングキューブ#
contour
フィルタで提供されるフライングエッジとマーチングキューブのフィルタを使って,スカラーフィールドから曲面を生成します.
例題を提供してくれたGitHubユーザーの stla に感謝します.
import numpy as np
import pyvista as pv
スパイダーケイジ#
marching cubesアルゴリズムを使用して,スパイダーケージ関数から生成された等値面を抽出します.
a = 0.9
def spider_cage(x, y, z):
x2 = x * x
y2 = y * y
x2_y2 = x2 + y2
return (np.sqrt((x2 - y2) ** 2 / x2_y2 + 3 * (z * np.sin(a)) ** 2) - 3) ** 2 + 6 * (
np.sqrt((x * y) ** 2 / x2_y2 + (z * np.cos(a)) ** 2) - 1.5
) ** 2
# create a uniform grid to sample the function with
n = 100
x_min, y_min, z_min = -5, -5, -3
grid = pv.ImageData(
dimensions=(n, n, n),
spacing=(abs(x_min) / n * 2, abs(y_min) / n * 2, abs(z_min) / n * 2),
origin=(x_min, y_min, z_min),
)
x, y, z = grid.points.T
# sample and plot
values = spider_cage(x, y, z)
mesh = grid.contour([1], values, method='marching_cubes')
dist = np.linalg.norm(mesh.points, axis=1)
mesh.plot(scalars=dist, smooth_shading=True, specular=1, cmap="plasma", show_scalar_bar=False)
バースセクスィック#
flying edgesアルゴリズムを使用して, Barth sextic 関数から生成された等値面を抽出します.
phi = (1 + np.sqrt(5)) / 2
phi2 = phi * phi
def barth_sextic(x, y, z):
x2 = x * x
y2 = y * y
z2 = z * z
arr = (
3 * (phi2 * x2 - y2) * (phi2 * y2 - z2) * (phi2 * z2 - x2)
- (1 + 2 * phi) * (x2 + y2 + z2 - 1) ** 2
)
nan_mask = x2 + y2 + z2 > 3.1
arr[nan_mask] = np.nan
return arr
# create a uniform grid to sample the function with
n = 100
k = 2.0
x_min, y_min, z_min = -k, -k, -k
grid = pv.ImageData(
dimensions=(n, n, n),
spacing=(abs(x_min) / n * 2, abs(y_min) / n * 2, abs(z_min) / n * 2),
origin=(x_min, y_min, z_min),
)
x, y, z = grid.points.T
# sample and plot
values = barth_sextic(x, y, z)
mesh = grid.contour([0], values, method='flying_edges')
dist = np.linalg.norm(mesh.points, axis=1)
mesh.plot(scalars=dist, smooth_shading=True, specular=1, cmap="plasma", show_scalar_bar=False)
バースセクスィックのアニメーション#
バルト6芒星関数から抽出された様々なアイソカーブを20フレーム表示します.
def angle_to_range(angle):
return -2 * np.sin(angle)
pl = pv.Plotter(window_size=[800, 800], off_screen=True)
pl.open_gif('barth_sextic.gif')
for angle in np.linspace(0, np.pi, 20, endpoint=False):
# clear the plotter before adding each frame's mesh
pl.clear()
pl.enable_lightkit()
mesh = grid.contour([angle_to_range(angle)], values, method='flying_edges')
dist = np.linalg.norm(mesh.points, axis=1)
pl.add_mesh(
mesh,
scalars=dist,
smooth_shading=True,
specular=1,
rng=[0.5, 1.5],
cmap="plasma",
show_scalar_bar=False,
)
pl.write_frame()
pl.close()
Total running time of the script: (0 minutes 7.937 seconds)