pendulum.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. from pysketcher import *
  2. H = 7.
  3. W = 6.
  4. drawing_tool.set_coordinate_system(xmin=0, xmax=W,
  5. ymin=0, ymax=H,
  6. axis=False)
  7. drawing_tool.set_linecolor('blue')
  8. #drawing_tool.set_grid(True)
  9. def set_dashed_thin_blackline(*objects):
  10. """Set linestyle of an object to dashed, black, width=1."""
  11. for obj in objects:
  12. obj.set_linestyle('dashed')
  13. obj.set_linecolor('black')
  14. obj.set_linewidth(1)
  15. L = 5*H/7 # length
  16. P = (W/6, 0.85*H) # rotation point
  17. a = 40 # angle
  18. path = Arc(P, L, -90, a)
  19. angle = Arc_wText(r'$\theta$', P, L/4, -90, a, text_spacing=1/30.)
  20. vertical = Line(P, P-point(0,L))
  21. rod = Line(P, P + L*point(sin(radians(a)), -L*cos(radians(a))))
  22. # or shorter (and more reliable)
  23. mass_pt = path.geometric_features()['end']
  24. rod = Line(P, mass_pt)
  25. mass = Circle(center=mass_pt, radius=L/20.)
  26. mass.set_filled_curves(color='blue')
  27. rod_vec = rod.geometric_features()['end'] - rod.geometric_features()['start']
  28. mass_symbol = Text('$m$', mass_pt + L/10*unit_vec(rod_vec))
  29. length = Distance_wText(P, mass_pt, '$L$')
  30. # Displace length indication
  31. length.translate(L/15*point(cos(radians(a)), sin(radians(a))))
  32. gravity = Gravity(start=P+point(0.8*L,0), length=L/3)
  33. set_dashed_thin_blackline(vertical, path)
  34. dims = Composition(
  35. {'vertical': vertical, 'theta': angle, 'path': path,
  36. 'g': gravity, 'L': length, 'm': mass_symbol})
  37. fig = Composition({'body': mass, 'rod': rod, 'dims': dims})
  38. #drawing_tool.ax.set_xlim(4,10)
  39. #drawing_tool.ax.set_ylim(1,8)
  40. fig.draw()
  41. drawing_tool.display()
  42. drawing_tool.savefig('tmp_pendulum1')
  43. # Draw body diagram
  44. raw_input('Press Return to make body diagram: ')
  45. #import time; time.sleep(3)
  46. drawing_tool.erase()
  47. drawing_tool.set_linecolor('black')
  48. mg_force = Force(mass_pt, mass_pt + L/5*point(0,-1), '$mg$', text_pos='end')
  49. rod_force = Force(mass_pt, mass_pt - L/3*unit_vec(rod_vec),
  50. '$S$', text_pos='end')
  51. rod_start = rod.geometric_features()['start']
  52. vertical2 = Line(rod_start, rod_start + point(0,-L/3))
  53. set_dashed_thin_blackline(vertical2)
  54. set_dashed_thin_blackline(rod)
  55. angle2 = Arc_wText(r'$\theta$', rod_start, L/6, -90, a, text_spacing=1/30.)
  56. # Cannot understand this one:
  57. #path2 = Arc(P, L, -90+a-a/2., a)
  58. #path2.set_arrow('<-')
  59. #path2.set_linestyle('dashed')
  60. body_diagram = Composition(
  61. {'mg': mg_force, 'S': rod_force, 'rod': rod,
  62. 'vertical': vertical2, 'theta': angle2,
  63. #'path': path2,
  64. 'body': mass, 'm': mass_symbol})
  65. body_diagram.draw()
  66. drawing_tool.display('Body diagram')
  67. drawing_tool.savefig('tmp_pendulum2')
  68. drawing_tool.adjust_coordinate_system(body_diagram.minmax_coordinates(), 90)
  69. drawing_tool.display('Body diagram')
  70. drawing_tool.savefig('tmp_pendulum3')
  71. raw_input()