%matplotlib widget
import matplotlib as mpl mpl.rc('text', usetex = True) mpl.rc('font', family = 'serif')
import time
from pysketcher import *
from ipywidgets import FloatSlider, AppLayout, Label, HBox, Button, Output
from IPython.display import HTML, SVG, display, clear_output
from math import tan, radians, sin, cos
myfig={}
sketch = Sketch(myfig)
libraries = """\
name: head
shapes:
libraries: ["from math import tan, radians, sin, cos","from pysketcher import *"]
"""
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
"""
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
"""
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
"""
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})"
"""
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})"
"""
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")
d = myfig['friction'].draw()
drawing_tool.display()
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()
left = Button(
description = '',
icon = 'rotate-left',
)
left.on_click(doleft)
right = Button(
description = '',
icon = 'rotate-right',
)
right.on_click(doright)
output = Output()
applayout = AppLayout(
center=output,
footer=HBox([left,right]),
pane_heights=[0, 6, 1]
)
#drawing_tool.mpl.ion()
applayout
with output:
clear_output()
display(drawing_tool.mpl.gcf().canvas)
drawing_tool.mpl.ion()
Use left and right rotation button to rotate the sketch
for i in range(0,10):
doright(None)
clear_output(wait=True)
display(SVG(Sketch.matplotlib2SVG()))
time.sleep(0.01)
for i in range(0,10):
doright(None)
clear_output(wait=True)
display(Sketch.matplotlib2PNG())
time.sleep(0.01)
drawing_tool.mpl.gcf().canvas.print_png("friction.png")
from PIL import Image
img = Image.open("friction.png")
img
myfig['friction'].graphviz_dot('friction')
!dot -Tpng -o dotfriction.png friction.dot
from PIL import Image
img = Image.open("dotfriction.png")
img
!dot -Tsvg -o dotfriction.svg friction.dot
display(SVG("dotfriction.svg"))
sketchstring = sketch.getSketch()
import sys
sys.stdout.write(sketchstring)
sketch.loadSketch(sketchstring)