衝突#

2つのメッシュの衝突判定を行います.

この例では, collision フィルタを使用して,ある球体が別の球体に衝突したときの面を検出します.

注釈

vtk.vtkCollisionDetectionFilter の性質上,このメソッドを繰り返し使用すると vtk.vtkCollisionDetectionFilter を直接使用した場合よりも遅くなります. このフィルタの最初の更新では, vtkOBBTree のインスタンスが2つ作成されます.その後,入力メッシュの変換や行列を変更することで,このインスタンスを更新することができます.

このメソッドは変換を前提としていないので,単一の衝突テストには使いやすいですが,繰り返される衝突を高速に計算するには pyvistavtk の組み合わせを使うことをお勧めします. 詳しくは, Collision Detection Example をご覧ください.

import numpy as np

import pyvista as pv

pv.set_plot_theme("document")

メインのメッシュとセカンダリーの "moving" メッシュの作成

衝突面はこの球体上にプロットされますが,そのために初期の "collisions" マスクを設定します.

sphere0 = pv.Sphere()
sphere0['collisions'] = np.zeros(sphere0.n_cells, dtype=bool)

# This mesh will be the moving mesh
sphere1 = pv.Sphere(radius=0.6, center=(-1, 0, 0))

プロッターをセットアップしてムービーを開き,球体を動かした後のフレームを書き込んでいきます.

pl = pv.Plotter()
pl.enable_hidden_line_removal()
pl.add_mesh(sphere0, scalars='collisions', show_scalar_bar=False, cmap='bwr')
pl.camera_position = 'xz'
pl.add_mesh(sphere1, style='wireframe', color='green', line_width=5)

# for this example
pl.open_gif("collision_movie.gif")

# alternatively, to disable movie generation:
# pl.show(auto_close=False, interactive=False)

delta_x = 0.05
for _ in range(int(2 / delta_x)):
    sphere1.translate([delta_x, 0, 0], inplace=True)
    col, n_contacts = sphere0.collision(sphere1)

    collision_mask = np.zeros(sphere0.n_cells, dtype=bool)
    if n_contacts:
        collision_mask[col['ContactCells']] = True
    sphere0['collisions'] = collision_mask
    pl.write_frame()

    # alternatively, disable movie plotting and simply render the image
    # pl.render()

pl.close()
collisions

Total running time of the script: (0 minutes 5.898 seconds)

Sphinx-Galleryによるギャラリー