# Dry Friction mockup¶

## Content¶

- Libraries
- Sketch container
- Sketch Parts yaml definition
- Read yaml sketch definition, draw it
- Simulate sketch rotation
- Sketch composition
- Sketch serialization

## Libraries¶

home

In [1]:

    %matplotlib widget

import matplotlib as mpl mpl.rc('text', usetex = True) mpl.rc('font', family = 'serif')

In [2]:

    import time

In [3]:

    from pysketcher import *

In [4]:

    from ipywidgets import FloatSlider, AppLayout, Label, HBox, Button, Output

In [5]:

    from IPython.display import HTML, SVG, display, clear_output

In [6]:

    from math import tan, radians, sin, cos

## Sketch container¶

home

In [7]:

    myfig={}
    sketch = Sketch(myfig)

## Sketch Parts yaml definition¶

home

In [8]:

    libraries = """\
    name: head
    shapes:
        libraries: ["from math import tan, radians, sin, cos","from pysketcher import *"]
    """

In [9]:

    constants = """\
    name: constants
    shapes:
        fontsize: 18         # size of the characters
        g: 9.81              # constant gravity
        theta: 30.0          # inclined plane angle
        L: 10.0              # sketch sizing parameter
        a: 1.0               #
        xmin: 0.0            # sketech min Abscissa
        ymin: -3.0           # sketech min Ordinate
        rl: 2.0              # rectangle width
        rL: 1.0              # rectangle length
    """

In [10]:

    frame = """\
    name: frame
    shapes:
        setframe:            # sketch setup
            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')"
        setblackline:        # default frame values and actions
            action: "drawing_tool.set_linecolor('black')"
        B: point(a+L,0)                      # wall right end
        A: point(a,tan(radians(theta))*L)    # wall left end
        normal_vec: point(sin(radians(theta)),cos(radians(theta)))     # Vector normal to wall
        tangent_vec: point(cos(radians(theta)),-sin(radians(theta)))   # Vector tangent to wall
        help_line: Line(A,B)                 # wall line
        x: a + 3*L/10.                       # contact point Abscissa
        y: help_line(x=x)                    # contact point Ordinate
        contact: point(x, y)                 # contact point: middle of the rectangle bottom edge
        c: contact + rL/2*normal_vec
    """

In [11]:

    body = """\
    name: body
    shapes:
        rectangle:
            formula: Rectangle(contact, rl, rL)
            style:
                linecolor: blue
                filled_curves: blue
            transform: ["rotate(-theta, contact)",
                        "translate(-rl/2*tangent_vec)"]
        N:
            formula: Force(contact - rl*normal_vec, contact, r'$N$', text_pos='start')
            style:
                linecolor: black
        wheel:
            formula: "Composition({'outer': rectangle})"
            style:
                shadow: 1
        mc:
            formula: Text(r'$c$', c)
        body:
            formula: "Composition({'wheel': wheel, 'N': N, 'mc': mc})"
            style:
                linecolor: black
    """

In [12]:

    plan = """\
    name: plan
    shapes:
        mB:
            formula: Text(r'$B$',B)
        mA:
            formula: Text(r'$A$', A)
        wall:
            formula: Wall(x=[A[0], B[0]], y=[A[1], B[1]], thickness=-0.25,transparent=False)
            style:
                linecolor: black
        x_const:
            formula: Line(contact, contact + point(0,4))
            style:
                linestyle: dotted
            transform: rotate(-theta, contact)
        x_axis:
            formula: "Axis(start=contact+ 2*rl*normal_vec, length=2*rl,label='$x$', rotation_angle=-theta)"
        plan:
            formula: "Composition({'body': body, 'inclined wall': wall, 'x start': x_const, 'x axis': x_axis, 'mA': mA, 'mB': mB})"
    """

In [13]:

    friction = """\
    name: friction
    shapes:
        mg:
            formula: Gravity(c, rl, text='$Mg$')
            style:
                linecolor: black
        angle:
            formula: "Arc_wText(r'$<bslash>theta$', center=B, radius=3, start_angle=180-theta, arc_angle=theta, fontsize=fontsize)"
            style:
                linecolor: black
                linewidth: 1
        ground:
             formula: Line((B[0]-L/10., 0), (B[0]-L/2.,0))
             stlye:
                 linecolor: black
                 linestyle: dashed
                 linewidth: 1
        friction:
                formula: "Composition({'plan': plan, 'ground': ground, 'mg': mg, 'angle': angle})"
    """

## Read yaml sketch definition, draw it¶

home

In [14]:

    if sketch.append(libraries):
        if sketch.append(constants):
            if sketch.append(frame):
                if sketch.append(body):
                    if sketch.append(plan):
                        if sketch.append(friction):
                            print("success")

    success

In [31]:

    d = myfig['friction'].draw()

In [32]:

    drawing_tool.display()

In [33]:

    def doright(change):
        rotate(-5)
    def doleft(change):
        rotate(5)
    def rotate(theta):
        angle = myfig['theta']
        angle -= theta
        myfig['theta'] = angle
        drawing_tool.erase()
        x = myfig['plan']['body']['mc'].x
        y = myfig['plan']['body']['mc'].y
        myfig['plan'].rotate(theta,myfig['B'])
        xf = myfig['plan']['body']['mc'].x
        yf = myfig['plan']['body']['mc'].y
        trans = point(xf-x,yf-y)
        myfig['angle'].changeAngle(180-angle, angle)
        myfig['mg'].translate(trans)
        myfig['friction'].draw()

In [34]:

    left = Button(
        description = '',
        icon = 'rotate-left',
    )
    left.on_click(doleft)
    right = Button(
        description = '',
        icon = 'rotate-right',
    )
    right.on_click(doright)
    output = Output()

In [35]:

    applayout = AppLayout(
        center=output,
        footer=HBox([left,right]),
        pane_heights=[0, 6, 1]
    )
    #drawing_tool.mpl.ion()

In [36]:

    applayout

In [37]:

    with output:
        clear_output()
        display(drawing_tool.mpl.gcf().canvas)

### Turn it interactiv¶

In [39]:

    drawing_tool.mpl.ion()

Use left and right rotation button to rotate the sketch

## Simulate sketch rotation¶

home

### Using SVG¶

In [38]:

    for i in range(0,10):
        doright(None)
        clear_output(wait=True)
        display(SVG(Sketch.matplotlib2SVG()))
        time.sleep(0.01)

### Using PNG¶

In [ ]:

    for i in range(0,10):
        doright(None)
        clear_output(wait=True)
        display(Sketch.matplotlib2PNG())
        time.sleep(0.01)

### take a canvas snapshot¶

In [ ]:

    drawing_tool.mpl.gcf().canvas.print_png("friction.png")
    from PIL import Image
    img = Image.open("friction.png")
    img

## Sketch composition¶

home

In [ ]:

    myfig['friction'].graphviz_dot('friction')

In [ ]:

    !dot -Tpng -o dotfriction.png friction.dot
    from PIL import Image
    img = Image.open("dotfriction.png")
    img

In [ ]:

    !dot -Tsvg -o dotfriction.svg friction.dot

In [ ]:

    display(SVG("dotfriction.svg"))

## Sketch serialization¶

home

In [27]:

    sketchstring = sketch.getSketch()

In [28]:

    import sys

In [29]:

    sys.stdout.write(sketchstring)

    !!omap
    - name: unknown
    - parts:
      - name: head
        shapes:
          libraries: ['from math import tan, radians, sin, cos', from pysketcher import
              *]
      - name: constants
        shapes:
          fontsize: 18       # size of the characters
          g: 9.81            # constant gravity
          theta: 30.0        # inclined plane angle
          L: 10.0            # sketch sizing parameter
          a: 1.0             #
          xmin: 0.0          # sketech min Abscissa
          ymin: -3.0         # sketech min Ordinate
          rl: 2.0            # rectangle width
          rL: 1.0            # rectangle length
      - name: frame
        shapes:
          setframe:          # sketch setup
            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')
          setblackline:      # default frame values and actions
            action: drawing_tool.set_linecolor('black')
          B: point(a+L,0)                    # wall right end
          A: point(a,tan(radians(theta))*L)  # wall left end
          normal_vec: point(sin(radians(theta)),cos(radians(theta)))   # Vector normal to wall
          tangent_vec: point(cos(radians(theta)),-sin(radians(theta))) # Vector tangent to wall
          help_line: Line(A,B)               # wall line
          x: a + 3*L/10.                     # contact point Abscissa
          y: help_line(x=x)                  # contact point Ordinate
          contact: point(x, y)               # contact point: middle of the rectangle bottom edge
          c: contact + rL/2*normal_vec
      - name: body
        shapes:
          rectangle:
            formula: Rectangle(contact, rl, rL)
            style:
              linecolor: blue
              filled_curves: blue
            transform: ['rotate(-theta, contact)', translate(-rl/2*tangent_vec)]
          N:
            formula: Force(contact - rl*normal_vec, contact, r'$N$', text_pos='start')
            style:
              linecolor: black
          wheel:
            formula: "Composition({'outer': rectangle})"
            style:
              shadow: 1
          mc:
            formula: Text(r'$c$', c)
          body:
            formula: "Composition({'wheel': wheel, 'N': N, 'mc': mc})"
            style:
              linecolor: black
      - name: plan
        shapes:
          mB:
            formula: Text(r'$B$',B)
          mA:
            formula: Text(r'$A$', A)
          wall:
            formula: Wall(x=[A[0], B[0]], y=[A[1], B[1]], thickness=-0.25,transparent=False)
            style:
              linecolor: black
          x_const:
            formula: Line(contact, contact + point(0,4))
            style:
              linestyle: dotted
            transform: rotate(-theta, contact)
          x_axis:
            formula: Axis(start=contact+ 2*rl*normal_vec, length=2*rl,label='$x$', rotation_angle=-theta)
          plan:
            formula: "Composition({'body': body, 'inclined wall': wall, 'x start': x_const,\
              \ 'x axis': x_axis, 'mA': mA, 'mB': mB})"
      - name: friction
        shapes:
          mg:
            formula: Gravity(c, rl, text='$Mg$')
            style:
              linecolor: black
          angle:
            formula: Arc_wText(r'$<bslash>theta$', center=B, radius=3, start_angle=180-theta,
              arc_angle=theta, fontsize=fontsize)
            style:
              linecolor: black
              linewidth: 1
          ground:
            formula: Line((B[0]-L/10., 0), (B[0]-L/2.,0))
            stlye:
              linecolor: black
              linestyle: dashed
              linewidth: 1
          friction:
            formula: "Composition({'plan': plan, 'ground': ground, 'mg': mg, 'angle':\
              \ angle})"

In [30]:

    sketch.loadSketch(sketchstring)

Out[30]:

    True

In [ ]: