{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Collision {#collision_example}\n\nPerform a collision detection between two meshes.\n\nThis example use the\n`collision <pyvista.PolyDataFilters.collision>`{.interpreted-text\nrole=\"class\"} filter to detect the faces from one sphere colliding with\nanother sphere.\n\n::: note\n::: title\nNote\n:::\n\nDue to the nature of the\n[vtk.vtkCollisionDetectionFilter](https://vtk.org/doc/nightly/html/classvtkCollisionDetectionFilter.html),\nrepeated uses of this method will be slower that using the\n`vtk.vtkCollisionDetectionFilter` directly. The first update of the\nfilter creates two instances of\n[vtkOBBTree](https://vtk.org/doc/nightly/html/classvtkOBBTree.html),\nwhich can be subsequently updated by modifying the transform or matrix\nof the input meshes.\n\nThis method assumes no transform and is easier to use for single\ncollision tests, but it is recommended to use a combination of `pyvista`\nand `vtk` for rapidly computing repeated collisions. See the [Collision\nDetection\nExample](https://kitware.github.io/vtk-examples/site/Python/Visualization/CollisionDetection/)\n:::\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n\nimport pyvista as pv\n\npv.set_plot_theme(\"document\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create the main mesh and the secondary \\\"moving\\\" mesh\n\nCollision faces will be plotted on this sphere, and to do so we\ninitialize an initial `\"collisions\"` mask.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "sphere0 = pv.Sphere()\nsphere0['collisions'] = np.zeros(sphere0.n_cells, dtype=bool)\n\n# This mesh will be the moving mesh\nsphere1 = pv.Sphere(radius=0.6, center=(-1, 0, 0))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Set up the plotter open a movie, and write a frame after moving the\nsphere.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pl = pv.Plotter()\npl.enable_hidden_line_removal()\npl.add_mesh(sphere0, scalars='collisions', show_scalar_bar=False, cmap='bwr')\npl.camera_position = 'xz'\npl.add_mesh(sphere1, style='wireframe', color='green', line_width=5)\n\n# for this example\npl.open_gif(\"collision_movie.gif\")\n\n# alternatively, to disable movie generation:\n# pl.show(auto_close=False, interactive=False)\n\ndelta_x = 0.05\nfor _ in range(int(2 / delta_x)):\n sphere1.translate([delta_x, 0, 0], inplace=True)\n col, n_contacts = sphere0.collision(sphere1)\n\n collision_mask = np.zeros(sphere0.n_cells, dtype=bool)\n if n_contacts:\n collision_mask[col['ContactCells']] = True\n sphere0['collisions'] = collision_mask\n pl.write_frame()\n\n # alternatively, disable movie plotting and simply render the image\n # pl.render()\n\npl.close()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.2" } }, "nbformat": 4, "nbformat_minor": 0 }