{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Bézier triangular patches defined as Plotly trisurfs ##" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One year ago we presented [here](http://nbviewer.jupyter.org/github/empet/Geometric-Modeling/blob/master/Bezier-triangular-patch-in-plotly.ipynb) a method for visualizing Bézier triangular surfaces via Python Plotly. Since at that time Plotly could plot only rectangular patches we devised a tricky method to associate a rectangular meshgrid to a triangulation. Now Plotly can plot trisurfs, and here we present how we triangulate the parameter domain of a triangular patch in order to plot it as a trisurf." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The new method is based on the theoretical presentation of Bézier triangular surfaces made in the previous notebook." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np\n", "from __future__ import division" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Below we define functions that perform the triangulation of the equilateral triangle $\\Delta$, in $\\mathbb{R}^3$, of vertices $(0,0,1)$, $(1,0,0)$, $(0,1,0)$. Unlike the triangulation method provided by `matplotlib.tri`, we define a triangulation that returns the barycentric coordinates of vertices, not the cartesian ones." ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "The `triangulate` function called for an integer `p` returns the vertices of a triangulation having $p+1$ points on each side of the triangle $\\Delta$, `simplices` returns the indices corresponding to vertices that form the unfilled triangles in the image below, while `simplicesCompl` returns the indices corresponding to vertices of filled triangles:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\nKAIIIIAAAgggoCJAwFJR4hgEEEAAAQQQQCCDAAErAxaHIoAAAggggAACKgIELBUljkEAAQQQQAAB\nBDIIELAyYHEoAggggAACCCCgIkDAUlHiGAQQQAABBBBAIIMAASsDFocigAACCCCAAAIqAgQsFSWO\nQQABBBBAAAEEMggQsDJgcSgCCCCAAAIIIKAiQMBSUeIYBBBAAAEEEEAggwABKwMWhyKAAAIIIIAA\nAioCBCwVJY5BAAEEEEAAAQQyCBCwMmBxKAIIIIAAAgggoCJAwFJR4hgEEEAAAQQQQCCDAAErAxaH\nIoAAAggggAACKgIELBUljkEAAQQQQAABBDIIELAyYHEoAggggAACCCCgIkDAUlHiGAQQQAABBBBA\nIIMAASsDFocigAACCCCAAAIqAgQsFSWOQQABBBBAAAEEMggQsDJgcSgCCCCAAAIIIKAiQMBSUeIY\nBBBAAAEEEEAggwABKwMWhyKAAAIIIIAAAioCBCwVJY5BAAEEEEAAAQQyCBCwMmBxKAIIIIAAAggg\noCJAwFJR4hgEEEAAAQQQQCCDAAErAxaHIoAAAggggAACKgIELBUljkEAAQQQQAABBDIIELAyYHEo\nAggggAACCCCgIkDAUlHiGAQQQAABBBBAIIMAASsDFocigAACCCCAAAIqAgQsFSWOQQABBBBAAAEE\nMggQsDJgcSgCCCCAAAIIIKAiQMBSUeIYBBBAAAEEEEAggwABKwMWhyKAAAIIIIAAAioCBCwVJY5B\nAAEEEEAAAQQyCBCwMmBxKAIIIIAAAgggoCJAwFJR4hgEEEAAAQQQQCCDAAErAxaHIoAAAggggAAC\nKgIELBUljkEAAQQQQAABBDIIELAyYHEoAggggAACCCCgIkDAUlHiGAQQQAABBBBAIIMAASsDFoci\ngAACCCCAAAIqAgQsFSWOQQABBBBAAAEEMggQsDJgcSgCCCCAAAIIIKAiQMBSUeIYBBBAAAEEEEAg\ngwABKwMWhyKAAAIIIIAAAioCBCwVJY5BAAEEEEAAAQQyCBCwMmBxKAIIIIAAAgggoCJAwFJR4hgE\nEEAAAQQQQCCDAAErAxaHIoAAAggggAACKgIELBUljkEAAQQQQAABBDIIELAyYHEoAggggAACCCCg\nIkDAUlHiGAQQQAABBBBAIIMAASsDFocigAACCCCAAAIqAgQsFSWOQQABBBBAAAEEMggQsDJgcSgC\nCCCAAAIIIKAiQMBSUeIYBBBAAAEEEEAggwABKwMWhyKAAAIIIIAAAioCBCwVJY5BAAEEEEAAAQQy\nCBCwMmBxKAIIIIAAAgggoCJAwFJR4hgEEEAAAQQQQCCDAAErAxaHIoAAAggggAACKgIELBUljkEA\nAQQQQAABBDIIELAyYHEoAggggAACCCCgIkDAUlHiGAQQQAABBBBAIIMAASsDFocigAACCCCAAAIq\nAgQsFSWOQQABBBBAAAEEMggQsDJgcSgCCCCAAAIIIKAiQMBSUeIYBBBAAAEEEEAggwABKwMWhyKA\nAAIIIIAAAioCBCwVJY5BAAEEEEAAAQQyCBCwMmBxKAIIIIAAAgggoCJAwFJR4hgEEEAAAQQQQCCD\nwP8Hkn+s5+G+DJIAAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import Image\n", "Image(filename='Imag/triangulgroups.png')" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def triangulate(p):\n", " I=range(p, -1, -1)\n", " return [(i/p,j/p, 1-(i+j)/p) for i in I for j in range(p-i, -1, -1)]\n", "\n", "def simplices(p):\n", " \n", " triplets=[]\n", " i=0\n", " j=1\n", " for nr in range(1,p+1):\n", " for k in range(nr):\n", " triplets.append([i,j,j+1])\n", " i+=1\n", " j+=1\n", " j+=1\n", " return np.array(triplets).reshape((len(triplets), 3)) " ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def simplicesCompl(p):\n", " \n", " triplets=[]\n", " i=1\n", " j=2\n", " t=4\n", " m=2\n", " for nr in range(1,p):\n", " for k in range(nr):\n", " triplets.append([i,j,t])\n", " if k1: \n", " return deCasteljau(n-1, deCasteljau_step(n, b, lam), lam) \n", " else: \n", " return b[0]" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "To each point (triplet of barycentric coordinates) in a triangulation one associates a point on the Bézier patch. \n", "\n", "The following function discretizes a Bézier surface of degree `n`, control points `b`, and triangulation vertices ( `barycenters`), defined above:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def surface_points(n, b, barycenters):\n", " \n", " points=[]\n", " for weight in barycenters:\n", " b_aux=np.array(b)\n", " points.append(deCasteljau(n, b_aux, weight))\n", " return zip(*points) " ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ " `set_data_for_Surface` prepare data for a plot:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def set_data_for_Surface(n, b, p):\n", " \n", " if len(b)!=(n+1)*(n+2)/2:\n", " raise ValueError('incorect number of control points')\n", " barycenters=triangulate(p)\n", " \n", " x,y,z=surface_points(n, b, barycenters )\n", " return x,y, z" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def map_z2color(zval, cmap, vmin, vmax):\n", " #map the normalized value zval to a corresponding color in the colormap cmap\n", " \n", " if vmin>=vmax:\n", " raise ValueError('incorrect relation between vmin and vmax')\n", " t=(zval-vmin)/float((vmax-vmin))#normalize val\n", " C=map(np.uint8, np.array(cmap(t)[:3])*255)\n", " return 'rgb'+str((C[0], C[1], C[2]))\n", " \n", "\n", "def tri_indices(simplices):\n", " #simplices is a numpy array defining the simplices of the triangulation\n", " #returns the lists of indices i, j, k\n", " \n", " return ([triplet[c] for triplet in simplices] for c in range(3))" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import plotly.plotly as py\n", "from plotly.graph_objs import *\n", "import matplotlib.cm as cm\n", "import plotly\n", "plotly.offline.init_notebook_mode() " ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def plotly_trisurf(x, y, z, simplices, colormap=cm.RdBu):\n", " #x, y, z are lists of coordinates of the triangle vertices \n", " #simplices are the simplices that define the triangulation;\n", " #simplices is a numpy array of shape (no_triangles, 3)\n", " #insert here the type check for input data\n", " \n", " points3D=np.vstack((x,y,z)).T\n", " tri_vertices= points3D[simplices]# vertices of the surface triangles \n", " zmean=[np.mean(tri[:,2]) for tri in tri_vertices ]# mean values of z-coordinates of \n", " #triangle vertices\n", " min_zmean=np.min(zmean)\n", " max_zmean=np.max(zmean) \n", " facecolor=[map_z2color(zz, colormap, min_zmean, max_zmean) for zz in zmean] \n", " I,J,K=tri_indices(simplices)\n", " \n", " triangles=Mesh3d(x=x,\n", " y=y,\n", " z=z,\n", " facecolor=facecolor, \n", " i=I,\n", " j=J,\n", " k=K,\n", " name=''\n", " )\n", " \n", " \n", " return triangles\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Function that plots triangles with a color not a colormap:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def plotly_trisurf_color(x, y, z, simplices, color):\n", " #x, y, z are lists of coordinates of the triangle vertices \n", " #simplices are the simplices that define the triangulation;\n", " #simplices is a numpy array of shape (no_triangles, 3)\n", " \n", " facecolor=[color]*simplices.shape[0]\n", " I,J,K=tri_indices(simplices)\n", " triangles=Mesh3d(x=x,\n", " y=y,\n", " z=z,\n", " facecolor=facecolor, \n", " i=I,\n", " j=J,\n", " k=K,\n", " name=''\n", " )\n", " \n", " \n", " return triangles" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We plot three surfaces corresponding to the same input data (Bézier control points), with the global triangulation, complementary triangulations colored distinctly, complementary triangulations colored with the same colorscale:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": true }, "outputs": [], "source": [ "n=3\n", "b=[[0,5.0, 3.0],\n", " [-1.2, 4, 4.4],\n", " [ 1.7, 3.0, 4.6],\n", " [-2.3, 2.8, 6.0],\n", " [-0.5, 2.5, 5.2],\n", " [2.8,2, 6.25],\n", " [-3.8,0, 4.2],\n", " [-1.8, -0.63, 3.17],\n", " [1.9,1.0, 3.0],\n", " [3.5, 0.2, 5.8 ]]\n", "p=40" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [], "source": [ "x,y,z=set_data_for_Surface(n, b, p)\n", "tr=plotly_trisurf(x, y, z, simplicesAll(p), colormap=cm.viridis)\n", "data=Data([tr])" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "axis = dict(\n", "showbackground=True, \n", "backgroundcolor=\"rgb(230, 230,230)\",\n", "gridcolor=\"rgb(255, 255, 255)\", \n", "zerolinecolor=\"rgb(255, 255, 255)\", \n", " )\n", "\n", "layout = Layout(\n", " title='Bezier triangular patch defined as a trisurf',\n", " width=800,\n", " height=800,\n", " showlegend=False,\n", " scene=Scene(xaxis=XAxis(axis),\n", " yaxis=YAxis(axis), \n", " zaxis=ZAxis(axis), \n", " aspectratio=dict(x=1,\n", " y=1,\n", " z=1\n", " ),\n", " )\n", " )\n", "\n", "fig = Figure(data=data, layout=layout)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plotly.offline.iplot(fig)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [], "source": [ "trace1=plotly_trisurf_color(x, y, z, simplices(p), color='blue')\n", "trace2=plotly_trisurf_color(x, y, z, simplicesCompl(p), color='white')\n", "data1=Data([trace1, trace2])" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "\n", "\n", "fig1 = Figure(data=data1, layout=layout)\n", "fig1['layout'].update(title='Bezier triangular patch defined as a trisurf with interleaved colors')" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "\n", "plotly.offline.iplot(fig1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally we plot the surface defined by two Plotly Surface instances: one for the simplices corresponding to unfilled triangles in the image above, and another for\n", " the simplices representing the filled triangles:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "trace3=plotly_trisurf(x, y, z, simplices(p), colormap=cm.viridis)\n", "trace4=plotly_trisurf(x, y, z, simplicesCompl(p), colormap=cm.viridis)\n", "data2=Data([trace3, trace4])\n", "fig2 = Figure(data=data2, layout=layout)\n", "fig2['layout'].update(title='Bezier triangular patch defined as a trisurf')\n", "plotly.offline.iplot(fig2)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.core.display import HTML\n", "def css_styling():\n", " styles = open(\"./custom.css\", \"r\").read()\n", " return HTML(styles)\n", "css_styling()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.11" } }, "nbformat": 4, "nbformat_minor": 0 }