{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Dry Friction Test Case" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Content" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- [Libraries](#Libraries)\n", "- [Sketch container](#Sketch-container)\n", "- [Sketch Parts yaml definition](#Sketch-Parts-yaml-definition)\n", "- [Read yaml sketch definition, draw it](#Read-yaml-sketch-definition,-draw-it)\n", "- [Simulate sketch rotation](#Simulate-sketch-rotation)\n", "- [Sketch composition](#Sketch-composition)\n", "- [Sketch serialization](#Sketch-serialization)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Libraries" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[home](#Content)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib widget" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "import matplotlib as mpl\n", "mpl.rc('text', usetex = True)\n", "mpl.rc('font', family = 'serif')" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import time" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from pysketcher import *" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from ipywidgets import FloatSlider, AppLayout, Label, HBox, Button, Output" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from IPython.display import HTML, SVG, display, clear_output" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from math import tan, radians, sin, cos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sketch container" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[home](#Table-of-Content)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "myfig={}\n", "sketch = Sketch(myfig)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sketch Parts yaml definition" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[home](#Content)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "libraries = \"\"\"\\\n", "name: head\n", "shapes:\n", " libraries: [\"from math import tan, radians, sin, cos\",\"from pysketcher import *\"]\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "constants = \"\"\"\\\n", "name: constants\n", "shapes:\n", " fontsize: 18 # size of the characters\n", " g: 9.81 # constant gravity\n", " theta: 30.0 # inclined plane angle\n", " L: 10.0 # sketch sizing parameter\n", " a: 1.0 #\n", " xmin: 0.0 # sketech min Abscissa\n", " ymin: -3.0 # sketech min Ordinate \n", " rl: 2.0 # rectangle width\n", " rL: 1.0 # rectangle length\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "frame = \"\"\"\\\n", "name: frame\n", "shapes:\n", " setframe: # sketch setup\n", " action: \"drawing_tool.set_coordinate_system(xmin=xmin-L/5, xmax=xmin+1.5*L,ymin=ymin, ymax=ymin+1.5*L,instruction_file='tmp_mpl_friction.py')\"\n", " setblackline: # default frame values and actions\n", " action: \"drawing_tool.set_linecolor('black')\"\n", " B: point(a+L,0) # wall right end\n", " A: point(a,tan(radians(theta))*L) # wall left end\n", " normal_vec: point(sin(radians(theta)),cos(radians(theta))) # Vector normal to wall\n", " tangent_vec: point(cos(radians(theta)),-sin(radians(theta))) # Vector tangent to wall\n", " help_line: Line(A,B) # wall line\n", " x: a + 3*L/10. # contact point Abscissa\n", " y: help_line(x=x) # contact point Ordinate\n", " contact: point(x, y) # contact point: middle of the rectangle bottom edge\n", " c: contact + rL/2*normal_vec\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "body = \"\"\"\\\n", "name: body\n", "shapes:\n", " rectangle: \n", " formula: Rectangle(contact, rl, rL)\n", " style:\n", " linecolor: blue\n", " filled_curves: \n", " color: blue\n", " transform: [\"rotate(-theta, contact)\",\n", " \"translate(-rl/2*tangent_vec)\"]\n", " N: \n", " formula: Force(contact - rl*normal_vec, contact, r'$N$', text_pos='start')\n", " style:\n", " linecolor: black\n", " wheel: \n", " formula: \"Composition({'outer': rectangle})\" \n", " style:\n", " shadow: 1\n", " mc:\n", " formula: Text(r'$c$', c)\n", " body: \n", " formula: \"Composition({'wheel': wheel, 'N': N, 'mc': mc})\"\n", " style:\n", " linecolor: black\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "plan = \"\"\"\\\n", "name: plan\n", "shapes:\n", " mB:\n", " formula: Text(r'$B$',B)\n", " mA:\n", " formula: Text(r'$A$', A)\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", " 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+ 2*rl*normal_vec, length=2*rl,label='$x$', rotation_angle=-theta)\"\n", " plan: \n", " formula: \"Composition({'body': body, 'inclined wall': wall, 'x start': x_const, 'x axis': x_axis, 'mA': mA, 'mB': mB})\"\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "friction = \"\"\"\\\n", "name: friction\n", "shapes:\n", " mg: \n", " formula: Gravity(c, rl, text='$Mg$')\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", " friction: \n", " formula: \"Composition({'plan': plan, 'ground': ground, 'mg': mg, 'angle': angle})\"\n", "\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Read yaml sketch definition, draw it" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[home](#Content)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "success\n" ] } ], "source": [ "if sketch.append(libraries):\n", " if sketch.append(constants):\n", " if sketch.append(frame):\n", " if sketch.append(body):\n", " if sketch.append(plan):\n", " if sketch.append(friction):\n", " print(\"success\")" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "d = myfig['friction'].draw()" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "drawing_tool.display()" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "def doright(change):\n", " rotate(-5)\n", "def doleft(change):\n", " rotate(5)\n", "def rotate(theta):\n", " angle = myfig['theta']\n", " angle -= theta\n", " myfig['theta'] = angle\n", " drawing_tool.erase()\n", " x = myfig['plan']['body']['mc'].x\n", " y = myfig['plan']['body']['mc'].y\n", " myfig['plan'].rotate(theta,myfig['B'])\n", " xf = myfig['plan']['body']['mc'].x\n", " yf = myfig['plan']['body']['mc'].y\n", " trans = point(xf-x,yf-y)\n", " myfig['angle'].changeAngle(180-angle, angle)\n", " myfig['mg'].translate(trans)\n", " myfig['friction'].draw()" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "left = Button(\n", " description = '',\n", " icon = 'rotate-left',\n", ")\n", "left.on_click(doleft)\n", "right = Button(\n", " description = '',\n", " icon = 'rotate-right',\n", ")\n", "right.on_click(doright)\n", "output = Output()" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "applayout = AppLayout(\n", " center=output,\n", " footer=HBox([left,right]),\n", " pane_heights=[0, 6, 1]\n", ")\n", "#drawing_tool.mpl.ion()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "0e343db62cba4a5d903b9aaa2db89e64", "version_major": 2, "version_minor": 0 }, "text/plain": [ "AppLayout(children=(HBox(children=(Button(icon='rotate-left', style=ButtonStyle()), Button(icon='rotate-right'…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "applayout" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "with output:\n", " clear_output()\n", " display(drawing_tool.mpl.gcf().canvas)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Turn it interactiv" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "drawing_tool.mpl.ion()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use left and right rotation button to rotate the sketch" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Simulate sketch rotation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[home](#Content)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using SVG" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "for i in range(0,10):\n", " doright(None)\n", " clear_output(wait=True)\n", " display(SVG(Sketch.matplotlib2SVG()))\n", " time.sleep(0.01)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using PNG" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "for i in range(0,10):\n", " doright(None)\n", " clear_output(wait=True)\n", " display(Sketch.matplotlib2PNG()) \n", " time.sleep(0.01)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### take a canvas snapshot" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "drawing_tool.mpl.gcf().canvas.print_png(\"friction.png\")\n", "from PIL import Image\n", "img = Image.open(\"friction.png\")\n", "img" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sketch composition" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[home](#Content)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "myfig['friction'].graphviz_dot('friction')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!dot -Tpng -o dotfriction.png friction.dot\n", "from PIL import Image\n", "img = Image.open(\"dotfriction.png\")\n", "img" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!dot -Tsvg -o dotfriction.svg friction.dot" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "display(SVG(\"dotfriction.svg\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sketch serialization" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[home](#Content)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### To and from string" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sketchstring = sketch.sketch2String()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import sys" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sys.stdout.write(sketchstring)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sketch.string2Sketch(sketchstring)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### To and from File" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### To File" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sketch.sketch2File(\"dryfriction.yml\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### From File" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sketch.file2Sketch(\"dryfriction.yml\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sketch.file2Sketch(\"springmass.yml\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sketch.container['springmass'].draw()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "display(SVG(Sketch.matplotlib2SVG()))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### From URL" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sketch.url2Sketch(\"https://raw.githubusercontent.com/gbrault/jupytersketches/master/dryfriction.yml\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "d = sketch.container['friction'].draw()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "display(SVG(Sketch.matplotlib2SVG()))" ] } ], "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 }