{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "require.undef(\"nbextensions/vpython_libraries/glow.min\");" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "require.undef(\"nbextensions/vpython_libraries/glowcomm\");" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "require.undef(\"nbextensions/vpython_libraries/jquery-ui.custom.min\");" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "require([\"nbextensions/vpython_libraries/glow.min\"], function(){console.log(\"GLOW LOADED\");})" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "require([\"nbextensions/vpython_libraries/glowcomm\"], function(){console.log(\"GLOWCOMM LOADED\");})" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "require([\"nbextensions/vpython_libraries/jquery-ui.custom.min\"], function(){console.log(\"JQUERY LOADED\");})" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "window.__context = { glowscript_container: $(\"#glowscript\").removeAttr(\"id\")}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from vpython import *\n", "scene.width = scene.height = 600\n", "# There is an L by L grid of vertex objects, numbered 0 through L-1 by 0 through L-1.\n", "# Only the vertex operators numbered L-2 by L-2 are used to create quads.\n", "# The extra row and extra column of vertex objects simplifies edge calculations.\n", "# The stride length from y = 0 to y = 1 is L.\n", "L = 25\n", "scene.center = vec(0.05*L,0.2*L,0)\n", "scene.range = 1.3*L\n", "## The next line contains LaTeX math notation. See http://www.glowscript.org/docs/VPythonDocs/MathJax.html\n", "#scene.caption = \"\"\"\\\\( f(x,y,t) = 0.7+0.2\\\\sin{(10x)}\\\\cos{(10y)}\\\\cos{(2t)} \\\\)\n", "scene.caption = \"\"\"f(x,y,t) = 0.7+0.2sin(10x)cos(10y)cos(2t)\n", "Click to toggle between pausing or running.\n", "In GlowScript programs:\n", " Right button drag or Ctrl-drag to rotate \"camera\" to view scene.\n", " To zoom, drag with mid1e button or Alt/Option depressed, or use scroll wheel.\n", " On a two-button mouse, mid1e is left + right.\n", " Touch screen: pinch/extend to zoom, swipe or two-finger rotate.\"\"\"\n", "#MathJax.Hub.Queue([\"Typeset\",MathJax.Hub]) # format the LaTeX; see http://www.glowscript.org/docs/VPythonDocs/MathJax.html\n", "\n", "class plot3D:\n", " def __init__(self, f, xmin, xmax, ymin, ymax, zmin, zmax):\n", " # The x axis is labeled y, the z axis is labeled x, and the y axis is labeled z.\n", " # This is done to mimic fairly standard practive for plotting\n", " # the z value of a function of x and y.\n", " self.f = f\n", " if not xmin: self.xmin = 0\n", " else: self.xmin = xmin\n", " if not xmax: self.xmax = 1\n", " else: self.xmax = xmax\n", " if not ymin: self.ymin = 0\n", " else: self.ymin = ymin\n", " if not ymax: self.ymax = 1\n", " else: self.ymax = ymax\n", " if not zmin: self.zmin = 0\n", " else: self.zmin = zmin\n", " if not zmax: self.zmax = 1\n", " else: self.zmax = zmax\n", " \n", " R = L/100\n", " d = L-2\n", " xaxis = cylinder(pos=vec(0,0,0), axis=vec(0,0,d), radius=R, color=color.yellow)\n", " yaxis = cylinder(pos=vec(0,0,0), axis=vec(d,0,0), radius=R, color=color.yellow)\n", " zaxis = cylinder(pos=vec(0,0,0), axis=vec(0,d,0), radius=R, color=color.yellow)\n", " k = 1.02\n", " h = 0.05*L\n", " text(pos=xaxis.pos+k*xaxis.axis, text='x', height=h, align='center', billboard=True, emissive=True)\n", " text(pos=yaxis.pos+k*yaxis.axis, text='y', height=h, align='center', billboard=True, emissive=True)\n", " text(pos=zaxis.pos+k*zaxis.axis, text='z', height=h, align='center', billboard=True, emissive=True)\n", " \n", " self.vertices = []\n", " for x in range(L):\n", " for y in range(L):\n", " val = self.evaluate(x,y)\n", " self.vertices.append(self.make_vertex( x, y, val ))\n", " \n", " self.make_quads()\n", " self.make_normals()\n", " \n", " def evaluate(self, x, y):\n", " d = L-2\n", " return (d/(self.zmax-self.zmin)) * (self.f(self.xmin+x*(self.xmax-self.xmin)/d, self.ymin+y*(self.ymax-self.ymin)/d)-self.zmin)\n", " \n", " def make_quads(self):\n", " # Create the quad objects, based on the vertex objects already created.\n", " for x in range(L-2):\n", " for y in range(L-2):\n", " v0 = self.get_vertex(x,y)\n", " v1 = self.get_vertex(x+1,y)\n", " v2 = self.get_vertex(x+1, y+1)\n", " v3 = self.get_vertex(x, y+1)\n", " quad(vs=[v0, v1, v2, v3])\n", " \n", " def make_normals(self):\n", " # Set the normal for each vertex to be perpendicular to the lower left corner of the quad.\n", " # The vectors a and b point to the right and up around a vertex in the xy plance.\n", " for i in range(L*L):\n", " x = int(i/L)\n", " y = i % L\n", " if x == L-1 or y == L-1: continue\n", " v = self.vertices[i]\n", " a = self.vertices[i+L].pos - v.pos\n", " b = self.vertices[i+1].pos - v.pos\n", " v.normal = cross(a,b)\n", " \n", " def replot(self):\n", " for i in range(L*L):\n", " x = int(i/L)\n", " y = i % L\n", " v = self.vertices[i]\n", " v.pos.y = self.evaluate(x,y)\n", " self.make_normals()\n", " \n", " def make_vertex(self,x,y,value):\n", " return vertex(pos=vec(y,value,x), color=color.cyan, normal=vec(0,1,0))\n", " \n", " def get_vertex(self,x,y):\n", " return self.vertices[x*L+y]\n", " \n", " def get_pos(self,x,y):\n", " return self.get_vertex(x,y).pos\n", "\n", "t = 0\n", "dt = 0.02\n", "def f(x, y):\n", " # Return the value of the function of x and y:\n", " return 0.7+0.2*sin(10*x)*cos(10*y)*sin(5*t)\n", "\n", "p = plot3D(f, 0, 1, 0, 1, 0, 1) # function, xmin, xmax, ymin, ymax (defaults 0, 1, 0, 1, 0, 1)\n", "\n", "run = True\n", "def running(ev):\n", " global run\n", " run = not run\n", "\n", "scene.bind('mousedown', running)\n", "scene.forward = vec(-0.7,-0.5,-1)\n", "\n", "while True:\n", " rate(30)\n", " if run:\n", " p.replot()\n", " t += dt\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "VPython", "language": "python", "name": "vpython" }, "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.5.1" } }, "nbformat": 4, "nbformat_minor": 0 }