{ "cells": [ { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "from jp_doodle import doodle_files\n", "vf_js = doodle_files.vendor_path(\"js/canvas_2d_vector_field.js\")\n", "from jp_doodle import dual_canvas\n", "import jp_proxy_widget" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "22ce57770b1e44a286e0141ec05cd91c", "version_major": 2, "version_minor": 0 }, "text/html": [ "<p>Failed to display Jupyter Widget of type <code>VBox</code>.</p>\n", "<p>\n", " If you're reading this message in Jupyter Notebook or JupyterLab, it may mean\n", " that the widgets JavaScript is still loading. If this message persists, it\n", " likely means that the widgets JavaScript library is either not installed or\n", " not enabled. See the <a href=\"https://ipywidgets.readthedocs.io/en/stable/user_install.html\">Jupyter\n", " Widgets Documentation</a> for setup instructions.\n", "</p>\n", "<p>\n", " If you're reading this message in another notebook frontend (for example, a static\n", " rendering on GitHub or <a href=\"https://nbviewer.jupyter.org/\">NBViewer</a>),\n", " it may mean that your frontend doesn't currently support widgets.\n", "</p>\n" ], "text/plain": [ "VBox(children=(JSProxyWidget(status=u'Not yet rendered'), Text(value=u'Not yet rendered', description=u'status:'), Text(value=u'No error', description=u'error'), Output(layout=Layout(border=u'1px solid black'))))" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "w = jp_proxy_widget.JSProxyWidget()\n", "w.load_js_files([vf_js])\n", "dual_canvas.load_requirements(w)\n", "w.js_init(\"\"\"\n", "debugger;\n", "element.canvas_2d_vector_field.example(element);\n", "\"\"\")\n", "\n", "w.debugging_display()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "element" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "w.element.reset_canvas()" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.60555127546\n" ] }, { "data": { "text/plain": [ "(array([[ 0.30242086, 0.57327401, 0.87441002],\n", " [ 0.8699484 , 0.32549768, 0.29876122]]),\n", " array([[ 0.27784884, 0.52669488, 0.80336326],\n", " [ 0.89160212, 0.33359958, 0.30619763]]))" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "print np.linalg.norm((2,3))\n", "x = np.random.random((2,3))\n", "\n", "def unitize(vectors):\n", " (nr, nc) = vectors.shape\n", " norms = np.linalg.norm(vectors, axis=1)\n", " return vectors/norms.reshape((nr, 1))\n", "\n", "(x, unitize(x))\n" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "# random motions from 1000 random positions\n", "npoints = 100\n", "duration = 1\n", "shape = (npoints, 2)\n", "points = np.random.random(shape) * 2.0 - 1.0\n", "max_movement = 0.2\n", "movement = max_movement * (np.random.random(shape) * 2.0 - 1.0)\n", "offsets = np.random.random((npoints,)) * duration\n", "motions = []\n", "for i in range(npoints):\n", " (x, y) = points[i]\n", " (dx, dy) = movement[i]\n", " motion = {\n", " \"sx\": x-dx, \"sy\": y-dy, \"ex\": x+dx, \"ey\": y+dy, \"dt\": offsets[i]\n", " }\n", " motions.append(motion)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "f5d113cb241b4215afa3110934a1a330", "version_major": 2, "version_minor": 0 }, "text/html": [ "<p>Failed to display Jupyter Widget of type <code>Tab</code>.</p>\n", "<p>\n", " If you're reading this message in Jupyter Notebook or JupyterLab, it may mean\n", " that the widgets JavaScript is still loading. If this message persists, it\n", " likely means that the widgets JavaScript library is either not installed or\n", " not enabled. See the <a href=\"https://ipywidgets.readthedocs.io/en/stable/user_install.html\">Jupyter\n", " Widgets Documentation</a> for setup instructions.\n", "</p>\n", "<p>\n", " If you're reading this message in another notebook frontend (for example, a static\n", " rendering on GitHub or <a href=\"https://nbviewer.jupyter.org/\">NBViewer</a>),\n", " it may mean that your frontend doesn't currently support widgets.\n", "</p>\n" ], "text/plain": [ "Tab(children=(VBox(children=(SnapshotCanvas(status=u'Not yet rendered'), JSProxyWidget(status=u'Not yet rendered'))), HTML(value=u'<img src=\"vector_field.png?id=snapshot_id_9_1539974981245\" id=\"snapshot_id_9_1539974981245\"/>\\n <div id=\"snapshot_id_10_1539974981246\">vector_field.png</div>')), _titles={u'1': 'Snapshot', u'0': 'Canvas'})" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def show_motions(motions, duration=1, radius=0.01): \n", " #c2 = dual_canvas.DualCanvasWidget(width=800, height=800)\n", " c2 = dual_canvas.SnapshotCanvas(\"vector_field.png\", width=800, height=800)\n", " c2.js_init(\"\"\"\n", " var frame0 = element.frame_region(50, 50, 300, 300, -1, -1, 1, 1);\n", " element.frame0 = frame0;\n", " frame0.frame_rect({x:-1, y:-1, w:2, h:2, color:\"#ddf\"});\n", " frame0.lower_left_axes({min_x:-1, min_y:-1, max_x:1, max_y:1, max_tick_count:4});\n", " var frame = element.frame_region(50, 50, 300, 300, -1, -1, 1, 1);\n", " var f_options = {\n", " frame: frame,\n", " duration: duration, // seconds\n", " initial_color: \"red\",\n", " final_color: \"red\",\n", " radius: radius,\n", " motions: motions,\n", " shape: \"line\",\n", " };\n", " element.fit(null, 50)\n", " element.canvas_2d_vector_field(f_options);\n", " \"\"\", motions=motions, duration=duration, radius=radius)\n", " #return c2.debugging_display()\n", " return c2\n", "\n", "c2 = show_motions(motions, duration)\n", "c2.display_all()" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "element" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c2.element.reset_canvas()" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "#points" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "#motions" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "# attraction towards the center\n", "xc = 0.3\n", "yc = 0.4\n", "npoints = 100\n", "duration = 1\n", "shape = (npoints, 2)\n", "points = np.random.random(shape) * 2.0 - 1.0\n", "max_movement = 0.2\n", "shift = np.array([[xc, yc]]) - points\n", "movement = max_movement * shift\n", "offsets = np.random.random((npoints,)) * duration\n", "motions = []\n", "for i in range(npoints):\n", " (x, y) = points[i]\n", " (dx, dy) = movement[i]\n", " motion = {\n", " \"sx\": x-dx, \"sy\": y-dy, \"ex\": x+dx, \"ey\": y+dy, \"dt\": offsets[i]\n", " }\n", " motions.append(motion)\n", " \n", "c3 = show_motions(motions, duration)\n", "#c3" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "# motion around the center point\n", "xc = 0.3\n", "yc = 0.4\n", "npoints = 100\n", "duration = 1\n", "shape = (npoints, 2)\n", "points = np.random.random(shape) * 2.0 - 1.0\n", "max_movement = 0.2\n", "shift = np.array([[xc, yc]]) - points\n", "shift2 = np.zeros(shape)\n", "shift2[:,0] = shift[:,1]\n", "shift2[:,1] = -shift[:,0]\n", "movement = max_movement * shift2\n", "offsets = np.random.random((npoints,)) * duration\n", "motions = []\n", "for i in range(npoints):\n", " (x, y) = points[i]\n", " (dx, dy) = movement[i]\n", " motion = {\n", " \"sx\": x-dx, \"sy\": y-dy, \"ex\": x+dx, \"ey\": y+dy, \"dt\": offsets[i]\n", " }\n", " motions.append(motion)\n", " \n", "c4 = show_motions(motions, duration)\n", "c4.js_init(\"\"\"\n", "debugger;\n", "element.frame0.frame_circle({x: xc, y:yc, r:max_movement, color:\"rgba(255,200,100,0.7)\"})\n", "\"\"\", xc=xc, yc=yc, max_movement=max_movement)\n", "#c4" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "element" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c4.element.reset_canvas()" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "4992e17da5dd456c9daa3070f0667fed", "version_major": 2, "version_minor": 0 }, "text/html": [ "<p>Failed to display Jupyter Widget of type <code>SnapshotCanvas</code>.</p>\n", "<p>\n", " If you're reading this message in Jupyter Notebook or JupyterLab, it may mean\n", " that the widgets JavaScript is still loading. If this message persists, it\n", " likely means that the widgets JavaScript library is either not installed or\n", " not enabled. See the <a href=\"https://ipywidgets.readthedocs.io/en/stable/user_install.html\">Jupyter\n", " Widgets Documentation</a> for setup instructions.\n", "</p>\n", "<p>\n", " If you're reading this message in another notebook frontend (for example, a static\n", " rendering on GitHub or <a href=\"https://nbviewer.jupyter.org/\">NBViewer</a>),\n", " it may mean that your frontend doesn't currently support widgets.\n", "</p>\n" ], "text/plain": [ "SnapshotCanvas(status=u'Not yet rendered')" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def attraction(cx, cy, points, factor=1.0):\n", " shift = factor * (np.array([[cx, cy]]) - points)\n", " return unitize(shift)\n", "\n", "def clockwise(cx, cy, points, factor=1.0):\n", " shift = attraction(cx, cy, points, factor=1.0)\n", " shift2 = np.zeros(shift.shape)\n", " shift2[:,0] = shift[:,1]\n", " shift2[:,1] = -shift[:,0]\n", " return shift2\n", "\n", "npoints = 1000\n", "duration = 1\n", "shape = (npoints, 2)\n", "points = np.random.random(shape) * 2.0 - 1.0\n", "shift = 0.25 * (\n", " #+ attraction(0.5, 0.5, points)\n", " + 2* attraction(-0.5, -0.5, points)\n", " + clockwise(0.5, -0.5, points, -1)\n", " + 3*clockwise(-0.5, 0.5, points, -1)\n", ")\n", "#shift = unitize(shift)\n", "max_movement = 0.2\n", "movement = max_movement * shift\n", "offsets = np.random.random((npoints,)) * duration\n", "motions = []\n", "for i in range(npoints):\n", " (x, y) = points[i]\n", " (dx, dy) = movement[i]\n", " motion = {\n", " \"sx\": x-dx, \"sy\": y-dy, \"ex\": x+dx, \"ey\": y+dy, \"dt\": offsets[i]\n", " }\n", " motions.append(motion)\n", " \n", "c4 = show_motions(motions, duration)\n", "c4" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "element" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c4.element.reset_canvas()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "# dump motions to file\n", "filename = \"motions.json\"\n", "f = open(filename, \"w\")\n", "f.write(\"[\\n\")\n", "for m in motions:\n", " f.write(\"{\")\n", " for k in m:\n", " v = m[k]\n", " f.write(\"%s:%2.2f,\" % (k, v))\n", " f.write(\"},\\n\")\n", "f.write(\"]\\n\")\n", "f.close()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "print(open(filename).read(3200))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "motions[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [] } ], "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.13" } }, "nbformat": 4, "nbformat_minor": 2 }