._pysketcher001.html 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  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. <style type="text/css">
  13. /* blueish style */
  14. /* Color definitions: http://www.december.com/html/spec/color0.html
  15. CSS examples: http://www.w3schools.com/css/css_examples.asp */
  16. body {
  17. margin-top: 1.0em;
  18. background-color: #ffffff;
  19. font-family: Helvetica, Arial, FreeSans, san-serif;
  20. color: #000000;
  21. }
  22. h1 { font-size: 1.8em; color: #1e36ce; }
  23. h2 { font-size: 1.6em; color: #1e36ce; }
  24. h3 { font-size: 1.4em; color: #1e36ce; }
  25. a { color: #1e36ce; text-decoration:none; }
  26. tt { font-family: "Courier New", Courier; }
  27. /* pre style removed because it will interfer with pygments */
  28. p { text-indent: 0px; }
  29. hr { border: 0; width: 80%; border-bottom: 1px solid #aaa}
  30. p.caption { width: 80%; font-style: normal; text-align: left; }
  31. hr.figure { border: 0; width: 80%; border-bottom: 1px solid #aaa}
  32. div { text-align: justify; text-justify: inter-word; }
  33. </style>
  34. </head>
  35. <!-- tocinfo
  36. {'highest level': 1,
  37. 'sections': [(' A First Glimpse of Pysketcher ', 1, None, '___sec0'),
  38. (' Basic Construction of Sketches ', 2, None, '___sec1'),
  39. (' Basic Drawing ', 3, None, '___sec2'),
  40. (' Groups of Objects ', 3, None, '___sec3'),
  41. (' Changing Line Styles and Colors ', 3, None, '___sec4'),
  42. (' The Figure Composition as an Object Hierarchy ',
  43. 3,
  44. None,
  45. '___sec5'),
  46. (' Animation: Translating the Vehicle ', 3, None, '___sec6'),
  47. (' Animation: Rolling the Wheels ',
  48. 3,
  49. 'sketcher:vehicle1:anim',
  50. 'sketcher:vehicle1:anim'),
  51. (' Basic Shapes ', 1, None, '___sec8'),
  52. (' Axis ', 2, None, '___sec9'),
  53. (' Distance with Text ', 2, None, '___sec10'),
  54. (' Rectangle ', 2, None, '___sec11'),
  55. (' Triangle ', 2, None, '___sec12'),
  56. (' Arc ', 2, None, '___sec13'),
  57. (' Spring ', 2, None, '___sec14'),
  58. (' Dashpot ', 2, None, '___sec15'),
  59. (' Wavy ', 2, None, '___sec16'),
  60. (' Stochastic curves ', 2, None, '___sec17'),
  61. (' Inner Workings of the Pysketcher Tool ',
  62. 1,
  63. None,
  64. '___sec18'),
  65. (' Example of Classes for Geometric Objects ',
  66. 2,
  67. None,
  68. '___sec19'),
  69. (' Simple Geometric Objects ', 3, None, '___sec20'),
  70. (' Class Curve ', 3, None, '___sec21'),
  71. (' Compound Geometric Objects ', 3, None, '___sec22'),
  72. (' Adding Functionality via Recursion ', 2, None, '___sec23'),
  73. (' Basic Principles of Recursion ', 3, None, '___sec24'),
  74. (' Explaining Recursion ', 3, None, '___sec25'),
  75. (' Scaling, Translating, and Rotating a Figure ',
  76. 2,
  77. 'sketcher:scaling',
  78. 'sketcher:scaling'),
  79. (' Scaling ', 3, None, '___sec27'),
  80. (' Translation ', 3, None, '___sec28'),
  81. (' Rotation ', 3, None, '___sec29')]}
  82. end of tocinfo -->
  83. <body>
  84. <script type="text/x-mathjax-config">
  85. MathJax.Hub.Config({
  86. TeX: {
  87. equationNumbers: { autoNumber: "none" },
  88. extensions: ["AMSmath.js", "AMSsymbols.js", "autobold.js", "color.js"]
  89. }
  90. });
  91. </script>
  92. <script type="text/javascript"
  93. src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
  94. </script>
  95. <a name="part0001"></a>
  96. <p>
  97. <!-- begin top navigation -->
  98. <table style="width: 100%"><tr><td>
  99. <div style="text-align: left;"><a href="._pysketcher000.html"><img src="http://hplgit.github.io/doconce/bundled/html_images/prev1.png" border=0 alt="&laquo; Previous"></a></div>
  100. </td><td>
  101. <div style="text-align: right;"><a href="._pysketcher002.html"><img src="http://hplgit.github.io/doconce/bundled/html_images/next1.png" border=0 alt="Next &raquo;"></a></div>
  102. </td></tr></table>
  103. <!-- end top navigation -->
  104. </p>
  105. <p>
  106. <!-- !split -->
  107. <p>
  108. 2DO:
  109. <ul>
  110. <li> two wheels of different radii on inclined plane coupled to
  111. correct solution</li>
  112. <li> <a href="http://inventwithpython.com/chapter17.html" target="_self">Pygame backend</a></li>
  113. </ul>
  114. <h1 id="___sec0">A First Glimpse of Pysketcher </h1>
  115. <p>
  116. Formulation of physical problems makes heavy use of <em>principal sketches</em>
  117. such as the one in Figure <a href="#sketcher:fig:inclinedplane">1</a>.
  118. This particular sketch illustrates the classical mechanics problem
  119. of a rolling wheel on an inclined plane.
  120. The figure
  121. is made up many individual elements: a rectangle
  122. filled with a pattern (the inclined plane), a hollow circle with color
  123. (the wheel), arrows with labels (the \( N \) and \( Mg \) forces, and the \( x \)
  124. axis), an angle with symbol \( \theta \), and a dashed line indicating the
  125. starting location of the wheel.
  126. <p>
  127. Drawing software and plotting programs can produce such figures quite
  128. easily in principle, but the amount of details the user needs to
  129. control with the mouse can be substantial. Software more tailored to
  130. producing sketches of this type would work with more convenient
  131. abstractions, such as circle, wall, angle, force arrow, axis, and so
  132. forth. And as soon we start <em>programming</em> to construct the figure we
  133. get a range of other powerful tools at disposal. For example, we can
  134. easily translate and rotate parts of the figure and make an animation
  135. that illustrates the physics of the problem.
  136. Programming as a superior alternative to interactive drawing is
  137. the mantra of this section.
  138. <p>
  139. <center> <!-- figure -->
  140. <hr class="figure">
  141. <center><p class="caption">Figure 1: Sketch of a physics problem. <div id="sketcher:fig:inclinedplane"></div> </p></center>
  142. <p><img src="fig-tut/wheel_on_inclined_plane.png" align="bottom" width=400></p>
  143. </center>
  144. <h2 id="___sec1">Basic Construction of Sketches </h2>
  145. <p>
  146. Before attacking real-life sketches as in Figure <a href="#sketcher:fig:inclinedplane">1</a>
  147. we focus on the significantly simpler drawing shown
  148. in Figure <a href="#sketcher:fig:vehicle0">2</a>. This toy sketch consists of
  149. several elements: two circles, two rectangles, and a &quot;ground&quot; element.
  150. <p>
  151. <center> <!-- figure -->
  152. <hr class="figure">
  153. <center><p class="caption">Figure 2: Sketch of a simple figure. <div id="sketcher:fig:vehicle0"></div> </p></center>
  154. <p><img src="fig-tut/vehicle0_dim.png" align="bottom" width=600></p>
  155. </center>
  156. <p>
  157. When the sketch is defined in terms of computer code, it is natural to
  158. parameterize geometric features, such as the radius of the wheel (\( R \)),
  159. the center point of the left wheel (\( w_1 \)), as well as the height (\( H \)) and
  160. length (\( L \)) of the main part. The simple vehicle in
  161. Figure <a href="#sketcher:fig:vehicle0">2</a> is quickly drawn in almost any interactive
  162. tool. However, if we want to change the radius of the wheels, you need a
  163. sophisticated drawing tool to avoid redrawing the whole figure, while
  164. in computer code this is a matter of changing the \( R \) parameter and
  165. rerunning the program.
  166. For example, Figure <a href="#sketcher:fig:vehicle0b">3</a> shows
  167. a variation of the drawing in
  168. Figure <a href="#sketcher:fig:vehicle0">2</a> obtained by just setting
  169. \( R=0.5 \), \( L=5 \), \( H=2 \), and \( R=2 \). Being able
  170. to quickly change geometric sizes is key to many problem settings in
  171. physics and engineering, but then a program must define the geometry.
  172. <p>
  173. <center> <!-- figure -->
  174. <hr class="figure">
  175. <center><p class="caption">Figure 3: Redrawing a figure with other geometric parameters. <div id="sketcher:fig:vehicle0b"></div> </p></center>
  176. <p><img src="fig-tut/vehicle_v2.png" align="bottom" width=500></p>
  177. </center>
  178. <h3 id="___sec2">Basic Drawing </h3>
  179. <p>
  180. A typical program creating these five elements is shown next.
  181. After importing the <code>pysketcher</code> package, the first task is always to
  182. define a coordinate system:
  183. <p>
  184. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  185. <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>
  186. drawing_tool<span style="color: #666666">.</span>set_coordinate_system(
  187. xmin<span style="color: #666666">=0</span>, xmax<span style="color: #666666">=10</span>, ymin<span style="color: #666666">=-1</span>, ymax<span style="color: #666666">=8</span>)
  188. </pre></div>
  189. <p>
  190. Instead of working with lengths expressed by specific numbers it is
  191. highly recommended to use variables to parameterize lengths as
  192. this makes it easier to change dimensions later.
  193. Here we introduce some key lengths for the radius of the wheels,
  194. distance between the wheels, etc.:
  195. <p>
  196. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  197. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">R <span style="color: #666666">=</span> <span style="color: #666666">1</span> <span style="color: #408080; font-style: italic"># radius of wheel</span>
  198. L <span style="color: #666666">=</span> <span style="color: #666666">4</span> <span style="color: #408080; font-style: italic"># distance between wheels</span>
  199. H <span style="color: #666666">=</span> <span style="color: #666666">2</span> <span style="color: #408080; font-style: italic"># height of vehicle body</span>
  200. w_1 <span style="color: #666666">=</span> <span style="color: #666666">5</span> <span style="color: #408080; font-style: italic"># position of front wheel</span>
  201. drawing_tool<span style="color: #666666">.</span>set_coordinate_system(xmin<span style="color: #666666">=0</span>, xmax<span style="color: #666666">=</span>w_1 <span style="color: #666666">+</span> <span style="color: #666666">2*</span>L <span style="color: #666666">+</span> <span style="color: #666666">3*</span>R,
  202. ymin<span style="color: #666666">=-1</span>, ymax<span style="color: #666666">=2*</span>R <span style="color: #666666">+</span> <span style="color: #666666">3*</span>H)
  203. </pre></div>
  204. <p>
  205. With the drawing area in place we can make the first <code>Circle</code> object
  206. in an intuitive fashion:
  207. <p>
  208. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  209. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">wheel1 <span style="color: #666666">=</span> Circle(center<span style="color: #666666">=</span>(w_1, R), radius<span style="color: #666666">=</span>R)
  210. </pre></div>
  211. <p>
  212. to change dimensions later.
  213. <p>
  214. To translate the geometric information about the <code>wheel1</code> object to
  215. instructions for the plotting engine (in this case Matplotlib), one calls the
  216. <code>wheel1.draw()</code>. To display all drawn objects, one issues
  217. <code>drawing_tool.display()</code>. The typical steps are hence:
  218. <p>
  219. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  220. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">wheel1 <span style="color: #666666">=</span> Circle(center<span style="color: #666666">=</span>(w_1, R), radius<span style="color: #666666">=</span>R)
  221. wheel1<span style="color: #666666">.</span>draw()
  222. <span style="color: #408080; font-style: italic"># Define other objects and call their draw() methods</span>
  223. drawing_tool<span style="color: #666666">.</span>display()
  224. drawing_tool<span style="color: #666666">.</span>savefig(<span style="color: #BA2121">&#39;tmp.png&#39;</span>) <span style="color: #408080; font-style: italic"># store picture</span>
  225. </pre></div>
  226. <p>
  227. The next wheel can be made by taking a copy of <code>wheel1</code> and
  228. translating the object to the right according to a
  229. displacement vector \( (L,0) \):
  230. <p>
  231. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  232. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">wheel2 <span style="color: #666666">=</span> wheel1<span style="color: #666666">.</span>copy()
  233. wheel2<span style="color: #666666">.</span>translate((L,<span style="color: #666666">0</span>))
  234. </pre></div>
  235. <p>
  236. The two rectangles are also made in an intuitive way:
  237. <p>
  238. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  239. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">under <span style="color: #666666">=</span> Rectangle(lower_left_corner<span style="color: #666666">=</span>(w_1<span style="color: #666666">-2*</span>R, <span style="color: #666666">2*</span>R),
  240. width<span style="color: #666666">=2*</span>R <span style="color: #666666">+</span> L <span style="color: #666666">+</span> <span style="color: #666666">2*</span>R, height<span style="color: #666666">=</span>H)
  241. over <span style="color: #666666">=</span> Rectangle(lower_left_corner<span style="color: #666666">=</span>(w_1, <span style="color: #666666">2*</span>R <span style="color: #666666">+</span> H),
  242. width<span style="color: #666666">=2.5*</span>R, height<span style="color: #666666">=1.25*</span>H)
  243. </pre></div>
  244. <h3 id="___sec3">Groups of Objects </h3>
  245. <p>
  246. Instead of calling the <code>draw</code> method of every object, we can
  247. group objects and call <code>draw</code>, or perform other operations, for
  248. the whole group. For example, we may collect the two wheels
  249. in a <code>wheels</code> group and the <code>over</code> and <code>under</code> rectangles
  250. in a <code>body</code> group. The whole vehicle is a composition
  251. of its <code>wheels</code> and <code>body</code> groups. The code goes like
  252. <p>
  253. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  254. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">wheels <span style="color: #666666">=</span> Composition({<span style="color: #BA2121">&#39;wheel1&#39;</span>: wheel1, <span style="color: #BA2121">&#39;wheel2&#39;</span>: wheel2})
  255. body <span style="color: #666666">=</span> Composition({<span style="color: #BA2121">&#39;under&#39;</span>: under, <span style="color: #BA2121">&#39;over&#39;</span>: over})
  256. vehicle <span style="color: #666666">=</span> Composition({<span style="color: #BA2121">&#39;wheels&#39;</span>: wheels, <span style="color: #BA2121">&#39;body&#39;</span>: body})
  257. </pre></div>
  258. <p>
  259. The ground is illustrated by an object of type <code>Wall</code>,
  260. mostly used to indicate walls in sketches of mechanical systems.
  261. A <code>Wall</code> takes the <code>x</code> and <code>y</code> coordinates of some curve,
  262. and a <code>thickness</code> parameter, and creates a thick curve filled
  263. with a simple pattern. In this case the curve is just a flat
  264. line so the construction is made of two points on the
  265. ground line (\( (w_1-L,0) \) and \( (w_1+3L,0) \)):
  266. <p>
  267. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  268. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">ground <span style="color: #666666">=</span> Wall(x<span style="color: #666666">=</span>[w_1 <span style="color: #666666">-</span> L, w_1 <span style="color: #666666">+</span> <span style="color: #666666">3*</span>L], y<span style="color: #666666">=</span>[<span style="color: #666666">0</span>, <span style="color: #666666">0</span>], thickness<span style="color: #666666">=-0.3*</span>R)
  269. </pre></div>
  270. <p>
  271. The negative thickness makes the pattern-filled rectangle appear below
  272. the defined line, otherwise it appears above.
  273. <p>
  274. We may now collect all the objects in a &quot;top&quot; object that contains
  275. the whole figure:
  276. <p>
  277. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  278. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">fig <span style="color: #666666">=</span> Composition({<span style="color: #BA2121">&#39;vehicle&#39;</span>: vehicle, <span style="color: #BA2121">&#39;ground&#39;</span>: ground})
  279. fig<span style="color: #666666">.</span>draw() <span style="color: #408080; font-style: italic"># send all figures to plotting backend</span>
  280. drawing_tool<span style="color: #666666">.</span>display()
  281. drawing_tool<span style="color: #666666">.</span>savefig(<span style="color: #BA2121">&#39;tmp.png&#39;</span>)
  282. </pre></div>
  283. <p>
  284. The <code>fig.draw()</code> call will visit
  285. all subgroups, their subgroups,
  286. and so forth in the hierarchical tree structure of
  287. figure elements,
  288. and call <code>draw</code> for every object.
  289. <h3 id="___sec4">Changing Line Styles and Colors </h3>
  290. <p>
  291. Controlling the line style, line color, and line width is
  292. fundamental when designing figures. The <code>pysketcher</code>
  293. package allows the user to control such properties in
  294. single objects, but also set global properties that are
  295. used if the object has no particular specification of
  296. the properties. Setting the global properties are done like
  297. <p>
  298. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  299. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">drawing_tool<span style="color: #666666">.</span>set_linestyle(<span style="color: #BA2121">&#39;dashed&#39;</span>)
  300. drawing_tool<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;black&#39;</span>)
  301. drawing_tool<span style="color: #666666">.</span>set_linewidth(<span style="color: #666666">4</span>)
  302. </pre></div>
  303. <p>
  304. At the object level the properties are specified in a similar
  305. way:
  306. <p>
  307. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  308. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">wheels<span style="color: #666666">.</span>set_linestyle(<span style="color: #BA2121">&#39;solid&#39;</span>)
  309. wheels<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;red&#39;</span>)
  310. </pre></div>
  311. <p>
  312. and so on.
  313. <p>
  314. Geometric figures can be specified as <em>filled</em>, either with a color or with a
  315. special visual pattern:
  316. <p>
  317. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  318. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #408080; font-style: italic"># Set filling of all curves</span>
  319. drawing_tool<span style="color: #666666">.</span>set_filled_curves(color<span style="color: #666666">=</span><span style="color: #BA2121">&#39;blue&#39;</span>, pattern<span style="color: #666666">=</span><span style="color: #BA2121">&#39;/&#39;</span>)
  320. <span style="color: #408080; font-style: italic"># Turn off filling of all curves</span>
  321. drawing_tool<span style="color: #666666">.</span>set_filled_curves(<span style="color: #008000">False</span>)
  322. <span style="color: #408080; font-style: italic"># Fill the wheel with red color</span>
  323. wheel1<span style="color: #666666">.</span>set_filled_curves(<span style="color: #BA2121">&#39;red&#39;</span>)
  324. </pre></div>
  325. <p>
  326. <!-- <a href="http://packages.python.org/ete2/" target="_self"><tt>http://packages.python.org/ete2/</tt></a> for visualizing tree structures! -->
  327. <h3 id="___sec5">The Figure Composition as an Object Hierarchy </h3>
  328. <p>
  329. The composition of objects making up the figure
  330. is hierarchical, similar to a family, where
  331. each object has a parent and a number of children. Do a
  332. <code>print fig</code> to display the relations:
  333. <p>
  334. <!-- code=text (!bc dat) typeset with pygments style "default" -->
  335. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">ground
  336. wall
  337. vehicle
  338. body
  339. over
  340. rectangle
  341. under
  342. rectangle
  343. wheels
  344. wheel1
  345. arc
  346. wheel2
  347. arc
  348. </pre></div>
  349. <p>
  350. The indentation reflects how deep down in the hierarchy (family)
  351. we are.
  352. This output is to be interpreted as follows:
  353. <ul>
  354. <li> <code>fig</code> contains two objects, <code>ground</code> and <code>vehicle</code></li>
  355. <li> <code>ground</code> contains an object <code>wall</code></li>
  356. <li> <code>vehicle</code> contains two objects, <code>body</code> and <code>wheels</code></li>
  357. <li> <code>body</code> contains two objects, <code>over</code> and <code>under</code></li>
  358. <li> <code>wheels</code> contains two objects, <code>wheel1</code> and <code>wheel2</code></li>
  359. </ul>
  360. In this listing there are also objects not defined by the
  361. programmer: <code>rectangle</code> and <code>arc</code>. These are of type <code>Curve</code>
  362. and automatically generated by the classes <code>Rectangle</code> and <code>Circle</code>.
  363. <p>
  364. More detailed information can be printed by
  365. <p>
  366. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  367. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">print</span> fig<span style="color: #666666">.</span>show_hierarchy(<span style="color: #BA2121">&#39;std&#39;</span>)
  368. </pre></div>
  369. <p>
  370. yielding the output
  371. <p>
  372. <!-- code=text (!bc dat) typeset with pygments style "default" -->
  373. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">ground (Wall):
  374. wall (Curve): 4 coords fillcolor=&#39;white&#39; fillpattern=&#39;/&#39;
  375. vehicle (Composition):
  376. body (Composition):
  377. over (Rectangle):
  378. rectangle (Curve): 5 coords
  379. under (Rectangle):
  380. rectangle (Curve): 5 coords
  381. wheels (Composition):
  382. wheel1 (Circle):
  383. arc (Curve): 181 coords
  384. wheel2 (Circle):
  385. arc (Curve): 181 coords
  386. </pre></div>
  387. <p>
  388. Here we can see the class type for each figure object, how many
  389. coordinates that are involved in basic figures (<code>Curve</code> objects), and
  390. special settings of the basic figure (fillcolor, line types, etc.).
  391. For example, <code>wheel2</code> is a <code>Circle</code> object consisting of an <code>arc</code>,
  392. which is a <code>Curve</code> object consisting of 181 coordinates (the
  393. points needed to draw a smooth circle). The <code>Curve</code> objects are the
  394. only objects that really holds specific coordinates to be drawn.
  395. The other object types are just compositions used to group
  396. parts of the complete figure.
  397. <p>
  398. One can also get a graphical overview of the hierarchy of figure objects
  399. that build up a particular figure <code>fig</code>.
  400. Just call <code>fig.graphviz_dot('fig')</code> to produce a file <code>fig.dot</code> in
  401. the <em>dot format</em>. This file contains relations between parent and
  402. child objects in the figure and can be turned into an image,
  403. as in Figure <a href="#sketcher:fig:vehicle0:hier1">4</a>, by
  404. running the <code>dot</code> program:
  405. <p>
  406. <!-- code=text (!bc sys) typeset with pygments style "default" -->
  407. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">Terminal&gt; dot -Tpng -o fig.png fig.dot
  408. </pre></div>
  409. <p>
  410. <center> <!-- figure -->
  411. <hr class="figure">
  412. <center><p class="caption">Figure 4: Hierarchical relation between figure objects. <div id="sketcher:fig:vehicle0:hier1"></div> </p></center>
  413. <p><img src="fig-tut/vehicle0_hier1.png" align="bottom" width=500></p>
  414. </center>
  415. <p>
  416. The call <code>fig.graphviz_dot('fig', classname=True)</code> makes a <code>fig.dot</code> file
  417. where the class type of each object is also visible, see
  418. Figure <a href="#sketcher:fig:vehicle0:hier2">5</a>. The ability to write out the
  419. object hierarchy or view it graphically can be of great help when
  420. working with complex figures that involve layers of subfigures.
  421. <p>
  422. <center> <!-- figure -->
  423. <hr class="figure">
  424. <center><p class="caption">Figure 5: Hierarchical relation between figure objects, including their class names. <div id="sketcher:fig:vehicle0:hier2"></div> </p></center>
  425. <p><img src="fig-tut/Vehicle0_hier2.png" align="bottom" width=500></p>
  426. </center>
  427. <p>
  428. Any of the objects can in the program be reached through their names, e.g.,
  429. <p>
  430. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  431. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>]
  432. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>]
  433. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>][<span style="color: #BA2121">&#39;wheel2&#39;</span>]
  434. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>][<span style="color: #BA2121">&#39;wheel2&#39;</span>][<span style="color: #BA2121">&#39;arc&#39;</span>]
  435. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>][<span style="color: #BA2121">&#39;wheel2&#39;</span>][<span style="color: #BA2121">&#39;arc&#39;</span>]<span style="color: #666666">.</span>x <span style="color: #408080; font-style: italic"># x coords</span>
  436. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>][<span style="color: #BA2121">&#39;wheel2&#39;</span>][<span style="color: #BA2121">&#39;arc&#39;</span>]<span style="color: #666666">.</span>y <span style="color: #408080; font-style: italic"># y coords</span>
  437. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>][<span style="color: #BA2121">&#39;wheel2&#39;</span>][<span style="color: #BA2121">&#39;arc&#39;</span>]<span style="color: #666666">.</span>linestyle
  438. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>][<span style="color: #BA2121">&#39;wheel2&#39;</span>][<span style="color: #BA2121">&#39;arc&#39;</span>]<span style="color: #666666">.</span>linetype
  439. </pre></div>
  440. <p>
  441. Grabbing a part of the figure this way is handy for
  442. changing properties of that part, for example, colors, line styles
  443. (see Figure <a href="#sketcher:fig:vehicle0:v2">6</a>):
  444. <p>
  445. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  446. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>]<span style="color: #666666">.</span>set_filled_curves(<span style="color: #BA2121">&#39;blue&#39;</span>)
  447. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>]<span style="color: #666666">.</span>set_linewidth(<span style="color: #666666">6</span>)
  448. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>]<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;black&#39;</span>)
  449. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;body&#39;</span>][<span style="color: #BA2121">&#39;under&#39;</span>]<span style="color: #666666">.</span>set_filled_curves(<span style="color: #BA2121">&#39;red&#39;</span>)
  450. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;body&#39;</span>][<span style="color: #BA2121">&#39;over&#39;</span>]<span style="color: #666666">.</span>set_filled_curves(pattern<span style="color: #666666">=</span><span style="color: #BA2121">&#39;/&#39;</span>)
  451. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;body&#39;</span>][<span style="color: #BA2121">&#39;over&#39;</span>]<span style="color: #666666">.</span>set_linewidth(<span style="color: #666666">14</span>)
  452. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;body&#39;</span>][<span style="color: #BA2121">&#39;over&#39;</span>][<span style="color: #BA2121">&#39;rectangle&#39;</span>]<span style="color: #666666">.</span>linewidth <span style="color: #666666">=</span> <span style="color: #666666">4</span>
  453. </pre></div>
  454. <p>
  455. The last line accesses the <code>Curve</code> object directly, while the line above,
  456. accesses the <code>Rectangle</code> object, which will then set the linewidth of
  457. its <code>Curve</code> object, and other objects if it had any.
  458. The result of the actions above is shown in Figure <a href="#sketcher:fig:vehicle0:v2">6</a>.
  459. <p>
  460. <center> <!-- figure -->
  461. <hr class="figure">
  462. <center><p class="caption">Figure 6: Left: Basic line-based drawing. Right: Thicker lines and filled parts. <div id="sketcher:fig:vehicle0:v2"></div> </p></center>
  463. <p><img src="fig-tut/vehicle0.png" align="bottom" width=700></p>
  464. </center>
  465. <p>
  466. We can also change position of parts of the figure and thereby make
  467. animations, as shown next.
  468. <h3 id="___sec6">Animation: Translating the Vehicle </h3>
  469. <p>
  470. Can we make our little vehicle roll? A first attempt will be to
  471. fake rolling by just displacing all parts of the vehicle.
  472. The relevant parts constitute the <code>fig['vehicle']</code> object.
  473. This part of the figure can be translated, rotated, and scaled.
  474. A translation along the ground means a translation in \( x \) direction,
  475. say a length \( L \) to the right:
  476. <p>
  477. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  478. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>]<span style="color: #666666">.</span>translate((L,<span style="color: #666666">0</span>))
  479. </pre></div>
  480. <p>
  481. You need to erase, draw, and display to see the movement:
  482. <p>
  483. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  484. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">drawing_tool<span style="color: #666666">.</span>erase()
  485. fig<span style="color: #666666">.</span>draw()
  486. drawing_tool<span style="color: #666666">.</span>display()
  487. </pre></div>
  488. <p>
  489. Without erasing, the old drawing of the vehicle will remain in
  490. the figure so you get two vehicles. Without <code>fig.draw()</code> the
  491. new coordinates of the vehicle will not be communicated to
  492. the drawing tool, and without calling display the updated
  493. drawing will not be visible.
  494. <p>
  495. A figure that moves in time is conveniently realized by the
  496. function <code>animate</code>:
  497. <p>
  498. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  499. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">animate(fig, tp, action)
  500. </pre></div>
  501. <p>
  502. Here, <code>fig</code> is the entire figure, <code>tp</code> is an array of
  503. time points, and <code>action</code> is a user-specified function that changes
  504. <code>fig</code> at a specific time point. Typically, <code>action</code> will move
  505. parts of <code>fig</code>.
  506. <p>
  507. In the present case we can define the movement through a velocity
  508. function <code>v(t)</code> and displace the figure <code>v(t)*dt</code> for small time
  509. intervals <code>dt</code>. A possible velocity function is
  510. <p>
  511. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  512. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">v</span>(t):
  513. <span style="color: #008000; font-weight: bold">return</span> <span style="color: #666666">-8*</span>R<span style="color: #666666">*</span>t<span style="color: #666666">*</span>(<span style="color: #666666">1</span> <span style="color: #666666">-</span> t<span style="color: #666666">/</span>(<span style="color: #666666">2*</span>R))
  514. </pre></div>
  515. <p>
  516. Our action function for horizontal displacements <code>v(t)*dt</code> becomes
  517. <p>
  518. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  519. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">move</span>(t, fig):
  520. x_displacement <span style="color: #666666">=</span> dt<span style="color: #666666">*</span>v(t)
  521. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>]<span style="color: #666666">.</span>translate((x_displacement, <span style="color: #666666">0</span>))
  522. </pre></div>
  523. <p>
  524. Since our velocity is negative for \( t\in [0,2R] \) the displacement is
  525. to the left.
  526. <p>
  527. The <code>animate</code> function will for each time point <code>t</code> in <code>tp</code> erase
  528. the drawing, call <code>action(t, fig)</code>, and show the new figure by
  529. <code>fig.draw()</code> and <code>drawing_tool.display()</code>.
  530. Here we choose a resolution of the animation corresponding to
  531. 25 time points in the time interval \( [0,2R] \):
  532. <p>
  533. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  534. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">numpy</span>
  535. tp <span style="color: #666666">=</span> numpy<span style="color: #666666">.</span>linspace(<span style="color: #666666">0</span>, <span style="color: #666666">2*</span>R, <span style="color: #666666">25</span>)
  536. dt <span style="color: #666666">=</span> tp[<span style="color: #666666">1</span>] <span style="color: #666666">-</span> tp[<span style="color: #666666">0</span>] <span style="color: #408080; font-style: italic"># time step</span>
  537. animate(fig, tp, move, pause_per_frame<span style="color: #666666">=0.2</span>)
  538. </pre></div>
  539. <p>
  540. The <code>pause_per_frame</code> adds a pause, here 0.2 seconds, between
  541. each frame in the animation.
  542. <p>
  543. We can also ask <code>animate</code> to store each frame in a file:
  544. <p>
  545. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  546. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">files <span style="color: #666666">=</span> animate(fig, tp, move_vehicle, moviefiles<span style="color: #666666">=</span><span style="color: #008000">True</span>,
  547. pause_per_frame<span style="color: #666666">=0.2</span>)
  548. </pre></div>
  549. <p>
  550. The <code>files</code> variable, here <code>'tmp_frame_%04d.png'</code>,
  551. is the printf-specification used to generate the individual
  552. plot files. We can use this specification to make a video
  553. file via <code>ffmpeg</code> (or <code>avconv</code> on Debian-based Linux systems such
  554. as Ubuntu). Videos in the Flash and WebM formats can be created
  555. by
  556. <p>
  557. <!-- code=text (!bc sys) typeset with pygments style "default" -->
  558. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">Terminal&gt; ffmpeg -r 12 -i tmp_frame_%04d.png -vcodec flv mov.flv
  559. Terminal&gt; ffmpeg -r 12 -i tmp_frame_%04d.png -vcodec libvpx mov.webm
  560. </pre></div>
  561. <p>
  562. An animated GIF movie can also be made using the <code>convert</code> program
  563. from the ImageMagick software suite:
  564. <p>
  565. <!-- code=text (!bc sys) typeset with pygments style "default" -->
  566. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">Terminal&gt; convert -delay 20 tmp_frame*.png mov.gif
  567. Terminal&gt; animate mov.gif # play movie
  568. </pre></div>
  569. <p>
  570. The delay between frames, in units of 1/100 s,
  571. governs the speed of the movie.
  572. To play the animated GIF file in a web page, simply insert
  573. <code>&lt;img src=&quot;mov.gif&quot;&gt;</code> in the HTML code.
  574. <p>
  575. The individual PNG frames can be directly played in a web
  576. browser by running
  577. <p>
  578. <!-- code=text (!bc sys) typeset with pygments style "default" -->
  579. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">Terminal&gt; scitools movie output_file=mov.html fps=5 tmp_frame*
  580. </pre></div>
  581. <p>
  582. or calling
  583. <p>
  584. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  585. <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">scitools.std</span> <span style="color: #008000; font-weight: bold">import</span> movie
  586. movie(files, encoder<span style="color: #666666">=</span><span style="color: #BA2121">&#39;html&#39;</span>, output_file<span style="color: #666666">=</span><span style="color: #BA2121">&#39;mov.html&#39;</span>)
  587. </pre></div>
  588. <p>
  589. in Python. Load the resulting file <code>mov.html</code> into a web browser
  590. to play the movie.
  591. <p>
  592. Try to run <a href="http://tinyurl.com/ot733jn/vehicle0.py" target="_self"><tt>vehicle0.py</tt></a> and
  593. then load <code>mov.html</code> into a browser, or play one of the <code>mov.*</code>
  594. video files. Alternatively, you can view a ready-made <a href="http://tinyurl.com/oou9lp7/mov-tut/vehicle0.html" target="_self">movie</a>.
  595. <h3 id="sketcher:vehicle1:anim">Animation: Rolling the Wheels</h3>
  596. <p>
  597. It is time to show rolling wheels. To this end, we add spokes to the
  598. wheels, formed by two crossing lines, see Figure <a href="#sketcher:fig:vehicle1">7</a>.
  599. The construction of the wheels will now involve a circle and two lines:
  600. <p>
  601. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  602. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">wheel1 <span style="color: #666666">=</span> Composition({
  603. <span style="color: #BA2121">&#39;wheel&#39;</span>: Circle(center<span style="color: #666666">=</span>(w_1, R), radius<span style="color: #666666">=</span>R),
  604. <span style="color: #BA2121">&#39;cross&#39;</span>: Composition({<span style="color: #BA2121">&#39;cross1&#39;</span>: Line((w_1,<span style="color: #666666">0</span>), (w_1,<span style="color: #666666">2*</span>R)),
  605. <span style="color: #BA2121">&#39;cross2&#39;</span>: Line((w_1<span style="color: #666666">-</span>R,R), (w_1<span style="color: #666666">+</span>R,R))})})
  606. wheel2 <span style="color: #666666">=</span> wheel1<span style="color: #666666">.</span>copy()
  607. wheel2<span style="color: #666666">.</span>translate((L,<span style="color: #666666">0</span>))
  608. </pre></div>
  609. <p>
  610. Observe that <code>wheel1.copy()</code> copies all the objects that make
  611. up the first wheel, and <code>wheel2.translate</code> translates all
  612. the copied objects.
  613. <p>
  614. <center> <!-- figure -->
  615. <hr class="figure">
  616. <center><p class="caption">Figure 7: Wheels with spokes to illustrate rolling. <div id="sketcher:fig:vehicle1"></div> </p></center>
  617. <p><img src="fig-tut/vehicle1.png" align="bottom" width=400></p>
  618. </center>
  619. <p>
  620. The <code>move</code> function now needs to displace all the objects in the
  621. entire vehicle and also rotate the <code>cross1</code> and <code>cross2</code>
  622. objects in both wheels.
  623. The rotation angle follows from the fact that the arc length
  624. of a rolling wheel equals the displacement of the center of
  625. the wheel, leading to a rotation angle
  626. <p>
  627. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  628. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">angle <span style="color: #666666">=</span> <span style="color: #666666">-</span> x_displacement<span style="color: #666666">/</span>R
  629. </pre></div>
  630. <p>
  631. With <code>w_1</code> tracking the \( x \) coordinate of the center
  632. of the front wheel, we can rotate that wheel by
  633. <p>
  634. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  635. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">w1 <span style="color: #666666">=</span> fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>][<span style="color: #BA2121">&#39;wheel1&#39;</span>]
  636. <span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">math</span> <span style="color: #008000; font-weight: bold">import</span> degrees
  637. w1<span style="color: #666666">.</span>rotate(degrees(angle), center<span style="color: #666666">=</span>(w_1, R))
  638. </pre></div>
  639. <p>
  640. The <code>rotate</code> function takes two parameters: the rotation angle
  641. (in degrees) and the center point of the rotation, which is the
  642. center of the wheel in this case. The other wheel is rotated by
  643. <p>
  644. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  645. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">w2 <span style="color: #666666">=</span> fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>][<span style="color: #BA2121">&#39;wheel2&#39;</span>]
  646. w2<span style="color: #666666">.</span>rotate(degrees(angle), center<span style="color: #666666">=</span>(w_1 <span style="color: #666666">+</span> L, R))
  647. </pre></div>
  648. <p>
  649. That is, the angle is the same, but the rotation point is different.
  650. The update of the center point is done by <code>w_1 += x_displacement</code>.
  651. The complete <code>move</code> function with translation of the entire
  652. vehicle and rotation of the wheels then becomes
  653. <p>
  654. <!-- code=python (!bc pycod) typeset with pygments style "default" -->
  655. <div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">w_1 <span style="color: #666666">=</span> w_1 <span style="color: #666666">+</span> L <span style="color: #408080; font-style: italic"># start position</span>
  656. <span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">move</span>(t, fig):
  657. x_displacement <span style="color: #666666">=</span> dt<span style="color: #666666">*</span>v(t)
  658. fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>]<span style="color: #666666">.</span>translate((x_displacement, <span style="color: #666666">0</span>))
  659. <span style="color: #408080; font-style: italic"># Rotate wheels</span>
  660. <span style="color: #008000; font-weight: bold">global</span> w_1
  661. w_1 <span style="color: #666666">+=</span> x_displacement
  662. <span style="color: #408080; font-style: italic"># R*angle = -x_displacement</span>
  663. angle <span style="color: #666666">=</span> <span style="color: #666666">-</span> x_displacement<span style="color: #666666">/</span>R
  664. w1 <span style="color: #666666">=</span> fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>][<span style="color: #BA2121">&#39;wheel1&#39;</span>]
  665. w1<span style="color: #666666">.</span>rotate(degrees(angle), center<span style="color: #666666">=</span>(w_1, R))
  666. w2 <span style="color: #666666">=</span> fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</span>][<span style="color: #BA2121">&#39;wheel2&#39;</span>]
  667. w2<span style="color: #666666">.</span>rotate(degrees(angle), center<span style="color: #666666">=</span>(w_1 <span style="color: #666666">+</span> L, R))
  668. </pre></div>
  669. <p>
  670. The complete example is found in the file
  671. <a href="http://tinyurl.com/ot733jn/vehicle1.py" target="_self"><tt>vehicle1.py</tt></a>. You may run this file or watch a <a href="http://tinyurl.com/oou9lp7/mov-tut/vehicle1.html" target="_self">ready-made movie</a>.
  672. <p>
  673. The advantages with making figures this way, through programming
  674. rather than using interactive drawing programs, are numerous. For
  675. example, the objects are parameterized by variables so that various
  676. dimensions can easily be changed. Subparts of the figure, possible
  677. involving a lot of figure objects, can change color, linetype, filling
  678. or other properties through a <em>single</em> function call. Subparts of the
  679. figure can be rotated, translated, or scaled. Subparts of the figure
  680. can also be copied and moved to other parts of the drawing
  681. area. However, the single most important feature is probably the
  682. ability to make animations governed by mathematical formulas or data
  683. coming from physics simulations of the problem, as shown in the example above.
  684. <p>
  685. <p>
  686. <!-- begin bottom navigation -->
  687. <table style="width: 100%"><tr><td>
  688. <div style="text-align: left;"><a href="._pysketcher000.html"><img src="http://hplgit.github.io/doconce/bundled/html_images/prev1.png" border=0 alt="&laquo; Previous"></a></div>
  689. </td><td>
  690. <div style="text-align: right;"><a href="._pysketcher002.html"><img src="http://hplgit.github.io/doconce/bundled/html_images/next1.png" border=0 alt="Next &raquo;"></a></div>
  691. </td></tr></table>
  692. <!-- end bottom navigation -->
  693. </p>
  694. <!-- ------------------- end of main content --------------- -->
  695. </body>
  696. </html>