._pysketcher003.html 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. <!--
  2. Automatically generated HTML file from DocOnce source
  3. (https://github.com/hplgit/doconce/)
  4. -->
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  8. <meta name="generator" content="DocOnce: https://github.com/hplgit/doconce/" />
  9. <meta name="description" content="Using Pysketcher to Create Principal Sketches of Physics Problems">
  10. <meta name="keywords" content="tree data structure,recursive function calls">
  11. <title>Using Pysketcher to Create Principal Sketches of Physics Problems</title>
  12. <!-- Bootstrap style: bootswatch_readable -->
  13. <link href="http://netdna.bootstrapcdn.com/bootswatch/3.1.1/readable/bootstrap.min.css" rel="stylesheet">
  14. <!-- not necessary
  15. <link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
  16. -->
  17. <style type="text/css">
  18. /* Add scrollbar to dropdown menus in bootstrap navigation bar */
  19. .dropdown-menu {
  20. height: auto;
  21. max-height: 400px;
  22. overflow-x: hidden;
  23. }
  24. </style>
  25. </head>
  26. <!-- tocinfo
  27. {'highest level': 1,
  28. 'sections': [('A first glimpse of Pysketcher', 1, None, '___sec0'),
  29. ('Basic construction of sketches', 2, None, '___sec1'),
  30. ('Basic drawing', 3, None, '___sec2'),
  31. ('Groups of objects', 3, None, '___sec3'),
  32. ('Changing line styles and colors', 3, None, '___sec4'),
  33. ('The figure composition as an object hierarchy',
  34. 3,
  35. None,
  36. '___sec5'),
  37. ('Animation: translating the vehicle', 3, None, '___sec6'),
  38. ('Animation: rolling the wheels',
  39. 3,
  40. 'sketcher:vehicle1:anim',
  41. 'sketcher:vehicle1:anim'),
  42. ('A simple pendulum',
  43. 1,
  44. 'sketcher:ex:pendulum',
  45. 'sketcher:ex:pendulum'),
  46. ('The basic physics sketch',
  47. 2,
  48. 'sketcher:ex:pendulum:basic',
  49. 'sketcher:ex:pendulum:basic'),
  50. ('The body diagram', 2, None, '___sec10'),
  51. ('Basic shapes', 1, None, '___sec11'),
  52. ('Axis', 2, None, '___sec12'),
  53. ('Distance with text', 2, None, '___sec13'),
  54. ('Rectangle', 2, None, '___sec14'),
  55. ('Triangle', 2, None, '___sec15'),
  56. ('Arc', 2, None, '___sec16'),
  57. ('Spring', 2, None, '___sec17'),
  58. ('Dashpot', 2, None, '___sec18'),
  59. ('Wavy', 2, None, '___sec19'),
  60. ('Stochastic curves', 2, None, '___sec20'),
  61. ('Inner workings of the Pysketcher tool', 1, None, '___sec21'),
  62. ('Example of classes for geometric objects',
  63. 2,
  64. None,
  65. '___sec22'),
  66. ('Simple geometric objects', 3, None, '___sec23'),
  67. ('Class curve', 3, None, '___sec24'),
  68. ('Compound geometric objects', 3, None, '___sec25'),
  69. ('Adding functionality via recursion', 2, None, '___sec26'),
  70. ('Basic principles of recursion', 3, None, '___sec27'),
  71. ('Explaining recursion', 3, None, '___sec28'),
  72. ('Scaling, translating, and rotating a figure',
  73. 2,
  74. 'sketcher:scaling',
  75. 'sketcher:scaling'),
  76. ('Scaling', 3, None, '___sec30'),
  77. ('Translation', 3, None, '___sec31'),
  78. ('Rotation', 3, None, '___sec32')]}
  79. end of tocinfo -->
  80. <body>
  81. <script type="text/x-mathjax-config">
  82. MathJax.Hub.Config({
  83. TeX: {
  84. equationNumbers: { autoNumber: "none" },
  85. extensions: ["AMSmath.js", "AMSsymbols.js", "autobold.js", "color.js"]
  86. }
  87. });
  88. </script>
  89. <script type="text/javascript"
  90. src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
  91. </script>
  92. <!-- Bootstrap navigation bar -->
  93. <div class="navbar navbar-default navbar-fixed-top">
  94. <div class="navbar-header">
  95. <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse">
  96. <span class="icon-bar"></span>
  97. <span class="icon-bar"></span>
  98. <span class="icon-bar"></span>
  99. </button>
  100. <a class="navbar-brand" href="pysketcher.html">Using Pysketcher to Create Principal Sketches of Physics Problems</a>
  101. </div>
  102. <div class="navbar-collapse collapse navbar-responsive-collapse">
  103. <ul class="nav navbar-nav navbar-right">
  104. <li class="dropdown">
  105. <a href="#" class="dropdown-toggle" data-toggle="dropdown">Contents <b class="caret"></b></a>
  106. <ul class="dropdown-menu">
  107. <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec0" style="font-size: 80%;"><b>A first glimpse of Pysketcher</b></a></li>
  108. <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec1" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Basic construction of sketches</a></li>
  109. <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec2" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Basic drawing</a></li>
  110. <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec3" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Groups of objects</a></li>
  111. <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec4" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Changing line styles and colors</a></li>
  112. <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec5" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The figure composition as an object hierarchy</a></li>
  113. <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec6" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Animation: translating the vehicle</a></li>
  114. <!-- navigation toc: --> <li><a href="._pysketcher002.html#sketcher:vehicle1:anim" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Animation: rolling the wheels</a></li>
  115. <!-- navigation toc: --> <li><a href="#sketcher:ex:pendulum" style="font-size: 80%;"><b>A simple pendulum</b></a></li>
  116. <!-- navigation toc: --> <li><a href="#sketcher:ex:pendulum:basic" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;The basic physics sketch</a></li>
  117. <!-- navigation toc: --> <li><a href="#___sec10" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;The body diagram</a></li>
  118. <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec11" style="font-size: 80%;"><b>Basic shapes</b></a></li>
  119. <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec12" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Axis</a></li>
  120. <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec13" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Distance with text</a></li>
  121. <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec14" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Rectangle</a></li>
  122. <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec15" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Triangle</a></li>
  123. <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec16" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Arc</a></li>
  124. <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec17" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Spring</a></li>
  125. <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec18" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Dashpot</a></li>
  126. <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec19" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Wavy</a></li>
  127. <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec20" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Stochastic curves</a></li>
  128. <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec21" style="font-size: 80%;"><b>Inner workings of the Pysketcher tool</b></a></li>
  129. <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec22" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Example of classes for geometric objects</a></li>
  130. <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec23" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Simple geometric objects</a></li>
  131. <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec24" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class curve</a></li>
  132. <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec25" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Compound geometric objects</a></li>
  133. <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec26" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Adding functionality via recursion</a></li>
  134. <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec27" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Basic principles of recursion</a></li>
  135. <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec28" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Explaining recursion</a></li>
  136. <!-- navigation toc: --> <li><a href="._pysketcher005.html#sketcher:scaling" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;Scaling, translating, and rotating a figure</a></li>
  137. <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec30" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Scaling</a></li>
  138. <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec31" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Translation</a></li>
  139. <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec32" style="font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rotation</a></li>
  140. </ul>
  141. </li>
  142. </ul>
  143. </div>
  144. </div>
  145. </div> <!-- end of navigation bar -->
  146. <div class="container">
  147. <p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p> <!-- add vertical space -->
  148. <a name="part0003"></a>
  149. <!-- !split -->
  150. <h1 id="sketcher:ex:pendulum">A simple pendulum</h1>
  151. <h2 id="sketcher:ex:pendulum:basic">The basic physics sketch</h2>
  152. <p>
  153. We now want to make a sketch of simple pendulum from physics, as shown
  154. in Figure <a href="#sketcher:ex:pendulum:fig1">8</a>. A suggested work flow is to
  155. first sketch the figure on a piece of paper and introduce a coordinate
  156. system. A simple coordinate system is indicated in Figure
  157. <a href="#sketcher:ex:pendulum:fig1wgrid">9</a>. In a code we introduce variables
  158. <code>W</code> and <code>H</code> for the width and height of the figure (i.e., extent of
  159. the coordinate system) and open the program like this:
  160. <p>
  161. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  162. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">pysketcher</span> <span style="color: #008000; font-weight: bold">import</span> <span style="color: #666666">*</span>
  163. H <span style="color: #666666">=</span> <span style="color: #666666">7.</span>
  164. W <span style="color: #666666">=</span> <span style="color: #666666">6.</span>
  165. drawing_tool<span style="color: #666666">.</span>set_coordinate_system(xmin<span style="color: #666666">=0</span>, xmax<span style="color: #666666">=</span>W,
  166. ymin<span style="color: #666666">=0</span>, ymax<span style="color: #666666">=</span>H,
  167. axis<span style="color: #666666">=</span><span style="color: #008000">True</span>)
  168. drawing_tool<span style="color: #666666">.</span>set_grid(<span style="color: #008000">True</span>)
  169. drawing_tool<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;blue&#39;</span>)
  170. </pre></div>
  171. <p>
  172. Note that when the sketch is ready for &quot;production&quot;, we will (normally)
  173. set <code>axis=False</code> to remove the coordinate system and also remove the
  174. grid, i.e., delete or
  175. comment out the line <code>drawing_tool.set_grid(True)</code>.
  176. Also note that we in this example let all lines be blue by default.
  177. <p>
  178. <center> <!-- figure -->
  179. <hr class="figure">
  180. <center><p class="caption">Figure 8: Sketch of a simple pendulum. <div id="sketcher:ex:pendulum:fig1"></div> </p></center>
  181. <p><img src="fig-tut/pendulum1.png" align="bottom" width=400></p>
  182. </center>
  183. <p>
  184. <center> <!-- figure -->
  185. <hr class="figure">
  186. <center><p class="caption">Figure 9: Sketch of a simple pendulum. <div id="sketcher:ex:pendulum:fig1wgrid"></div> </p></center>
  187. <p><img src="fig-tut/pendulum1_wgrid.png" align="bottom" width=400></p>
  188. </center>
  189. <p>
  190. The next step is to introduce variables for key quantities in the sketch.
  191. Let <code>L</code> be the length of the pendulum, <code>P</code> the rotation point, and let
  192. <code>a</code> be the angle the pendulum makes with the vertical (measured in degrees).
  193. We may set
  194. <p>
  195. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  196. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">L <span style="color: #666666">=</span> <span style="color: #666666">5*</span>H<span style="color: #666666">/7</span> <span style="color: #408080; font-style: italic"># length</span>
  197. P <span style="color: #666666">=</span> (W<span style="color: #666666">/6</span>, <span style="color: #666666">0.85*</span>H) <span style="color: #408080; font-style: italic"># rotation point</span>
  198. a <span style="color: #666666">=</span> <span style="color: #666666">40</span> <span style="color: #408080; font-style: italic"># angle</span>
  199. </pre></div>
  200. <p>
  201. Be careful with integer division if you use Python 2! Fortunately, we
  202. started out with <code>float</code> objects for <code>W</code> and <code>H</code> so the expressions above
  203. are safe.
  204. <p>
  205. What kind of objects do we need in this sketch? Looking at
  206. Figure <a href="#sketcher:ex:pendulum:fig1">8</a> we see that we need
  207. <ol>
  208. <li> a vertical, dashed line</li>
  209. <li> an arc with no text but dashed line to indicate the <em>path</em> of the
  210. mass</li>
  211. <li> an arc with name \( \theta \) to indicate the <em>angle</em></li>
  212. <li> a line, here called <em>rod</em>, from the rotation point to the mass</li>
  213. <li> a blue, filled circle representing the <em>mass</em></li>
  214. <li> a text \( m \) associated with the mass</li>
  215. <li> an indicator of the pendulum's <em>length</em> \( L \), visualized as
  216. a line with two arrows tips and the text \( L \)</li>
  217. <li> a gravity vector with the text \( g \)</li>
  218. </ol>
  219. Pysketcher has objects for each of these elements in our sketch.
  220. We start with the simplest element: the vertical line, going from
  221. <code>P</code> to <code>P</code> minus the length in \( y \) direction:
  222. <p>
  223. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  224. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">vertical <span style="color: #666666">=</span> Line(P, P<span style="color: #666666">-</span>point(<span style="color: #666666">0</span>,L))
  225. </pre></div>
  226. <p>
  227. The path of the mass is an arc that can be made by
  228. Pysketcher's <code>Arc</code> object:
  229. <p>
  230. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  231. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">path <span style="color: #666666">=</span> Arc(P, L, <span style="color: #666666">-90</span>, a)
  232. </pre></div>
  233. <p>
  234. The first argument <code>P</code> is the center point, the second is the
  235. radius (<code>L</code> here), the next arguments is the start angle, here
  236. it starts at -90 degrees, while the next argument is the angle of
  237. the arc, here <code>a</code>.
  238. For the path of the mass, we also need an arc object, but this
  239. time with an associated text. Pysketcher has a specialized object
  240. for this purpose, <code>Arc_wText</code>, since placing the text manually can
  241. be somewhat cumbersome.
  242. <p>
  243. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  244. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">angle <span style="color: #666666">=</span> Arc_wText(<span style="color: #BA2121">r&#39;$\theta$&#39;</span>, P, L<span style="color: #666666">/4</span>, <span style="color: #666666">-90</span>, a, text_spacing<span style="color: #666666">=1/30.</span>)
  245. </pre></div>
  246. <p>
  247. The arguments are as for <code>Arc</code> above, but the first one is the desired
  248. text. Remember to use a raw string since we want a LaTeX greek letter
  249. that contains a backslash.
  250. The <code>text_spacing</code> argument must often be tweaked. It is recommended
  251. to create only a few objects before rendering the sketch and then
  252. adjust spacings as one goes along.
  253. <p>
  254. The rod is simply a line from <code>P</code> to the mass. We can easily
  255. compute the position of the mass from basic geometry considerations,
  256. but it is easier and safer to look up this point in other objects
  257. if it is already computed. The <code>path</code> object stores its start and
  258. end points, so <code>path.geometric_features()['end']</code> is the end point
  259. of the path, which is the position of the mass. We can therefore
  260. create the rod simply as a line from <code>P</code> to this end point:
  261. <p>
  262. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  263. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">mass_pt <span style="color: #666666">=</span> path<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">&#39;end&#39;</span>]
  264. rod <span style="color: #666666">=</span> Line(P, mass_pt)
  265. </pre></div>
  266. <p>
  267. The mass is a circle filled with color:
  268. <p>
  269. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  270. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">mass <span style="color: #666666">=</span> Circle(center<span style="color: #666666">=</span>mass_pt, radius<span style="color: #666666">=</span>L<span style="color: #666666">/20.</span>)
  271. mass<span style="color: #666666">.</span>set_filled_curves(color<span style="color: #666666">=</span><span style="color: #BA2121">&#39;blue&#39;</span>)
  272. </pre></div>
  273. <p>
  274. To place the \( m \) correctly, we go a small distance in the direction of
  275. the rod, from the center of the circle. To this end, we need to
  276. compute the direction. This is easiest done by computing a vector
  277. from <code>P</code> to the center of the circle and calling <code>unit_vec</code> to make
  278. a unit vector in this direction:
  279. <p>
  280. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  281. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">rod_vec <span style="color: #666666">=</span> rod<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">&#39;end&#39;</span>] <span style="color: #666666">-</span> \
  282. rod<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">&#39;start&#39;</span>]
  283. unit_rod_vec <span style="color: #666666">=</span> unit_vec(rod_vec)
  284. mass_symbol <span style="color: #666666">=</span> Text(<span style="color: #BA2121">&#39;$m$&#39;</span>, mass_pt <span style="color: #666666">+</span> L<span style="color: #666666">/10*</span>unit_rod_vec)
  285. </pre></div>
  286. <p>
  287. Again, the distance <code>L/10</code> is something one has to experiment with.
  288. <p>
  289. The next object is the length measure with the text \( L \). Such length
  290. measures are represented by Pysketcher's <code>Distance_wText</code> object.
  291. An easy construction is to first place this length measure along the
  292. rod and then translate it a little distance (<code>L/15</code>) in the
  293. normal direction of the rod:
  294. <p>
  295. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  296. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">length <span style="color: #666666">=</span> Distance_wText(P, mass_pt, <span style="color: #BA2121">&#39;$L$&#39;</span>)
  297. length<span style="color: #666666">.</span>translate(L<span style="color: #666666">/15*</span>point(cos(radians(a)), sin(radians(a))))
  298. </pre></div>
  299. <p>
  300. For this translation we need a unit vector in the normal direction
  301. of the rod, which is from geometric considerations given by
  302. \( (\cos a, \sin a) \), when \( a \) is the angle of the pendulum.
  303. <p>
  304. The final object is the gravity force vector, which is so common
  305. in physics sketches that Pysketcher has a ready-made object: <code>Gravity</code>,
  306. <p>
  307. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  308. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">gravity <span style="color: #666666">=</span> Gravity(start<span style="color: #666666">=</span>P<span style="color: #666666">+</span>point(<span style="color: #666666">0.8*</span>L,<span style="color: #666666">0</span>), length<span style="color: #666666">=</span>L<span style="color: #666666">/3</span>)
  309. </pre></div>
  310. <p>
  311. Since blue is the default color for
  312. lines, we want the dashed lines (<code>vertical</code> and <code>path</code>) to be black
  313. and dashed with linewidth 1. These properties can be set one by one,
  314. but we can also make a little helper function:
  315. <p>
  316. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  317. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">set_dashed_thin_blackline</span>(<span style="color: #666666">*</span>objects):
  318. <span style="color: #BA2121; font-style: italic">&quot;&quot;&quot;Set linestyle of an object to dashed, black, width=1.&quot;&quot;&quot;</span>
  319. <span style="color: #008000; font-weight: bold">for</span> obj <span style="color: #AA22FF; font-weight: bold">in</span> objects:
  320. obj<span style="color: #666666">.</span>set_linestyle(<span style="color: #BA2121">&#39;dashed&#39;</span>)
  321. obj<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;black&#39;</span>)
  322. obj<span style="color: #666666">.</span>set_linewidth(<span style="color: #666666">1</span>)
  323. set_dashed_thin_blackline(vertical, path)
  324. </pre></div>
  325. <p>
  326. Now, all objects are in place, so it remains to compose the final
  327. figure and draw the composition:
  328. <p>
  329. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  330. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">fig <span style="color: #666666">=</span> Composition(
  331. {<span style="color: #BA2121">&#39;body&#39;</span>: mass, <span style="color: #BA2121">&#39;rod&#39;</span>: rod,
  332. <span style="color: #BA2121">&#39;vertical&#39;</span>: vertical, <span style="color: #BA2121">&#39;theta&#39;</span>: angle, <span style="color: #BA2121">&#39;path&#39;</span>: path,
  333. <span style="color: #BA2121">&#39;g&#39;</span>: gravity, <span style="color: #BA2121">&#39;L&#39;</span>: length, <span style="color: #BA2121">&#39;m&#39;</span>: mass_symbol})
  334. fig<span style="color: #666666">.</span>draw()
  335. drawing_tool<span style="color: #666666">.</span>display()
  336. drawing_tool<span style="color: #666666">.</span>savefig(<span style="color: #BA2121">&#39;pendulum1&#39;</span>)
  337. </pre></div>
  338. <h2 id="___sec10">The body diagram </h2>
  339. <p>
  340. Now we want to isolate the mass and draw all the forces that act on it.
  341. Figure <a href="#sketcher:ex:pendulum:fig2wgrid">10</a> shows the desired result, but
  342. embedded in the coordinate system.
  343. We consider three types of forces: the gravity force, the force from the
  344. rod, and air resistance. The body diagram is key for deriving the
  345. equation of motion, so it is illustrative to add useful mathematical
  346. quantities needed in the derivation, such as the unit vectors in polar
  347. coordinates.
  348. <p>
  349. <center> <!-- figure -->
  350. <hr class="figure">
  351. <center><p class="caption">Figure 10: Body diagram of a simple pendulum. <div id="sketcher:ex:pendulum:fig2wgrid"></div> </p></center>
  352. <p><img src="fig-tut/pendulum5_wgrid.png" align="bottom" width=400></p>
  353. </center>
  354. <p>
  355. We start by listing the objects in the sketch:
  356. <ol>
  357. <li> a text \( (x_0,y_0) \) representing the rotation point <code>P</code></li>
  358. <li> unit vector \( \boldsymbol{i}_r \) with text</li>
  359. <li> unit vector \( \boldsymbol{i}_\theta \) with text</li>
  360. <li> a dashed vertical line</li>
  361. <li> a dashed line along the rod</li>
  362. <li> an arc with text \( \theta \)</li>
  363. <li> the gravity force with text \( mg \)</li>
  364. <li> the force in the rod with text \( S \)</li>
  365. <li> the air resistance force with text \( \sim |v|v \)</li>
  366. </ol>
  367. The first object, \( (x_0,y_0) \), is simply a plain text where we have
  368. to experiment with the position. The unit vectors in polar coordinates
  369. may be drawn using the Pysketcher's <code>Force</code> object since it has an
  370. arrow with a text. The first three object can then be made as follows:
  371. <p>
  372. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  373. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">x0y0 <span style="color: #666666">=</span> Text(<span style="color: #BA2121">&#39;$(x_0,y_0)$&#39;</span>, P <span style="color: #666666">+</span> point(<span style="color: #666666">-0.4</span>,<span style="color: #666666">-0.1</span>))
  374. ir <span style="color: #666666">=</span> Force(P, P <span style="color: #666666">+</span> L<span style="color: #666666">/10*</span>unit_vec(rod_vec),
  375. <span style="color: #BA2121">r&#39;$\boldsymbol{i}_r$&#39;</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">&#39;end&#39;</span>,
  376. text_spacing<span style="color: #666666">=</span>(<span style="color: #666666">0.015</span>,<span style="color: #666666">0</span>))
  377. ith <span style="color: #666666">=</span> Force(P, P <span style="color: #666666">+</span> L<span style="color: #666666">/10*</span>unit_vec((<span style="color: #666666">-</span>rod_vec[<span style="color: #666666">1</span>], rod_vec[<span style="color: #666666">0</span>])),
  378. <span style="color: #BA2121">r&#39;$\boldsymbol{i}_{\theta}$&#39;</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">&#39;end&#39;</span>,
  379. text_spacing<span style="color: #666666">=</span>(<span style="color: #666666">0.02</span>,<span style="color: #666666">0.005</span>))
  380. </pre></div>
  381. <p>
  382. Note that tweaking of the position of <code>x0y0</code> use absolute coordinates, so
  383. if <code>W</code> or <code>H</code> is changed in the beginning of the figure, the tweaked position
  384. will most likely not look good. A better solution would be to express
  385. the tweaked displacement <code>point(-0.4,-0.1)</code> in terms of <code>W</code> and <code>H</code>.
  386. The <code>text_spacing</code> values in the <code>Force</code> objects also use absolute
  387. coordinates. Very often, this is much more convenient when adjusting
  388. the objects, and global size parameters like <code>W</code> and <code>H</code> are in practice
  389. seldom changed.
  390. <p>
  391. The vertical, dashed line, the dashed rod, and the arc for \( \theta \)
  392. are made by
  393. <p>
  394. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  395. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">rod_start <span style="color: #666666">=</span> rod<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">&#39;start&#39;</span>] <span style="color: #408080; font-style: italic"># Point P</span>
  396. vertical2 <span style="color: #666666">=</span> Line(rod_start, rod_start <span style="color: #666666">+</span> point(<span style="color: #666666">0</span>,<span style="color: #666666">-</span>L<span style="color: #666666">/3</span>))
  397. set_dashed_thin_blackline(vertical2)
  398. set_dashed_thin_blackline(rod)
  399. angle2 <span style="color: #666666">=</span> Arc_wText(<span style="color: #BA2121">r&#39;$\theta$&#39;</span>, rod_start, L<span style="color: #666666">/6</span>, <span style="color: #666666">-90</span>, a,
  400. text_spacing<span style="color: #666666">=1/30.</span>)
  401. </pre></div>
  402. <p>
  403. Note how we reuse the earlier defined object <code>rod</code>.
  404. <p>
  405. The forces are constructed as shown below.
  406. <p>
  407. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  408. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">mg_force <span style="color: #666666">=</span> Force(mass_pt, mass_pt <span style="color: #666666">+</span> L<span style="color: #666666">/5*</span>point(<span style="color: #666666">0</span>,<span style="color: #666666">-1</span>),
  409. <span style="color: #BA2121">&#39;$mg$&#39;</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">&#39;end&#39;</span>)
  410. rod_force <span style="color: #666666">=</span> Force(mass_pt, mass_pt <span style="color: #666666">-</span> L<span style="color: #666666">/3*</span>unit_vec(rod_vec),
  411. <span style="color: #BA2121">&#39;$S$&#39;</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">&#39;end&#39;</span>,
  412. text_spacing<span style="color: #666666">=</span>(<span style="color: #666666">0.03</span>, <span style="color: #666666">0.01</span>))
  413. air_force <span style="color: #666666">=</span> Force(mass_pt, mass_pt <span style="color: #666666">-</span>
  414. L<span style="color: #666666">/6*</span>unit_vec((rod_vec[<span style="color: #666666">1</span>], <span style="color: #666666">-</span>rod_vec[<span style="color: #666666">0</span>])),
  415. <span style="color: #BA2121">&#39;$\sim|v|v$&#39;</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">&#39;end&#39;</span>,
  416. text_spacing<span style="color: #666666">=</span>(<span style="color: #666666">0.04</span>,<span style="color: #666666">0.005</span>))
  417. </pre></div>
  418. <p>
  419. All objects are in place, and we can compose a figure to be drawn:
  420. <p>
  421. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  422. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">body_diagram <span style="color: #666666">=</span> Composition(
  423. {<span style="color: #BA2121">&#39;mg&#39;</span>: mg_force, <span style="color: #BA2121">&#39;S&#39;</span>: rod_force, <span style="color: #BA2121">&#39;rod&#39;</span>: rod,
  424. <span style="color: #BA2121">&#39;vertical&#39;</span>: vertical2, <span style="color: #BA2121">&#39;theta&#39;</span>: angle2,
  425. <span style="color: #BA2121">&#39;body&#39;</span>: mass, <span style="color: #BA2121">&#39;m&#39;</span>: mass_symbol})
  426. body_diagram[<span style="color: #BA2121">&#39;air&#39;</span>] <span style="color: #666666">=</span> air_force
  427. body_diagram[<span style="color: #BA2121">&#39;ir&#39;</span>] <span style="color: #666666">=</span> ir
  428. body_diagram[<span style="color: #BA2121">&#39;ith&#39;</span>] <span style="color: #666666">=</span> ith
  429. body_diagram[<span style="color: #BA2121">&#39;origin&#39;</span>] <span style="color: #666666">=</span> x0y0
  430. </pre></div>
  431. <p>
  432. Here, we exemplify that we can start out with a composition as a
  433. dictionary, but (as in ordinary Python dictionaries) add new
  434. elements later when desired.
  435. <p>
  436. <!-- FIGURE: [fig-tut/pendulum1.png, width=400 frac=0.5] Sketch of a simple pendulum. <div id="sketcher:ex:pendulum:fig2"></div> -->
  437. <p>
  438. <p>
  439. <!-- navigation buttons at the bottom of the page -->
  440. <ul class="pagination">
  441. <li><a href="._pysketcher002.html">&laquo;</a></li>
  442. <li><a href="._pysketcher000.html">1</a></li>
  443. <li><a href="._pysketcher001.html">2</a></li>
  444. <li><a href="._pysketcher002.html">3</a></li>
  445. <li class="active"><a href="._pysketcher003.html">4</a></li>
  446. <li><a href="._pysketcher004.html">5</a></li>
  447. <li><a href="._pysketcher005.html">6</a></li>
  448. <li><a href="._pysketcher004.html">&raquo;</a></li>
  449. </ul>
  450. <!-- ------------------- end of main content --------------- -->
  451. </div> <!-- end container -->
  452. <!-- include javascript, jQuery *first* -->
  453. <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
  454. <script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
  455. <!-- Bootstrap footer
  456. <footer>
  457. <a href="http://..."><img width="250" align=right src="http://..."></a>
  458. </footer>
  459. -->
  460. </body>
  461. </html>