-
-
Notifications
You must be signed in to change notification settings - Fork 404
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3326430
commit b6a8f6c
Showing
2 changed files
with
330 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"<div class=\"contentcontainer med left\" style=\"margin-left: -50px;\">\n", | ||
"<dl class=\"dl-horizontal\">\n", | ||
" <dt>Title</dt> <dd> TriMesh Element</dd>\n", | ||
" <dt>Dependencies</dt> <dd>Bokeh</dd>\n", | ||
" <dt>Backends</dt> <dd><a href='./TriMesh.ipynb'>Bokeh</a></dd> <dd><a href='../matplotlib/TriMesh.ipynb'>Matplotlib</a></dd>\n", | ||
"</dl>\n", | ||
"</div>" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import numpy as np\n", | ||
"import pandas as pd\n", | ||
"import holoviews as hv\n", | ||
"from scipy.spatial import Delaunay\n", | ||
"\n", | ||
"hv.extension('bokeh')" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"A ``TriMesh`` represents a mesh of triangles represented as the simplices and nodes. The simplices represent the indices into the node data, made up of three indices per triangle. The mesh therefore follows a datastructure very similar to a graph, with the abstract connectivity between nodes stored on the ``TriMesh`` element itself, the node positions stored on a ``Nodes`` element and the concrete ``EdgePaths`` making up each triangle generated when required by accessing the edgepaths.\n", | ||
"\n", | ||
"Unlike a Graph each simplex is represented as the node indices of the three corners of each triangle rather than the usual source and target node.\n", | ||
"\n", | ||
"We will begin with a simple random mesh, generated by sampling some random integers and then applying Delaunay triangulation, which is available in SciPy. We can then construct the ``TriMesh`` by passing it the **simplices** and the points (or **nodes**)." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"n_verts = 100\n", | ||
"pts = np.random.randint(1, n_verts, (n_verts, 2))\n", | ||
"tris = Delaunay(pts)\n", | ||
"\n", | ||
"trimesh = hv.TriMesh((tris.simplices, pts))\n", | ||
"trimesh" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Just like the ``Graph`` element we can access the ``Nodes`` and ``EdgePaths`` via the ``.nodes`` and ``.edgepaths`` attributes respectively." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"trimesh.nodes + trimesh.edgepaths" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Now let's make a slightly more interesting example by generating a more complex geometry. Here we will compute a geometry, then apply Delaunay triangulation again and finally apply a mask to drop nodes in the center." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# First create the x and y coordinates of the points.\n", | ||
"n_angles = 36\n", | ||
"n_radii = 8\n", | ||
"min_radius = 0.25\n", | ||
"radii = np.linspace(min_radius, 0.95, n_radii)\n", | ||
"\n", | ||
"angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)\n", | ||
"angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)\n", | ||
"angles[:, 1::2] += np.pi/n_angles\n", | ||
"\n", | ||
"x = (radii*np.cos(angles)).flatten()\n", | ||
"y = (radii*np.sin(angles)).flatten()\n", | ||
"nodes = np.column_stack([x, y])\n", | ||
"z = (np.cos(radii)*np.cos(angles*3.0)).flatten()\n", | ||
"\n", | ||
"# Apply Delaunay triangulation\n", | ||
"delauney = Delaunay(np.column_stack([x, y]))\n", | ||
"\n", | ||
"# Mask off unwanted triangles.\n", | ||
"xmid = x[delauney.simplices].mean(axis=1)\n", | ||
"ymid = y[delauney.simplices].mean(axis=1)\n", | ||
"mask = np.where(xmid*xmid + ymid*ymid < min_radius*min_radius, 1, 0)\n", | ||
"simplices = delauney.simplices[np.logical_not(mask)]\n", | ||
"z = z[simplices].mean(axis=1)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Once again we can simply supply the simplices and nodes to the ``TriMesh``." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"hv.TriMesh((simplices, nodes))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"We can also do something more interesting, e.g. adding a value dimension to the simplices, which we can color each triangle by." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%%opts TriMesh [filled=True edge_color_index='z' width=400 height=400 tools=['hover'] inspection_policy='edges'] (cmap='viridis')\n", | ||
"hv.TriMesh((np.column_stack([simplices, z]), nodes), vdims='z')" | ||
] | ||
} | ||
], | ||
"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.6.3" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"<div class=\"contentcontainer med left\" style=\"margin-left: -50px;\">\n", | ||
"<dl class=\"dl-horizontal\">\n", | ||
" <dt>Title</dt> <dd> TriMesh Element</dd>\n", | ||
" <dt>Dependencies</dt> <dd>Bokeh</dd>\n", | ||
" <dt>Backends</dt> <dd><a href='./TriMesh.ipynb'>Matplotlib</a></dd> <dd><a href='../bokeh/TriMesh.ipynb'>Bokeh</a></dd>\n", | ||
"</dl>\n", | ||
"</div>" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import numpy as np\n", | ||
"import pandas as pd\n", | ||
"import holoviews as hv\n", | ||
"from scipy.spatial import Delaunay\n", | ||
"\n", | ||
"hv.extension('matplotlib')" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"A ``TriMesh`` represents a mesh of triangles represented as the simplices and nodes. The simplices represent the indices into the node data, made up of three indices per triangle. The mesh therefore follows a datastructure very similar to a graph, with the abstract connectivity between nodes stored on the ``TriMesh`` element itself, the node positions stored on a ``Nodes`` element and the concrete ``EdgePaths`` making up each triangle generated when required by accessing the edgepaths.\n", | ||
"\n", | ||
"Unlike a Graph each simplex is represented as the node indices of the three corners of each triangle rather than the usual source and target node.\n", | ||
"\n", | ||
"We will begin with a simple random mesh, generated by sampling some random integers and then applying Delaunay triangulation, which is available in SciPy. We can then construct the ``TriMesh`` by passing it the **simplices** and the points (or **nodes**)." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"n_verts = 100\n", | ||
"pts = np.random.randint(1, n_verts, (n_verts, 2))\n", | ||
"tris = Delaunay(pts)\n", | ||
"\n", | ||
"trimesh = hv.TriMesh((tris.simplices, pts))\n", | ||
"trimesh" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Just like the ``Graph`` element we can access the ``Nodes`` and ``EdgePaths`` via the ``.nodes`` and ``.edgepaths`` attributes respectively." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"trimesh.nodes + trimesh.edgepaths" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Now let's make a slightly more interesting example by generating a more complex geometry. Here we will compute a geometry, then apply Delaunay triangulation again and finally apply a mask to drop nodes in the center." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# First create the x and y coordinates of the points.\n", | ||
"n_angles = 36\n", | ||
"n_radii = 8\n", | ||
"min_radius = 0.25\n", | ||
"radii = np.linspace(min_radius, 0.95, n_radii)\n", | ||
"\n", | ||
"angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)\n", | ||
"angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)\n", | ||
"angles[:, 1::2] += np.pi/n_angles\n", | ||
"\n", | ||
"x = (radii*np.cos(angles)).flatten()\n", | ||
"y = (radii*np.sin(angles)).flatten()\n", | ||
"nodes = np.column_stack([x, y])\n", | ||
"z = (np.cos(radii)*np.cos(angles*3.0)).flatten()\n", | ||
"\n", | ||
"# Apply Delaunay triangulation\n", | ||
"delauney = Delaunay(np.column_stack([x, y]))\n", | ||
"\n", | ||
"# Mask off unwanted triangles.\n", | ||
"xmid = x[delauney.simplices].mean(axis=1)\n", | ||
"ymid = y[delauney.simplices].mean(axis=1)\n", | ||
"mask = np.where(xmid*xmid + ymid*ymid < min_radius*min_radius, 1, 0)\n", | ||
"simplices = delauney.simplices[np.logical_not(mask)]\n", | ||
"z = z[simplices].mean(axis=1)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Once again we can simply supply the simplices and nodes to the ``TriMesh``." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"hv.TriMesh((simplices, nodes))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"We can also do something more interesting, e.g. adding a value dimension to the simplices, which we can color each triangle by." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%%opts TriMesh [filled=True edge_color_index='z' fig_size=200] (cmap='viridis')\n", | ||
"hv.TriMesh((np.column_stack([simplices, z]), nodes), vdims='z')" | ||
] | ||
} | ||
], | ||
"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.6.3" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |