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")
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)
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')
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"))
In [ ]: