Dry Friction mockup

Libraries

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

In [7]:
myfig={}

Sketch yaml definition

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

In [14]:
if sketchParse(libraries,myfig):
    if sketchParse(constants,myfig):
        if sketchParse(frame,myfig):
            if sketchParse(body,myfig):
                if sketchParse(plan,myfig):
                    if sketchParse(friction,myfig):
                        print("success")
success
In [15]:
d = myfig['friction'].draw()
In [16]:
drawing_tool.display()
In [17]:
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 [18]:
left = Button(
    description = '',
    icon = 'rotate-left',
)
left.on_click(doleft)
right = Button(
    description = '',
    icon = 'rotate-right',
)
right.on_click(doright)
output = Output()
In [19]:
applayout = AppLayout(
    center=output,
    footer=HBox([left,right]),
    pane_heights=[0, 6, 1]
)
#drawing_tool.mpl.ion()
In [20]:
applayout
In [21]:
with output:
    clear_output()
    display(drawing_tool.mpl.gcf().canvas)

Turn it interactiv

In [22]:
drawing_tool.mpl.ion()

Use left and right rotation button to rotate the sketch

Simulate sketch rotation

Using SVG

In [23]:
for i in range(0,10):
    doright(None)
    clear_output(wait=True)
    display(SVG(sketch2SVG()))
    time.sleep(0.01)
2020-08-05T18:54:57.809254 image/svg+xml Matplotlib v3.3.0, https://matplotlib.org/

Using PNG

In [24]:
for i in range(0,10):
    doright(None)
    clear_output(wait=True)
    display(sketch2PNG()) 
    time.sleep(0.01)

take a canvas snapshot

In [25]:
drawing_tool.mpl.gcf().canvas.print_png("friction.png")
from PIL import Image
img = Image.open("friction.png")
img
Out[25]:

Sketch composition

In [26]:
myfig['friction'].graphviz_dot('friction')
graphviz [('Composition:\\nfriction', 'Composition:\\nplan'), ('Composition:\\nplan', 'Composition:\\nbody'), ('Composition:\\nbody', 'Composition:\\nwheel'), ('Composition:\\nwheel', 'Rectangle:\\nouter'), ('Rectangle:\\nouter', 'Curve:\\nrectangle'), ('Composition:\\nbody', 'Force:\\nN'), ('Force:\\nN', 'Line:\\narrow'), ('Line:\\narrow', 'Curve:\\nline'), ('Force:\\nN', 'Text:\\ntext'), ('Composition:\\nbody', 'Text:\\nmc'), ('Composition:\\nplan', 'Wall:\\ninclined wall'), ('Wall:\\ninclined wall', 'Curve:\\nwall'), ('Composition:\\nplan', 'Line:\\nx start'), ('Line:\\nx start', 'Curve:\\nline'), ('Composition:\\nplan', 'Axis:\\nx axis'), ('Axis:\\nx axis', 'Arrow3:\\narrow'), ('Arrow3:\\narrow', 'Line:\\nline'), ('Line:\\nline', 'Curve:\\nline'), ('Arrow3:\\narrow', 'Line:\\nhead left'), ('Line:\\nhead left', 'Curve:\\nline'), ('Arrow3:\\narrow', 'Line:\\nhead right'), ('Line:\\nhead right', 'Curve:\\nline'), ('Axis:\\nx axis', 'Text:\\nlabel'), ('Composition:\\nplan', 'Text:\\nmA'), ('Composition:\\nplan', 'Text:\\nmB'), ('Composition:\\nfriction', 'Line:\\nground'), ('Line:\\nground', 'Curve:\\nline'), ('Composition:\\nfriction', 'Gravity:\\nmg'), ('Gravity:\\nmg', 'Line:\\narrow'), ('Line:\\narrow', 'Curve:\\nline'), ('Gravity:\\nmg', 'Text:\\ntext'), ('Composition:\\nfriction', 'Arc_wText:\\nangle'), ('Arc_wText:\\nangle', 'Arc:\\narc'), ('Arc:\\narc', 'Curve:\\narc'), ('Arc_wText:\\nangle', 'Text:\\ntext')] defaultdict(<function Shape.graphviz_dot.<locals>.<lambda> at 0x00000143A678E550>, {'Composition:\\nplan': 1, 'Composition:\\nfriction': 0, 'Composition:\\nbody': 1, 'Composition:\\nwheel': 1, 'Rectangle:\\nouter': 1, 'Curve:\\nrectangle': 1, 'Force:\\nN': 1, 'Line:\\narrow': 2, 'Curve:\\nline': 7, 'Text:\\ntext': 3, 'Text:\\nmc': 1, 'Wall:\\ninclined wall': 1, 'Curve:\\nwall': 1, 'Line:\\nx start': 1, 'Axis:\\nx axis': 1, 'Arrow3:\\narrow': 1, 'Line:\\nline': 1, 'Line:\\nhead left': 1, 'Line:\\nhead right': 1, 'Text:\\nlabel': 1, 'Text:\\nmA': 1, 'Text:\\nmB': 1, 'Line:\\nground': 1, 'Gravity:\\nmg': 1, 'Arc_wText:\\nangle': 1, 'Arc:\\narc': 1, 'Curve:\\narc': 1})
[('Composition:\\nfriction', 'Composition:\\nplan'), ('Composition:\\nplan', 'Composition:\\nbody'), ('Composition:\\nbody', 'Composition:\\nwheel'), ('Composition:\\nwheel', 'Rectangle:\\nouter'), ('Rectangle:\\nouter', 'Curve:\\nrectangle'), ('Composition:\\nbody', 'Force:\\nN'), ('Force:\\nN', 'Line:\\narrow (1)'), ('Line:\\narrow (1)', 'Curve:\\nline (1)'), ('Force:\\nN', 'Text:\\ntext (1)'), ('Composition:\\nbody', 'Text:\\nmc'), ('Composition:\\nplan', 'Wall:\\ninclined wall'), ('Wall:\\ninclined wall', 'Curve:\\nwall'), ('Composition:\\nplan', 'Line:\\nx start'), ('Line:\\nx start', 'Curve:\\nline (2)'), ('Composition:\\nplan', 'Axis:\\nx axis'), ('Axis:\\nx axis', 'Arrow3:\\narrow'), ('Arrow3:\\narrow', 'Line:\\nline'), ('Line:\\nline', 'Curve:\\nline (3)'), ('Arrow3:\\narrow', 'Line:\\nhead left'), ('Line:\\nhead left', 'Curve:\\nline (4)'), ('Arrow3:\\narrow', 'Line:\\nhead right'), ('Line:\\nhead right', 'Curve:\\nline (5)'), ('Axis:\\nx axis', 'Text:\\nlabel'), ('Composition:\\nplan', 'Text:\\nmA'), ('Composition:\\nplan', 'Text:\\nmB'), ('Composition:\\nfriction', 'Line:\\nground'), ('Line:\\nground', 'Curve:\\nline (6)'), ('Composition:\\nfriction', 'Gravity:\\nmg'), ('Gravity:\\nmg', 'Line:\\narrow (2)'), ('Line:\\narrow (2)', 'Curve:\\nline (7)'), ('Gravity:\\nmg', 'Text:\\ntext (2)'), ('Composition:\\nfriction', 'Arc_wText:\\nangle'), ('Arc_wText:\\nangle', 'Arc:\\narc'), ('Arc:\\narc', 'Curve:\\narc'), ('Arc_wText:\\nangle', 'Text:\\ntext (3)')]
Run dot -Tpng -o friction.png friction.dot
In [27]:
!dot -Tpng -o dotfriction.png friction.dot
from PIL import Image
img = Image.open("dotfriction.png")
img
Out[27]:
In [28]:
!dot -Tsvg -o dotfriction.svg friction.dot
In [29]:
display(SVG("dotfriction.svg"))
G Composition:\nfriction Composition: friction Composition:\nplan Composition: plan Composition:\nfriction->Composition:\nplan Line:\nground Line: ground Composition:\nfriction->Line:\nground Gravity:\nmg Gravity: mg Composition:\nfriction->Gravity:\nmg Arc_wText:\nangle Arc_wText: angle Composition:\nfriction->Arc_wText:\nangle Composition:\nbody Composition: body Composition:\nplan->Composition:\nbody Wall:\ninclined wall Wall: inclined wall Composition:\nplan->Wall:\ninclined wall Line:\nx start Line: x start Composition:\nplan->Line:\nx start Axis:\nx axis Axis: x axis Composition:\nplan->Axis:\nx axis Text:\nmA Text: mA Composition:\nplan->Text:\nmA Text:\nmB Text: mB Composition:\nplan->Text:\nmB Composition:\nwheel Composition: wheel Composition:\nbody->Composition:\nwheel Force:\nN Force: N Composition:\nbody->Force:\nN Text:\nmc Text: mc Composition:\nbody->Text:\nmc Rectangle:\nouter Rectangle: outer Composition:\nwheel->Rectangle:\nouter Curve:\nrectangle Curve: rectangle Rectangle:\nouter->Curve:\nrectangle Line:\narrow (1) Line: arrow (1) Force:\nN->Line:\narrow (1) Text:\ntext (1) Text: text (1) Force:\nN->Text:\ntext (1) Curve:\nline (1) Curve: line (1) Line:\narrow (1)->Curve:\nline (1) Curve:\nwall Curve: wall Wall:\ninclined wall->Curve:\nwall Curve:\nline (2) Curve: line (2) Line:\nx start->Curve:\nline (2) Arrow3:\narrow Arrow3: arrow Axis:\nx axis->Arrow3:\narrow Text:\nlabel Text: label Axis:\nx axis->Text:\nlabel Line:\nline Line: line Arrow3:\narrow->Line:\nline Line:\nhead left Line: head left Arrow3:\narrow->Line:\nhead left Line:\nhead right Line: head right Arrow3:\narrow->Line:\nhead right Curve:\nline (3) Curve: line (3) Line:\nline->Curve:\nline (3) Curve:\nline (4) Curve: line (4) Line:\nhead left->Curve:\nline (4) Curve:\nline (5) Curve: line (5) Line:\nhead right->Curve:\nline (5) Curve:\nline (6) Curve: line (6) Line:\nground->Curve:\nline (6) Line:\narrow (2) Line: arrow (2) Gravity:\nmg->Line:\narrow (2) Text:\ntext (2) Text: text (2) Gravity:\nmg->Text:\ntext (2) Curve:\nline (7) Curve: line (7) Line:\narrow (2)->Curve:\nline (7) Arc:\narc Arc: arc Arc_wText:\nangle->Arc:\narc Text:\ntext (3) Text: text (3) Arc_wText:\nangle->Text:\ntext (3) Curve:\narc Curve: arc Arc:\narc->Curve:\narc
In [ ]: