{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib widget" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from pysketcher import *" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from ipywidgets import FloatSlider, AppLayout, Label, HBox" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "from IPython.display import SVG, display" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import sys\n", "from ruamel.yaml import YAML\n", "from math import tan, radians, sin, cos" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "myfig={}" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "yaml = YAML()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "gw = \"\"\"\\\n", "libraries: [\"from math import tan, radians, sin, cos\",\"from pysketcher import *\"]\n", "fontsize: 18\n", "g: 9.81 # constant gravity\n", "theta: 30.0 # inclined plane angle\n", "L: 10.0 # scene length\n", "a: 1.0 #\n", "xmin: 0.0\n", "ymin: -3.0\n", "r: 1.0\n", "setframe:\n", " action: \"drawing_tool.set_coordinate_system(xmin=xmin, xmax=xmin+1.5*L,ymin=ymin, ymax=ymin+L+1,instruction_file='tmp_mpl.py')\"\n", "setblackline:\n", " action: \"drawing_tool.set_linecolor('black')\"\n", "B: point(a+L,0)\n", "A: point(a,tan(radians(theta))*L)\n", "normal_vec: point(sin(radians(theta)),cos(radians(theta)))\n", "tangent_vec: point(cos(radians(theta)),-sin(radians(theta)))\n", "help_line: Line(A,B)\n", "x: a + 3*L/10.\n", "y: help_line(x=x) \n", "contact: point(x, y) \n", "c: contact + r*normal_vec\n", "outer_wheel: \n", " formula: Circle(c, r)\n", " style:\n", " linecolor: blue\n", " filled_curves: blue\n", "hole: \n", " formula: Circle(c, r/2.)\n", " style:\n", " linecolor: blue\n", " filled_curves: white\n", "N: \n", " formula: Force(contact - 2*r*normal_vec, contact, r'$N$', text_pos='start')\n", " style:\n", " linecolor: black\n", "mg: \n", " formula: Gravity(c, 3*r, text='$Mg$')\n", " style:\n", " linecolor: black\n", "wheel: \n", " formula: \"Composition({'outer': outer_wheel, 'inner': hole})\" \n", " style:\n", " shadow: 4\n", "body: \n", " formula: \"Composition({'wheel': wheel, 'N': N, 'mg': mg})\"\n", " style:\n", " linecolor: black\n", "wall: \n", " formula: Wall(x=[A[0], B[0]], y=[A[1], B[1]], thickness=-0.25,transparent=False)\n", " style:\n", " linecolor: black \n", "angle: \n", " formula: \"Arc_wText(r'$theta$', center=B, radius=3, start_angle=180-theta, arc_angle=theta, fontsize=fontsize)\"\n", " style:\n", " linecolor: black\n", " linewidth: 1\n", "ground: \n", " formula: Line((B[0]-L/10., 0), (B[0]-L/2.,0))\n", " stlye:\n", " linecolor: black\n", " linestyle: dashed\n", " linewidth: 1\n", "x_const: \n", " formula: Line(contact, contact + point(0,4))\n", " style:\n", " linestyle: dotted\n", " transform: rotate(-theta, contact)\n", "x_axis: \n", " formula: \"Axis(start=contact+ 3*r*normal_vec, length=4*r,label='$x$', rotation_angle=-theta)\"\n", "fixed: \n", " formula: \"Composition({'angle': angle, 'inclined wall': wall,'ground': ground,'x start': x_const, 'x axis': x_axis})\"\n", "fig: \n", " formula: \"Composition({'body': body, 'fixed elements': fixed})\"\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "gwd = yaml.load(gw)\n", "#print(gwd['g'])\n", "#yaml.dump(gwd, sys.stdout)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "for _k in list(gwd.keys()):\n", " if _k == \"stop\":\n", " break\n", " _c = gwd[_k]\n", " _t = str(type(_c))\n", " if _k == \"libraries\":\n", " for l in _c:\n", " exec(l,myfig)\n", " #print(_k, _c, _t)\n", " if _t == \"\" or \\\n", " _t == \"\" or _t == \"\":\n", " _formula = f\"{_k} = {_c}\".replace(\"\",\"\\\\\") \n", " #print(_formula)\n", " exec(_formula,myfig)\n", " elif _t == \"\":\n", " #print(_c)\n", " _keys = list(_c.keys())\n", " #print(_keys)\n", " if 'formula' in _keys:\n", " _formula = f\"{_k} = {_c['formula']}\".replace(\"\",\"\\\\\")\n", " #print(_formula)\n", " exec(_formula,myfig)\n", " if 'style' in _keys:\n", " for _style in _c[\"style\"]:\n", " # x_const.set_linestyle('dotted')\n", " _param = _c[\"style\"][_style]\n", " __t = str(type(_param))\n", " #print(__t)\n", " if __t == \"\":\n", " _style = f\"{_k}.set_{_style}({_param})\"\n", " else:\n", " _style = f\"{_k}.set_{_style}('{_param}')\"\n", " #print(_style)\n", " exec(_style,myfig)\n", " if 'transform' in _keys:\n", " #print(_c['transform'])\n", " if str(type(_c['transform'])) == \"\":\n", " _t = f\"{_k}.{_c['transform']}\"\n", " #print(_t)\n", " exec(_t,myfig)\n", " else:\n", " for _transform in _c[\"transform\"]:\n", " # x_const.rotate(-theta, contact)\n", " _t = f\"{_k}.{_c['transform']}\"\n", " #print(_t)\n", " exec(_t,myfig)\n", " if \"action\" in _keys:\n", " _action = _c[\"action\"]\n", " #print(_action)\n", " exec(_action,myfig)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "d = myfig['fig'].draw()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "drawing_tool.display()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "def position(t):\n", " \"\"\"Position of center point of wheel.\"\"\"\n", " global tangent_vec,c,myfig\n", " return myfig['c'] + 0.5*myfig['g']*t**2*myfig['tangent_vec']\n", "t = 0\n", "def move(change):\n", " global fig,t,label,x,x0,dt\n", " dt = change.new - t \n", " t = change.new\n", " drawing_tool.erase()\n", " x = position(t)\n", " x0 = position(t-dt)\n", " displacement = x - x0 \n", " myfig['fig']['body'].translate(displacement)\n", " myfig['fig'].draw()\n", " label.value = f\"p:{x}\"" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "slider = FloatSlider(\n", " orientation='horizontal',\n", " description='Time:',\n", " value=0.0,\n", " min=0.0,\n", " max=1.0,\n", " step = 1.0 / 30\n", ")\n", "slider.observe(move, 'value')" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "label = Label(value=\"\")" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "0d24f9e65d9642e49d10453a9b1f0cfe", "version_major": 2, "version_minor": 0 }, "text/plain": [ "AppLayout(children=(HBox(children=(FloatSlider(value=0.0, description='Time:', max=1.0, step=0.033333333333333…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "AppLayout(\n", " center=drawing_tool.mpl.gcf().canvas,\n", " footer=HBox([slider,label]),\n", " pane_heights=[0, 6, 1]\n", ")\n", "#drawing_tool.mpl.ion()" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "drawing_tool.mpl.ion()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "myfig['fig'].graphviz_dot('fig')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!dot -Tpng -o fig.png fig.dot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](fig.png)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "drawing_tool.mpl.gcf().canvas.print_png(\"fig1.png\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](fig1.png)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", " \n", " \n", " \n", " \n", " 2020-08-01T10:34:52.138957\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.3.0, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from io import BytesIO\n", "f = BytesIO()\n", "drawing_tool.mpl.savefig(f, format=\"svg\")\n", "display(SVG(f.getvalue()))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }