Hans Petter Langtangen 10 years ago
parent
commit
fb451dd0ef
39 changed files with 3048 additions and 57 deletions
  1. 32 2
      README.do.txt
  2. 36 2
      README.md
  3. 197 0
      doc/pub/tutorial/._pysketcher000.html
  4. 813 0
      doc/pub/tutorial/._pysketcher001.html
  5. 523 0
      doc/pub/tutorial/._pysketcher002.html
  6. 896 0
      doc/pub/tutorial/._pysketcher003.html
  7. 8 8
      doc/pub/tutorial/html/genindex.html
  8. 8 8
      doc/pub/tutorial/html/index.html
  9. BIN
      doc/pub/tutorial/html/objects.inv
  10. 8 8
      doc/pub/tutorial/html/search.html
  11. 1 1
      doc/pub/tutorial/html/searchindex.js
  12. 197 0
      doc/pub/tutorial/pysketcher.html
  13. BIN
      doc/pub/tutorial/pysketcher.pdf
  14. 21 0
      doc/src/tut/basics.do.txt
  15. 43 3
      doc/src/tut/classes.do.txt
  16. BIN
      doc/src/tut/fig-tut/vehicle_v1.pdf
  17. BIN
      doc/src/tut/fig-tut/vehicle_v1.png
  18. BIN
      doc/src/tut/fig-tut/vehicle_v2.pdf
  19. BIN
      doc/src/tut/fig-tut/vehicle_v2.png
  20. BIN
      doc/src/tut/fig-tut/vehicle_v23.pdf
  21. BIN
      doc/src/tut/fig-tut/vehicle_v23.png
  22. BIN
      doc/src/tut/fig-tut/vehicle_v3.pdf
  23. BIN
      doc/src/tut/fig-tut/vehicle_v3.png
  24. 3 0
      doc/src/tut/main_sketcher.do.txt
  25. 19 13
      doc/src/tut/make.sh
  26. 10 0
      doc/src/tut/src-tut/README.txt
  27. 42 0
      doc/src/tut/src-tut/vehicle0_scaling.py
  28. BIN
      examples/FE_comic_strip.pdf
  29. BIN
      examples/FE_comic_strip.png
  30. BIN
      examples/FE_noncomic_strip.pdf
  31. BIN
      examples/FE_noncomic_strip.png
  32. 88 0
      examples/ForwardEuler.py
  33. 11 11
      examples/beam2.py
  34. 87 0
      examples/integral.py
  35. BIN
      examples/integral_comic_strip.pdf
  36. BIN
      examples/integral_comic_strip.png
  37. BIN
      examples/integral_noncomic_strip.pdf
  38. BIN
      examples/integral_noncomic_strip.png
  39. 5 1
      pysketcher/MatplotlibDraw.py

+ 32 - 2
README.do.txt

@@ -1,8 +1,38 @@
-Python-based drawing tool for making sketches of mechanics problems.
+======= Pysketcher =======
+
+Tool for defining sketches of physics problems in terms of Python code.
+
+===== Purpose =====
+
+Pysketcher can typically be used to draw figures like
+
+FIGURE: [doc/src/tut/fig-tut/wheel_on_inclined_plane, width=600 frac=0.6]
+
+Such figures can easily be *interactively* made using a lot of drawing programs.
+A Pysketcher figure, however, is defined in terms of computer code. This gives
+a great advantage: geometric features can be parameterized in term
+of variables, as here:
+
+FIGURE: [doc/src/tut/fig-tut/vehicle0_dim, width=600 frac=0.6]
+
+One can then quickly change parameters, here to
+`R=0.5; L=5; H=2` and `R=2; L=7; H=1`, and get new figures that would be
+tedious to draw manually in an interactive tool.
+
+FIGURE: [doc/src/tut/fig-tut/vehicle_v23, width=800]
+
+Another major feature of Pysketcher is the ability to let animate the
+sketch. Here is an example of a very simple vehicle on a bumpy road,
+where the solution of a differential equation (upper blue line) is fed
+back to the sketch to make a vertical displacement of the spring and
+other objects in the vehicle, "view animation": "http://hplgit.github.io/bumpy/doc/src/mov-bumpy/m2_k1_5_b0_2/index.html".
+
+FIGURE: [http://hplgit.github.io/bumpy/doc/src/mov-bumpy/m2_k1_5_b0_2/tmp_frame_0030.png, width=600]
+
 
 ===== Tutorial =====
 
-For an introduction to Pysketcher, see the tutorial in "HTML": "http://hplgit.github.io/pysketcher/doc/pub/html/index.html" or "PDF": "http://hplgit/github.io/pysketcher/doc/pub/pysketcher.pdf" (or a simplified version of
+For an introduction to Pysketcher, see the tutorial in "HTML": "http://hplgit.github.io/pysketcher/doc/pub/pysketcher.html", "Sphinx": "http://hplgit.github.io/pysketcher/doc/pub/html/index.html", or "PDF": "http://hplgit/github.io/pysketcher/doc/pub/pysketcher.pdf" format (or a simplified version of
 the tutorial in Chapter 9 in "A Primer on Scientific Programming with Python": "http://www.amazon.com/Scientific-Programming-Computational-Science-Engineering/dp/3642549586/ref=sr_1_2?s=books&ie=UTF8&qid=1407225588&sr=1-2&keywords=langtangen", by H. P. Langtangen, Springer, 2014).
 
 ===== Citation =====

+ 36 - 2
README.md

@@ -1,8 +1,42 @@
-Python-based drawing tool for making sketches of mechanics problems.
+## Pysketcher
+
+Tool for defining sketches of physics problems in terms of Python code.
+
+### Purpose
+
+Pysketcher can typically be used to draw figures like
+
+<!-- <img src="doc/src/tut/fig-tut/wheel_on_inclined_plane.png" width=600> -->
+![](doc/src/tut/fig-tut/wheel_on_inclined_plane.png)
+
+Such figures can easily be *interactively* made using a lot of drawing programs.
+A Pysketcher figure, however, is defined in terms of computer code. This gives
+a great advantage: geometric features can be parameterized in term
+of variables, as here:
+
+<!-- <img src="doc/src/tut/fig-tut/vehicle0_dim.png" width=600> -->
+![](doc/src/tut/fig-tut/vehicle0_dim.png)
+
+One can then quickly change parameters, here to
+`R=0.5; L=5; H=2` and `R=2; L=7; H=1`, and get new figures that would be
+tedious to draw manually in an interactive tool.
+
+<!-- <img src="doc/src/tut/fig-tut/vehicle_v23.png" width=800> -->
+![](doc/src/tut/fig-tut/vehicle_v23.png)
+
+Another major feature of Pysketcher is the ability to let animate the
+sketch. Here is an example of a very simple vehicle on a bumpy road,
+where the solution of a differential equation (upper blue line) is fed
+back to the sketch to make a vertical displacement of the spring and
+other objects in the vehicle, [view animation](http://hplgit.github.io/bumpy/doc/src/mov-bumpy/m2_k1_5_b0_2/index.html).
+
+<!-- <img src="http://hplgit.github.io/bumpy/doc/src/mov-bumpy/m2_k1_5_b0_2/tmp_frame_0030.png" width=600> -->
+![](http://hplgit.github.io/bumpy/doc/src/mov-bumpy/m2_k1_5_b0_2/tmp_frame_0030.png)
+
 
 ### Tutorial
 
-For an introduction to Pysketcher, see the tutorial in [HTML](http://hplgit.github.io/pysketcher/doc/pub/html/index.html) or [PDF](http://hplgit/github.io/pysketcher/doc/pub/pysketcher.pdf) (or a simplified version of
+For an introduction to Pysketcher, see the tutorial in [HTML](http://hplgit.github.io/pysketcher/doc/pub/pysketcher.html), [Sphinx](http://hplgit.github.io/pysketcher/doc/pub/html/index.html), or [PDF](http://hplgit/github.io/pysketcher/doc/pub/pysketcher.pdf) format (or a simplified version of
 the tutorial in Chapter 9 in [A Primer on Scientific Programming with Python](http://www.amazon.com/Scientific-Programming-Computational-Science-Engineering/dp/3642549586/ref=sr_1_2?s=books&ie=UTF8&qid=1407225588&sr=1-2&keywords=langtangen), by H. P. Langtangen, Springer, 2014).
 
 ### Citation

+ 197 - 0
doc/pub/tutorial/._pysketcher000.html

@@ -0,0 +1,197 @@
+<!--
+Automatically generated HTML file from DocOnce source
+(https://github.com/hplgit/doconce/)
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="DocOnce: https://github.com/hplgit/doconce/" />
+<meta name="description" content="Using Pysketcher to Create Principal Sketches of Physics Problems">
+<meta name="keywords" content="tree data structure,recursive function calls">
+
+<title>Using Pysketcher to Create Principal Sketches of Physics Problems</title>
+
+
+<style type="text/css">
+/* blueish style */
+
+/* Color definitions:  http://www.december.com/html/spec/color0.html
+   CSS examples:       http://www.w3schools.com/css/css_examples.asp */
+
+body {
+  margin-top: 1.0em;
+  background-color: #ffffff;
+  font-family: Helvetica, Arial, FreeSans, san-serif;
+  color: #000000;
+}
+h1 { font-size: 1.8em; color: #1e36ce; }
+h2 { font-size: 1.6em; color: #1e36ce; }
+h3 { font-size: 1.4em; color: #1e36ce; }
+a { color: #1e36ce; text-decoration:none; }
+tt { font-family: "Courier New", Courier; }
+/* pre style removed because it will interfer with pygments */
+p { text-indent: 0px; }
+hr { border: 0; width: 80%; border-bottom: 1px solid #aaa}
+p.caption { width: 80%; font-style: normal; text-align: left; }
+hr.figure { border: 0; width: 80%; border-bottom: 1px solid #aaa}
+
+div { text-align: justify; text-justify: inter-word; }
+</style>
+
+
+</head>
+
+<!-- tocinfo
+{'highest level': 1,
+ 'sections': [(' A First Glimpse of Pysketcher ', 1, None, '___sec0'),
+              (' Basic Construction of Sketches ', 2, None, '___sec1'),
+              (' Basic Drawing ', 3, None, '___sec2'),
+              (' Groups of Objects ', 3, None, '___sec3'),
+              (' Changing Line Styles and Colors ', 3, None, '___sec4'),
+              (' The Figure Composition as an Object Hierarchy ',
+               3,
+               None,
+               '___sec5'),
+              (' Animation: Translating the Vehicle ', 3, None, '___sec6'),
+              (' Animation: Rolling the Wheels ',
+               3,
+               'sketcher:vehicle1:anim',
+               'sketcher:vehicle1:anim'),
+              (' Basic Shapes ', 1, None, '___sec8'),
+              (' Axis ', 2, None, '___sec9'),
+              (' Distance with Text ', 2, None, '___sec10'),
+              (' Rectangle ', 2, None, '___sec11'),
+              (' Triangle ', 2, None, '___sec12'),
+              (' Arc ', 2, None, '___sec13'),
+              (' Spring ', 2, None, '___sec14'),
+              (' Dashpot ', 2, None, '___sec15'),
+              (' Wavy ', 2, None, '___sec16'),
+              (' Stochastic curves ', 2, None, '___sec17'),
+              (' Inner Workings of the Pysketcher Tool ',
+               1,
+               None,
+               '___sec18'),
+              (' Example of Classes for Geometric Objects ',
+               2,
+               None,
+               '___sec19'),
+              (' Simple Geometric Objects ', 3, None, '___sec20'),
+              (' Class Curve ', 3, None, '___sec21'),
+              (' Compound Geometric Objects ', 3, None, '___sec22'),
+              (' Adding Functionality via Recursion ', 2, None, '___sec23'),
+              (' Basic Principles of Recursion ', 3, None, '___sec24'),
+              (' Explaining Recursion ', 3, None, '___sec25'),
+              (' Scaling, Translating, and Rotating a Figure ',
+               2,
+               'sketcher:scaling',
+               'sketcher:scaling'),
+              (' Scaling ', 3, None, '___sec27'),
+              (' Translation ', 3, None, '___sec28'),
+              (' Rotation ', 3, None, '___sec29')]}
+end of tocinfo -->
+
+<body>
+
+
+
+<script type="text/x-mathjax-config">
+MathJax.Hub.Config({
+  TeX: {
+     equationNumbers: {  autoNumber: "none"  },
+     extensions: ["AMSmath.js", "AMSsymbols.js", "autobold.js", "color.js"]
+  }
+});
+</script>
+<script type="text/javascript"
+ src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
+</script>
+
+
+
+    
+<a name="part0000"></a>
+<p>
+<!-- begin top navigation -->
+<table style="width: 100%"><tr><td>
+</td><td>
+<div style="text-align: right;"><a href="._pysketcher001.html"><img src="http://hplgit.github.io/doconce/bundled/html_images/next1.png" border=0 alt="Next &raquo;"></a></div>
+</td></tr></table>
+<!-- end top navigation -->
+</p>
+
+<p>
+<!-- ------------------- main content ---------------------- -->
+
+
+
+<center><h1>Using Pysketcher to Create Principal Sketches of Physics Problems</h1></center>  <!-- document title -->
+
+<p>
+<!-- author(s): Hans Petter Langtangen -->
+
+<center>
+<b>Hans Petter Langtangen</b> [1, 2]
+</center>
+
+<p>
+<!-- institution(s) -->
+
+<center>[1] <b>Center for Biomedical Computing, Simula Research Laboratory</b></center>
+<center>[2] <b>Department of Informatics, University of Oslo</b></center>
+<p>
+<center><h4>Apr 27, 2015</h4></center> <!-- date -->
+<p>
+
+<!-- begin box -->
+<div style="width: 95%; padding: 10px; border: 1px solid #000; border-radius: 4px;">
+This document is derived from Chapter 9 in the book
+<a href="http://www.amazon.com/Scientific-Programming-Computational-Science-Engineering/dp/3642549586/ref=sr_1_2?s=books&ie=UTF8&qid=1407225588&sr=1-2&keywords=langtangen" target="_self">A Primer on Scientific Programming with Python</a>, by H. P. Langtangen,
+4th edition, Springer, 2014.
+</div>
+<!-- end box -->
+
+
+<p>
+<b>Abstract.</b> Pysketcher is a Python package which allows principal sketches of
+physics and mechanics problems to be realized through short programs
+instead of interactive (and potentially tedious and inaccurate)
+drawing.  Elements of the sketch, such as lines, circles, angles,
+forces, coordinate systems, etc., are realized as objects and
+collected in hierarchical structures. Parts of the hierarchical
+structures can easily change line styles and colors, or be copied,
+scaled, translated, and rotated. These features make it
+straightforward to move parts of the sketch to create animation,
+usually in accordance with the physics of the underlying problem.
+Exact dimensioning of the elements in the sketch is trivial to obtain
+since distances are specified in computer code.
+
+<p>
+Pysketcher is easy to learn from a number of examples. Beyond
+essential Python programming and a knowledge about mechanics problems,
+no further background is required.
+
+<p>
+<!-- Task (can be questions): make sketches of physical problems, see fig -->
+<!-- through user-friendly composition of basic shapes -->
+<!-- Desired knowledge: plotting curves, basic OO (ch. X.Y, ...) -->
+<!-- Required knowledge? -->
+<!-- Learning Goals: these targets the inner workings of pysketcher, -->
+<!-- which is just a part of this document... -->
+
+<p>
+<p>
+<!-- begin bottom navigation -->
+<table style="width: 100%"><tr><td>
+</td><td>
+<div style="text-align: right;"><a href="._pysketcher001.html"><img src="http://hplgit.github.io/doconce/bundled/html_images/next1.png" border=0 alt="Next &raquo;"></a></div>
+</td></tr></table>
+<!-- end bottom navigation -->
+</p>
+
+<!-- ------------------- end of main content --------------- -->
+
+
+</body>
+</html>
+    
+

+ 813 - 0
doc/pub/tutorial/._pysketcher001.html

@@ -0,0 +1,813 @@
+<!--
+Automatically generated HTML file from DocOnce source
+(https://github.com/hplgit/doconce/)
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="DocOnce: https://github.com/hplgit/doconce/" />
+<meta name="description" content="Using Pysketcher to Create Principal Sketches of Physics Problems">
+<meta name="keywords" content="tree data structure,recursive function calls">
+
+<title>Using Pysketcher to Create Principal Sketches of Physics Problems</title>
+
+
+<style type="text/css">
+/* blueish style */
+
+/* Color definitions:  http://www.december.com/html/spec/color0.html
+   CSS examples:       http://www.w3schools.com/css/css_examples.asp */
+
+body {
+  margin-top: 1.0em;
+  background-color: #ffffff;
+  font-family: Helvetica, Arial, FreeSans, san-serif;
+  color: #000000;
+}
+h1 { font-size: 1.8em; color: #1e36ce; }
+h2 { font-size: 1.6em; color: #1e36ce; }
+h3 { font-size: 1.4em; color: #1e36ce; }
+a { color: #1e36ce; text-decoration:none; }
+tt { font-family: "Courier New", Courier; }
+/* pre style removed because it will interfer with pygments */
+p { text-indent: 0px; }
+hr { border: 0; width: 80%; border-bottom: 1px solid #aaa}
+p.caption { width: 80%; font-style: normal; text-align: left; }
+hr.figure { border: 0; width: 80%; border-bottom: 1px solid #aaa}
+
+div { text-align: justify; text-justify: inter-word; }
+</style>
+
+
+</head>
+
+<!-- tocinfo
+{'highest level': 1,
+ 'sections': [(' A First Glimpse of Pysketcher ', 1, None, '___sec0'),
+              (' Basic Construction of Sketches ', 2, None, '___sec1'),
+              (' Basic Drawing ', 3, None, '___sec2'),
+              (' Groups of Objects ', 3, None, '___sec3'),
+              (' Changing Line Styles and Colors ', 3, None, '___sec4'),
+              (' The Figure Composition as an Object Hierarchy ',
+               3,
+               None,
+               '___sec5'),
+              (' Animation: Translating the Vehicle ', 3, None, '___sec6'),
+              (' Animation: Rolling the Wheels ',
+               3,
+               'sketcher:vehicle1:anim',
+               'sketcher:vehicle1:anim'),
+              (' Basic Shapes ', 1, None, '___sec8'),
+              (' Axis ', 2, None, '___sec9'),
+              (' Distance with Text ', 2, None, '___sec10'),
+              (' Rectangle ', 2, None, '___sec11'),
+              (' Triangle ', 2, None, '___sec12'),
+              (' Arc ', 2, None, '___sec13'),
+              (' Spring ', 2, None, '___sec14'),
+              (' Dashpot ', 2, None, '___sec15'),
+              (' Wavy ', 2, None, '___sec16'),
+              (' Stochastic curves ', 2, None, '___sec17'),
+              (' Inner Workings of the Pysketcher Tool ',
+               1,
+               None,
+               '___sec18'),
+              (' Example of Classes for Geometric Objects ',
+               2,
+               None,
+               '___sec19'),
+              (' Simple Geometric Objects ', 3, None, '___sec20'),
+              (' Class Curve ', 3, None, '___sec21'),
+              (' Compound Geometric Objects ', 3, None, '___sec22'),
+              (' Adding Functionality via Recursion ', 2, None, '___sec23'),
+              (' Basic Principles of Recursion ', 3, None, '___sec24'),
+              (' Explaining Recursion ', 3, None, '___sec25'),
+              (' Scaling, Translating, and Rotating a Figure ',
+               2,
+               'sketcher:scaling',
+               'sketcher:scaling'),
+              (' Scaling ', 3, None, '___sec27'),
+              (' Translation ', 3, None, '___sec28'),
+              (' Rotation ', 3, None, '___sec29')]}
+end of tocinfo -->
+
+<body>
+
+
+
+<script type="text/x-mathjax-config">
+MathJax.Hub.Config({
+  TeX: {
+     equationNumbers: {  autoNumber: "none"  },
+     extensions: ["AMSmath.js", "AMSsymbols.js", "autobold.js", "color.js"]
+  }
+});
+</script>
+<script type="text/javascript"
+ src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
+</script>
+
+
+
+    
+<a name="part0001"></a>
+<p>
+<!-- begin top navigation -->
+<table style="width: 100%"><tr><td>
+<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>
+</td><td>
+<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>
+</td></tr></table>
+<!-- end top navigation -->
+</p>
+
+<p>
+<!-- !split -->
+
+<p>
+2DO:
+
+<ul>
+ <li> two wheels of different radii on inclined plane coupled to
+   correct solution</li>
+ <li> <a href="http://inventwithpython.com/chapter17.html" target="_self">Pygame backend</a></li>
+</ul>
+
+<h1 id="___sec0">A First Glimpse of Pysketcher </h1>
+
+<p>
+Formulation of physical problems makes heavy use of <em>principal sketches</em>
+such as the one in Figure <a href="#sketcher:fig:inclinedplane">1</a>.
+This particular sketch illustrates the classical mechanics problem
+of a rolling wheel on an inclined plane.
+The figure
+is made up many individual elements: a rectangle
+filled with a pattern (the inclined plane), a hollow circle with color
+(the wheel), arrows with labels (the \( N \) and \( Mg \) forces, and the \( x \)
+axis), an angle with symbol \( \theta \), and a dashed line indicating the
+starting location of the wheel.
+
+<p>
+Drawing software and plotting programs can produce such figures quite
+easily in principle, but the amount of details the user needs to
+control with the mouse can be substantial. Software more tailored to
+producing sketches of this type would work with more convenient
+abstractions, such as circle, wall, angle, force arrow, axis, and so
+forth. And as soon we start <em>programming</em> to construct the figure we
+get a range of other powerful tools at disposal. For example, we can
+easily translate and rotate parts of the figure and make an animation
+that illustrates the physics of the problem.
+Programming as a superior alternative to interactive drawing is
+the mantra of this section.
+
+<p>
+<center> <!-- figure -->
+<hr class="figure">
+<center><p class="caption">Figure 1:  Sketch of a physics problem. <div id="sketcher:fig:inclinedplane"></div> </p></center>
+<p><img src="fig-tut/wheel_on_inclined_plane.png" align="bottom" width=400></p>
+</center>
+
+<h2 id="___sec1">Basic Construction of Sketches </h2>
+
+<p>
+Before attacking real-life sketches as in Figure <a href="#sketcher:fig:inclinedplane">1</a>
+we focus on the significantly simpler drawing shown
+in Figure <a href="#sketcher:fig:vehicle0">2</a>.  This toy sketch consists of
+several elements: two circles, two rectangles, and a &quot;ground&quot; element.
+
+<p>
+<center> <!-- figure -->
+<hr class="figure">
+<center><p class="caption">Figure 2:  Sketch of a simple figure. <div id="sketcher:fig:vehicle0"></div> </p></center>
+<p><img src="fig-tut/vehicle0_dim.png" align="bottom" width=600></p>
+</center>
+
+<p>
+When the sketch is defined in terms of computer code, it is natural to
+parameterize geometric features, such as the radius of the wheel (\( R \)),
+the center point of the left wheel (\( w_1 \)), as well as the height (\( H \)) and
+length (\( L \)) of the main part. The simple vehicle in
+Figure <a href="#sketcher:fig:vehicle0">2</a> is quickly drawn in almost any interactive
+tool. However, if we want to change the radius of the wheels, you need a
+sophisticated drawing tool to avoid redrawing the whole figure, while
+in computer code this is a matter of changing the \( R \) parameter and
+rerunning the program.
+For example, Figure <a href="#sketcher:fig:vehicle0b">3</a> shows
+a variation of the drawing in
+Figure <a href="#sketcher:fig:vehicle0">2</a> obtained by just setting
+\( R=0.5 \), \( L=5 \), \( H=2 \), and \( R=2 \). Being able
+to quickly change geometric sizes is key to many problem settings in
+physics and engineering, but then a program must define the geometry.
+
+<p>
+<center> <!-- figure -->
+<hr class="figure">
+<center><p class="caption">Figure 3:  Redrawing a figure with other geometric parameters. <div id="sketcher:fig:vehicle0b"></div> </p></center>
+<p><img src="fig-tut/vehicle_v2.png" align="bottom" width=500></p>
+</center>
+
+<h3 id="___sec2">Basic Drawing </h3>
+
+<p>
+A typical program creating these five elements is shown next.
+After importing the <code>pysketcher</code> package, the first task is always to
+define a coordinate system:
+
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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>
+
+drawing_tool<span style="color: #666666">.</span>set_coordinate_system(
+    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>)
+</pre></div>
+<p>
+Instead of working with lengths expressed by specific numbers it is
+highly recommended to use variables to parameterize lengths as
+this makes it easier to change dimensions later.
+Here we introduce some key lengths for the radius of the wheels,
+distance between the wheels, etc.:
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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>
+L <span style="color: #666666">=</span> <span style="color: #666666">4</span>    <span style="color: #408080; font-style: italic"># distance between wheels</span>
+H <span style="color: #666666">=</span> <span style="color: #666666">2</span>    <span style="color: #408080; font-style: italic"># height of vehicle body</span>
+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>
+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,
+                                   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)
+</pre></div>
+<p>
+With the drawing area in place we can make the first <code>Circle</code> object
+in an intuitive fashion:
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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)
+</pre></div>
+<p>
+to change dimensions later.
+
+<p>
+To translate the geometric information about the <code>wheel1</code> object to
+instructions for the plotting engine (in this case Matplotlib), one calls the
+<code>wheel1.draw()</code>. To display all drawn objects, one issues
+<code>drawing_tool.display()</code>. The typical steps are hence:
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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)
+wheel1<span style="color: #666666">.</span>draw()
+
+<span style="color: #408080; font-style: italic"># Define other objects and call their draw() methods</span>
+drawing_tool<span style="color: #666666">.</span>display()
+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>
+</pre></div>
+<p>
+The next wheel can be made by taking a copy of <code>wheel1</code> and
+translating the object to the right according to a
+displacement vector \( (L,0) \):
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">wheel2 <span style="color: #666666">=</span> wheel1<span style="color: #666666">.</span>copy()
+wheel2<span style="color: #666666">.</span>translate((L,<span style="color: #666666">0</span>))
+</pre></div>
+<p>
+The two rectangles are also made in an intuitive way:
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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),
+                  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)
+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),
+                  width<span style="color: #666666">=2.5*</span>R, height<span style="color: #666666">=1.25*</span>H)
+</pre></div>
+
+<h3 id="___sec3">Groups of Objects </h3>
+
+<p>
+Instead of calling the <code>draw</code> method of every object, we can
+group objects and call <code>draw</code>, or perform other operations, for
+the whole group. For example, we may collect the two wheels
+in a <code>wheels</code> group and the <code>over</code> and <code>under</code> rectangles
+in a <code>body</code> group. The whole vehicle is a composition
+of its <code>wheels</code> and <code>body</code> groups. The code goes like
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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})
+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})
+
+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})
+</pre></div>
+<p>
+The ground is illustrated by an object of type <code>Wall</code>,
+mostly used to indicate walls in sketches of mechanical systems.
+A <code>Wall</code> takes the <code>x</code> and <code>y</code> coordinates of some curve,
+and a <code>thickness</code> parameter, and creates a thick curve filled
+with a simple pattern. In this case the curve is just a flat
+line so the construction is made of two points on the
+ground line (\( (w_1-L,0) \) and \( (w_1+3L,0) \)):
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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)
+</pre></div>
+<p>
+The negative thickness makes the pattern-filled rectangle appear below
+the defined line, otherwise it appears above.
+
+<p>
+We may now collect all the objects in a &quot;top&quot; object that contains
+the whole figure:
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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})
+fig<span style="color: #666666">.</span>draw()  <span style="color: #408080; font-style: italic"># send all figures to plotting backend</span>
+drawing_tool<span style="color: #666666">.</span>display()
+drawing_tool<span style="color: #666666">.</span>savefig(<span style="color: #BA2121">&#39;tmp.png&#39;</span>)
+</pre></div>
+<p>
+The <code>fig.draw()</code> call will visit
+all subgroups, their subgroups,
+and so forth in the hierarchical tree structure of
+figure elements,
+and call <code>draw</code> for every object.
+
+<h3 id="___sec4">Changing Line Styles and Colors </h3>
+
+<p>
+Controlling the line style, line color, and line width is
+fundamental when designing figures. The <code>pysketcher</code>
+package allows the user to control such properties in
+single objects, but also set global properties that are
+used if the object has no particular specification of
+the properties. Setting the global properties are done like
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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>)
+drawing_tool<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;black&#39;</span>)
+drawing_tool<span style="color: #666666">.</span>set_linewidth(<span style="color: #666666">4</span>)
+</pre></div>
+<p>
+At the object level the properties are specified in a similar
+way:
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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>)
+wheels<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;red&#39;</span>)
+</pre></div>
+<p>
+and so on.
+
+<p>
+Geometric figures can be specified as <em>filled</em>, either with a color or with a
+special visual pattern:
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #408080; font-style: italic"># Set filling of all curves</span>
+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>)
+
+<span style="color: #408080; font-style: italic"># Turn off filling of all curves</span>
+drawing_tool<span style="color: #666666">.</span>set_filled_curves(<span style="color: #008000">False</span>)
+
+<span style="color: #408080; font-style: italic"># Fill the wheel with red color</span>
+wheel1<span style="color: #666666">.</span>set_filled_curves(<span style="color: #BA2121">&#39;red&#39;</span>)
+</pre></div>
+<p>
+<!-- <a href="http://packages.python.org/ete2/" target="_self"><tt>http://packages.python.org/ete2/</tt></a> for visualizing tree structures! -->
+
+<h3 id="___sec5">The Figure Composition as an Object Hierarchy </h3>
+
+<p>
+The composition of objects making up the figure
+is hierarchical, similar to a family, where
+each object has a parent and a number of children. Do a
+<code>print fig</code> to display the relations:
+<p>
+
+<!-- code=text (!bc dat) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">ground
+    wall
+vehicle
+    body
+        over
+            rectangle
+        under
+            rectangle
+    wheels
+        wheel1
+            arc
+        wheel2
+            arc
+</pre></div>
+<p>
+The indentation reflects how deep down in the hierarchy (family)
+we are.
+This output is to be interpreted as follows:
+
+<ul>
+  <li> <code>fig</code> contains two objects, <code>ground</code> and <code>vehicle</code></li>
+  <li> <code>ground</code> contains an object <code>wall</code></li>
+  <li> <code>vehicle</code> contains two objects, <code>body</code> and <code>wheels</code></li>
+  <li> <code>body</code> contains two objects, <code>over</code> and <code>under</code></li>
+  <li> <code>wheels</code> contains two objects, <code>wheel1</code> and <code>wheel2</code></li>
+</ul>
+
+In this listing there are also objects not defined by the
+programmer: <code>rectangle</code> and <code>arc</code>. These are of type <code>Curve</code>
+and automatically generated by the classes <code>Rectangle</code> and <code>Circle</code>.
+
+<p>
+More detailed information can be printed by
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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>)
+</pre></div>
+<p>
+yielding the output
+<p>
+
+<!-- code=text (!bc dat) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">ground (Wall):
+    wall (Curve): 4 coords fillcolor=&#39;white&#39; fillpattern=&#39;/&#39;
+vehicle (Composition):
+    body (Composition):
+        over (Rectangle):
+            rectangle (Curve): 5 coords
+        under (Rectangle):
+            rectangle (Curve): 5 coords
+    wheels (Composition):
+        wheel1 (Circle):
+            arc (Curve): 181 coords
+        wheel2 (Circle):
+            arc (Curve): 181 coords
+</pre></div>
+<p>
+Here we can see the class type for each figure object, how many
+coordinates that are involved in basic figures (<code>Curve</code> objects), and
+special settings of the basic figure (fillcolor, line types, etc.).
+For example, <code>wheel2</code> is a <code>Circle</code> object consisting of an <code>arc</code>,
+which is a <code>Curve</code> object consisting of 181 coordinates (the
+points needed to draw a smooth circle). The <code>Curve</code> objects are the
+only objects that really holds specific coordinates to be drawn.
+The other object types are just compositions used to group
+parts of the complete figure.
+
+<p>
+One can also get a graphical overview of the hierarchy of figure objects
+that build up a particular figure <code>fig</code>.
+Just call <code>fig.graphviz_dot('fig')</code> to produce a file <code>fig.dot</code> in
+the <em>dot format</em>. This file contains relations between parent and
+child objects in the figure and can be turned into an image,
+as in Figure <a href="#sketcher:fig:vehicle0:hier1">4</a>, by
+running the <code>dot</code> program:
+<p>
+
+<!-- code=text (!bc sys) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">Terminal&gt; dot -Tpng -o fig.png fig.dot
+</pre></div>
+<p>
+<center> <!-- figure -->
+<hr class="figure">
+<center><p class="caption">Figure 4:  Hierarchical relation between figure objects. <div id="sketcher:fig:vehicle0:hier1"></div> </p></center>
+<p><img src="fig-tut/vehicle0_hier1.png" align="bottom" width=500></p>
+</center>
+
+<p>
+The call <code>fig.graphviz_dot('fig', classname=True)</code> makes a <code>fig.dot</code> file
+where the class type of each object is also visible, see
+Figure <a href="#sketcher:fig:vehicle0:hier2">5</a>. The ability to write out the
+object hierarchy or view it graphically can be of great help when
+working with complex figures that involve layers of subfigures.
+
+<p>
+<center> <!-- figure -->
+<hr class="figure">
+<center><p class="caption">Figure 5:  Hierarchical relation between figure objects, including their class names. <div id="sketcher:fig:vehicle0:hier2"></div> </p></center>
+<p><img src="fig-tut/Vehicle0_hier2.png" align="bottom" width=500></p>
+</center>
+
+<p>
+Any of the objects can in the program be reached through their names, e.g.,
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>]
+fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>][<span style="color: #BA2121">&#39;wheels&#39;</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>]
+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>]
+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>
+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>
+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
+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
+</pre></div>
+<p>
+Grabbing a part of the figure this way is handy for
+changing properties of that part, for example, colors, line styles
+(see Figure <a href="#sketcher:fig:vehicle0:v2">6</a>):
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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>)
+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>)
+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>)
+
+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>)
+
+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>)
+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>)
+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>
+</pre></div>
+<p>
+The last line accesses the <code>Curve</code> object directly, while the line above,
+accesses the <code>Rectangle</code> object, which will then set the linewidth of
+its <code>Curve</code> object, and other objects if it had any.
+The result of the actions above is shown in Figure <a href="#sketcher:fig:vehicle0:v2">6</a>.
+
+<p>
+<center> <!-- figure -->
+<hr class="figure">
+<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>
+<p><img src="fig-tut/vehicle0.png" align="bottom" width=700></p>
+</center>
+
+<p>
+We can also change position of parts of the figure and thereby make
+animations, as shown next.
+
+<h3 id="___sec6">Animation: Translating the Vehicle </h3>
+
+<p>
+Can we make our little vehicle roll? A first attempt will be to
+fake rolling by just displacing all parts of the vehicle.
+The relevant parts constitute the <code>fig['vehicle']</code> object.
+This part of the figure can be translated, rotated, and scaled.
+A translation along the ground means a translation in \( x \) direction,
+say a length \( L \) to the right:
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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>))
+</pre></div>
+<p>
+You need to erase, draw, and display to see the movement:
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">drawing_tool<span style="color: #666666">.</span>erase()
+fig<span style="color: #666666">.</span>draw()
+drawing_tool<span style="color: #666666">.</span>display()
+</pre></div>
+<p>
+Without erasing, the old drawing of the vehicle will remain in
+the figure so you get two vehicles. Without <code>fig.draw()</code> the
+new coordinates of the vehicle will not be communicated to
+the drawing tool, and without calling display the updated
+drawing will not be visible.
+
+<p>
+A figure that moves in time is conveniently realized by the
+function <code>animate</code>:
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">animate(fig, tp, action)
+</pre></div>
+<p>
+Here, <code>fig</code> is the entire figure, <code>tp</code> is an array of
+time points, and <code>action</code> is a user-specified function that changes
+<code>fig</code> at a specific time point. Typically, <code>action</code> will move
+parts of <code>fig</code>.
+
+<p>
+In the present case we can define the movement through a velocity
+function <code>v(t)</code> and displace the figure <code>v(t)*dt</code> for small time
+intervals <code>dt</code>. A possible velocity function is
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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):
+    <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))
+</pre></div>
+<p>
+Our action function for horizontal displacements <code>v(t)*dt</code> becomes
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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):
+    x_displacement <span style="color: #666666">=</span> dt<span style="color: #666666">*</span>v(t)
+    fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>]<span style="color: #666666">.</span>translate((x_displacement, <span style="color: #666666">0</span>))
+</pre></div>
+<p>
+Since our velocity is negative for \( t\in [0,2R] \) the displacement is
+to the left.
+
+<p>
+The <code>animate</code> function will for each time point <code>t</code> in <code>tp</code> erase
+the drawing, call <code>action(t, fig)</code>, and show the new figure by
+<code>fig.draw()</code> and <code>drawing_tool.display()</code>.
+Here we choose a resolution of the animation corresponding to
+25 time points in the time interval \( [0,2R] \):
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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>
+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>)
+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>
+
+animate(fig, tp, move, pause_per_frame<span style="color: #666666">=0.2</span>)
+</pre></div>
+<p>
+The <code>pause_per_frame</code> adds a pause, here 0.2 seconds, between
+each frame in the animation.
+
+<p>
+We can also ask <code>animate</code> to store each frame in a file:
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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>,
+                pause_per_frame<span style="color: #666666">=0.2</span>)
+</pre></div>
+<p>
+The <code>files</code> variable, here <code>'tmp_frame_%04d.png'</code>,
+is the printf-specification used to generate the individual
+plot files. We can use this specification to make a video
+file via <code>ffmpeg</code> (or <code>avconv</code> on Debian-based Linux systems such
+as Ubuntu). Videos in the Flash and WebM formats can be created
+by
+
+<p>
+
+<!-- code=text (!bc sys) typeset with pygments style "default" -->
+<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
+Terminal&gt; ffmpeg -r 12 -i tmp_frame_%04d.png -vcodec libvpx mov.webm
+</pre></div>
+<p>
+An animated GIF movie can also be made using the <code>convert</code> program
+from the ImageMagick software suite:
+
+<p>
+
+<!-- code=text (!bc sys) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">Terminal&gt; convert -delay 20 tmp_frame*.png mov.gif
+Terminal&gt; animate mov.gif  # play movie
+</pre></div>
+<p>
+The delay between frames, in units of 1/100 s,
+governs the speed of the movie.
+To play the animated GIF file in a web page, simply insert
+<code>&lt;img src=&quot;mov.gif&quot;&gt;</code> in the HTML code.
+
+<p>
+The individual PNG frames can be directly played in a web
+browser by running
+
+<p>
+
+<!-- code=text (!bc sys) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">Terminal&gt; scitools movie output_file=mov.html fps=5 tmp_frame*
+</pre></div>
+<p>
+or calling
+
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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
+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>)
+</pre></div>
+<p>
+in Python. Load the resulting file <code>mov.html</code> into a web browser
+to play the movie.
+
+<p>
+Try to run <a href="http://tinyurl.com/ot733jn/vehicle0.py" target="_self"><tt>vehicle0.py</tt></a> and
+then load <code>mov.html</code> into a browser, or play one of the <code>mov.*</code>
+video files.  Alternatively, you can view a ready-made <a href="http://tinyurl.com/oou9lp7/mov-tut/vehicle0.html" target="_self">movie</a>.
+
+<h3 id="sketcher:vehicle1:anim">Animation: Rolling the Wheels</h3>
+
+<p>
+It is time to show rolling wheels. To this end, we add spokes to the
+wheels, formed by two crossing lines, see Figure <a href="#sketcher:fig:vehicle1">7</a>.
+The construction of the wheels will now involve a circle and two lines:
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">wheel1 <span style="color: #666666">=</span> Composition({
+    <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),
+    <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)),
+                          <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))})})
+wheel2 <span style="color: #666666">=</span> wheel1<span style="color: #666666">.</span>copy()
+wheel2<span style="color: #666666">.</span>translate((L,<span style="color: #666666">0</span>))
+</pre></div>
+<p>
+Observe that <code>wheel1.copy()</code> copies all the objects that make
+up the first wheel, and <code>wheel2.translate</code> translates all
+the copied objects.
+
+<p>
+<center> <!-- figure -->
+<hr class="figure">
+<center><p class="caption">Figure 7:  Wheels with spokes to illustrate rolling. <div id="sketcher:fig:vehicle1"></div> </p></center>
+<p><img src="fig-tut/vehicle1.png" align="bottom" width=400></p>
+</center>
+
+<p>
+The <code>move</code> function now needs to displace all the objects in the
+entire vehicle and also rotate the <code>cross1</code> and <code>cross2</code>
+objects in both wheels.
+The rotation angle follows from the fact that the arc length
+of a rolling wheel equals the displacement of the center of
+the wheel, leading to a rotation angle
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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
+</pre></div>
+<p>
+With <code>w_1</code> tracking the \( x \) coordinate of the center
+of the front wheel, we can rotate that wheel by
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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>]
+<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
+w1<span style="color: #666666">.</span>rotate(degrees(angle), center<span style="color: #666666">=</span>(w_1, R))
+</pre></div>
+<p>
+The <code>rotate</code> function takes two parameters: the rotation angle
+(in degrees) and the center point of the rotation, which is the
+center of the wheel in this case. The other wheel is rotated by
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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>]
+w2<span style="color: #666666">.</span>rotate(degrees(angle), center<span style="color: #666666">=</span>(w_1 <span style="color: #666666">+</span> L, R))
+</pre></div>
+<p>
+That is, the angle is the same, but the rotation point is different.
+The update of the center point is done by <code>w_1 += x_displacement</code>.
+The complete <code>move</code> function with translation of the entire
+vehicle and rotation of the wheels then becomes
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<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>
+
+<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">move</span>(t, fig):
+    x_displacement <span style="color: #666666">=</span> dt<span style="color: #666666">*</span>v(t)
+    fig[<span style="color: #BA2121">&#39;vehicle&#39;</span>]<span style="color: #666666">.</span>translate((x_displacement, <span style="color: #666666">0</span>))
+
+    <span style="color: #408080; font-style: italic"># Rotate wheels</span>
+    <span style="color: #008000; font-weight: bold">global</span> w_1
+    w_1 <span style="color: #666666">+=</span> x_displacement
+    <span style="color: #408080; font-style: italic"># R*angle = -x_displacement</span>
+    angle <span style="color: #666666">=</span> <span style="color: #666666">-</span> x_displacement<span style="color: #666666">/</span>R
+    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>]
+    w1<span style="color: #666666">.</span>rotate(degrees(angle), center<span style="color: #666666">=</span>(w_1, R))
+    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>]
+    w2<span style="color: #666666">.</span>rotate(degrees(angle), center<span style="color: #666666">=</span>(w_1 <span style="color: #666666">+</span> L, R))
+</pre></div>
+<p>
+The complete example is found in the file
+<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>.
+
+<p>
+The advantages with making figures this way, through programming
+rather than using interactive drawing programs, are numerous.  For
+example, the objects are parameterized by variables so that various
+dimensions can easily be changed.  Subparts of the figure, possible
+involving a lot of figure objects, can change color, linetype, filling
+or other properties through a <em>single</em> function call.  Subparts of the
+figure can be rotated, translated, or scaled.  Subparts of the figure
+can also be copied and moved to other parts of the drawing
+area. However, the single most important feature is probably the
+ability to make animations governed by mathematical formulas or data
+coming from physics simulations of the problem, as shown in the example above.
+
+<p>
+<p>
+<!-- begin bottom navigation -->
+<table style="width: 100%"><tr><td>
+<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>
+</td><td>
+<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>
+</td></tr></table>
+<!-- end bottom navigation -->
+</p>
+
+<!-- ------------------- end of main content --------------- -->
+
+
+</body>
+</html>
+    
+

+ 523 - 0
doc/pub/tutorial/._pysketcher002.html

@@ -0,0 +1,523 @@
+<!--
+Automatically generated HTML file from DocOnce source
+(https://github.com/hplgit/doconce/)
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="DocOnce: https://github.com/hplgit/doconce/" />
+<meta name="description" content="Using Pysketcher to Create Principal Sketches of Physics Problems">
+<meta name="keywords" content="tree data structure,recursive function calls">
+
+<title>Using Pysketcher to Create Principal Sketches of Physics Problems</title>
+
+
+<style type="text/css">
+/* blueish style */
+
+/* Color definitions:  http://www.december.com/html/spec/color0.html
+   CSS examples:       http://www.w3schools.com/css/css_examples.asp */
+
+body {
+  margin-top: 1.0em;
+  background-color: #ffffff;
+  font-family: Helvetica, Arial, FreeSans, san-serif;
+  color: #000000;
+}
+h1 { font-size: 1.8em; color: #1e36ce; }
+h2 { font-size: 1.6em; color: #1e36ce; }
+h3 { font-size: 1.4em; color: #1e36ce; }
+a { color: #1e36ce; text-decoration:none; }
+tt { font-family: "Courier New", Courier; }
+/* pre style removed because it will interfer with pygments */
+p { text-indent: 0px; }
+hr { border: 0; width: 80%; border-bottom: 1px solid #aaa}
+p.caption { width: 80%; font-style: normal; text-align: left; }
+hr.figure { border: 0; width: 80%; border-bottom: 1px solid #aaa}
+
+div { text-align: justify; text-justify: inter-word; }
+</style>
+
+
+</head>
+
+<!-- tocinfo
+{'highest level': 1,
+ 'sections': [(' A First Glimpse of Pysketcher ', 1, None, '___sec0'),
+              (' Basic Construction of Sketches ', 2, None, '___sec1'),
+              (' Basic Drawing ', 3, None, '___sec2'),
+              (' Groups of Objects ', 3, None, '___sec3'),
+              (' Changing Line Styles and Colors ', 3, None, '___sec4'),
+              (' The Figure Composition as an Object Hierarchy ',
+               3,
+               None,
+               '___sec5'),
+              (' Animation: Translating the Vehicle ', 3, None, '___sec6'),
+              (' Animation: Rolling the Wheels ',
+               3,
+               'sketcher:vehicle1:anim',
+               'sketcher:vehicle1:anim'),
+              (' Basic Shapes ', 1, None, '___sec8'),
+              (' Axis ', 2, None, '___sec9'),
+              (' Distance with Text ', 2, None, '___sec10'),
+              (' Rectangle ', 2, None, '___sec11'),
+              (' Triangle ', 2, None, '___sec12'),
+              (' Arc ', 2, None, '___sec13'),
+              (' Spring ', 2, None, '___sec14'),
+              (' Dashpot ', 2, None, '___sec15'),
+              (' Wavy ', 2, None, '___sec16'),
+              (' Stochastic curves ', 2, None, '___sec17'),
+              (' Inner Workings of the Pysketcher Tool ',
+               1,
+               None,
+               '___sec18'),
+              (' Example of Classes for Geometric Objects ',
+               2,
+               None,
+               '___sec19'),
+              (' Simple Geometric Objects ', 3, None, '___sec20'),
+              (' Class Curve ', 3, None, '___sec21'),
+              (' Compound Geometric Objects ', 3, None, '___sec22'),
+              (' Adding Functionality via Recursion ', 2, None, '___sec23'),
+              (' Basic Principles of Recursion ', 3, None, '___sec24'),
+              (' Explaining Recursion ', 3, None, '___sec25'),
+              (' Scaling, Translating, and Rotating a Figure ',
+               2,
+               'sketcher:scaling',
+               'sketcher:scaling'),
+              (' Scaling ', 3, None, '___sec27'),
+              (' Translation ', 3, None, '___sec28'),
+              (' Rotation ', 3, None, '___sec29')]}
+end of tocinfo -->
+
+<body>
+
+
+
+<script type="text/x-mathjax-config">
+MathJax.Hub.Config({
+  TeX: {
+     equationNumbers: {  autoNumber: "none"  },
+     extensions: ["AMSmath.js", "AMSsymbols.js", "autobold.js", "color.js"]
+  }
+});
+</script>
+<script type="text/javascript"
+ src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
+</script>
+
+
+
+    
+<a name="part0002"></a>
+<p>
+<!-- begin top navigation -->
+<table style="width: 100%"><tr><td>
+<div style="text-align: left;"><a href="._pysketcher001.html"><img src="http://hplgit.github.io/doconce/bundled/html_images/prev1.png" border=0 alt="&laquo; Previous"></a></div>
+</td><td>
+<div style="text-align: right;"><a href="._pysketcher003.html"><img src="http://hplgit.github.io/doconce/bundled/html_images/next1.png" border=0 alt="Next &raquo;"></a></div>
+</td></tr></table>
+<!-- end top navigation -->
+</p>
+
+<p>
+<!-- !split -->
+
+<h1 id="___sec8">Basic Shapes </h1>
+
+<p>
+This section presents many of the basic shapes in Pysketcher:
+<code>Axis</code>, <code>Distance_wText</code>, <code>Rectangle</code>, 	<code>Triangle</code>, <code>Arc</code>,
+<code>Spring</code>, <code>Dashpot</code>, and <code>Wavy</code>.
+Each shape is demonstrated with a figure and a
+unit test that shows how the figure is constructed in Python code.
+
+<h2 id="___sec9">Axis </h2>
+
+<p>
+The <code>Axis</code> object gives the possibility draw a single axis to
+notify a coordinate system. Here is an example where we
+draw \( x \) and \( y \) axis of three coordinate systems of different
+rotation:
+
+<p>
+<br />
+<br />
+
+<p>
+<center><p><img src="fig-tut/Axis.png" align="bottom" width=500></p></center>
+
+<p>
+<br />
+<br />
+
+<p>
+The corresponding code looks like this:
+
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">test_Axis</span>():
+    drawing_tool<span style="color: #666666">.</span>set_coordinate_system(
+        xmin<span style="color: #666666">=0</span>, xmax<span style="color: #666666">=15</span>, ymin<span style="color: #666666">=-7</span>, ymax<span style="color: #666666">=8</span>, axis<span style="color: #666666">=</span><span style="color: #008000">True</span>,
+        instruction_file<span style="color: #666666">=</span><span style="color: #BA2121">&#39;tmp_Axis.py&#39;</span>)
+    <span style="color: #408080; font-style: italic"># Draw normal x and y axis with origin at (7.5, 2)</span>
+    <span style="color: #408080; font-style: italic"># in the coordinate system of the sketch: [0,15]x[-7,8]</span>
+    x_axis <span style="color: #666666">=</span> Axis((<span style="color: #666666">7.5</span>,<span style="color: #666666">2</span>), <span style="color: #666666">5</span>, <span style="color: #BA2121">&#39;x&#39;</span>, rotation_angle<span style="color: #666666">=0</span>)
+    y_axis <span style="color: #666666">=</span> Axis((<span style="color: #666666">7.5</span>,<span style="color: #666666">2</span>), <span style="color: #666666">5</span>, <span style="color: #BA2121">&#39;y&#39;</span>, rotation_angle<span style="color: #666666">=90</span>)
+    system <span style="color: #666666">=</span> Composition({<span style="color: #BA2121">&#39;x axis&#39;</span>: x_axis, <span style="color: #BA2121">&#39;y axis&#39;</span>: y_axis})
+    system<span style="color: #666666">.</span>draw()
+    drawing_tool<span style="color: #666666">.</span>display()
+
+    <span style="color: #408080; font-style: italic"># Rotate this system 40 degrees counter clockwise</span>
+    <span style="color: #408080; font-style: italic"># and draw it with dashed lines</span>
+    system<span style="color: #666666">.</span>set_linestyle(<span style="color: #BA2121">&#39;dashed&#39;</span>)
+    system<span style="color: #666666">.</span>rotate(<span style="color: #666666">40</span>, (<span style="color: #666666">7.5</span>,<span style="color: #666666">2</span>))
+    system<span style="color: #666666">.</span>draw()
+    drawing_tool<span style="color: #666666">.</span>display()
+
+    <span style="color: #408080; font-style: italic"># Rotate this system another 220 degrees and show</span>
+    <span style="color: #408080; font-style: italic"># with dotted lines</span>
+    system<span style="color: #666666">.</span>set_linestyle(<span style="color: #BA2121">&#39;dotted&#39;</span>)
+    system<span style="color: #666666">.</span>rotate(<span style="color: #666666">220</span>, (<span style="color: #666666">7.5</span>,<span style="color: #666666">2</span>))
+    system<span style="color: #666666">.</span>draw()
+    drawing_tool<span style="color: #666666">.</span>display()
+
+    drawing_tool<span style="color: #666666">.</span>display(<span style="color: #BA2121">&#39;Axis&#39;</span>)
+</pre></div>
+
+<h2 id="___sec10">Distance with Text </h2>
+
+<p>
+The object <code>Distance_wText</code> is used to display an arrow, to indicate
+a distance in a sketch, with an additional text in the middle of the arrow.
+
+<p>
+The figure
+
+<p>
+<br />
+<br />
+
+<p>
+<center><p><img src="fig-tut/Distance_wText.png" align="bottom" width=500></p></center>
+
+<p>
+<br />
+<br />
+
+<p>
+was produced by this code:
+
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">test_Distance_wText</span>():
+    drawing_tool<span style="color: #666666">.</span>set_coordinate_system(
+        xmin<span style="color: #666666">=0</span>, xmax<span style="color: #666666">=10</span>, ymin<span style="color: #666666">=0</span>, ymax<span style="color: #666666">=6</span>,
+        axis<span style="color: #666666">=</span><span style="color: #008000">True</span>, instruction_file<span style="color: #666666">=</span><span style="color: #BA2121">&#39;tmp_Distance_wText.py&#39;</span>)
+
+    fontsize<span style="color: #666666">=14</span>
+    t <span style="color: #666666">=</span> <span style="color: #BA2121">r&#39;$ 2\pi R^2 $&#39;</span>  <span style="color: #408080; font-style: italic"># sample text</span>
+    examples <span style="color: #666666">=</span> Composition({
+        <span style="color: #BA2121">&#39;a0&#39;</span>: Distance_wText((<span style="color: #666666">4</span>,<span style="color: #666666">5</span>), (<span style="color: #666666">8</span>, <span style="color: #666666">5</span>), t, fontsize),
+        <span style="color: #BA2121">&#39;a6&#39;</span>: Distance_wText((<span style="color: #666666">4</span>,<span style="color: #666666">5</span>), (<span style="color: #666666">4</span>, <span style="color: #666666">4</span>), t, fontsize),
+        <span style="color: #BA2121">&#39;a1&#39;</span>: Distance_wText((<span style="color: #666666">0</span>,<span style="color: #666666">2</span>), (<span style="color: #666666">2</span>, <span style="color: #666666">4.5</span>), t, fontsize),
+        <span style="color: #BA2121">&#39;a2&#39;</span>: Distance_wText((<span style="color: #666666">0</span>,<span style="color: #666666">2</span>), (<span style="color: #666666">2</span>, <span style="color: #666666">0</span>), t, fontsize),
+        <span style="color: #BA2121">&#39;a3&#39;</span>: Distance_wText((<span style="color: #666666">2</span>,<span style="color: #666666">4.5</span>), (<span style="color: #666666">0</span>, <span style="color: #666666">5.5</span>), t, fontsize),
+        <span style="color: #BA2121">&#39;a4&#39;</span>: Distance_wText((<span style="color: #666666">8</span>,<span style="color: #666666">4</span>), (<span style="color: #666666">10</span>, <span style="color: #666666">3</span>), t, fontsize,
+                             text_spacing<span style="color: #666666">=-1./60</span>),
+        <span style="color: #BA2121">&#39;a5&#39;</span>: Distance_wText((<span style="color: #666666">8</span>,<span style="color: #666666">2</span>), (<span style="color: #666666">10</span>, <span style="color: #666666">1</span>), t, fontsize,
+                             text_spacing<span style="color: #666666">=-1./40</span>, alignment<span style="color: #666666">=</span><span style="color: #BA2121">&#39;right&#39;</span>),
+        <span style="color: #BA2121">&#39;c1&#39;</span>: Text_wArrow(<span style="color: #BA2121">&#39;text_spacing=-1./60&#39;</span>,
+                          (<span style="color: #666666">4</span>, <span style="color: #666666">3.5</span>), (<span style="color: #666666">9</span>, <span style="color: #666666">3.2</span>),
+                          fontsize<span style="color: #666666">=10</span>, alignment<span style="color: #666666">=</span><span style="color: #BA2121">&#39;left&#39;</span>),
+        <span style="color: #BA2121">&#39;c2&#39;</span>: Text_wArrow(<span style="color: #BA2121">&#39;text_spacing=-1./40, alignment=&quot;right&quot;&#39;</span>,
+                          (<span style="color: #666666">4</span>, <span style="color: #666666">0.5</span>), (<span style="color: #666666">9</span>, <span style="color: #666666">1.2</span>),
+                          fontsize<span style="color: #666666">=10</span>, alignment<span style="color: #666666">=</span><span style="color: #BA2121">&#39;left&#39;</span>),
+        })
+    examples<span style="color: #666666">.</span>draw()
+    drawing_tool<span style="color: #666666">.</span>display(<span style="color: #BA2121">&#39;Distance_wText and text positioning&#39;</span>)
+</pre></div>
+<p>
+Note the use of <code>Text_wArrow</code> to write an explaining text with an
+associated arrow, here used to explain how
+the <code>text_spacing</code> and <code>alignment</code> arguments can be used to adjust
+the appearance of the text that goes with the distance arrow.
+
+<h2 id="___sec11">Rectangle </h2>
+
+<p>
+<center><p><img src="fig-tut/Rectangle.png" align="bottom" width=500></p></center>
+
+<p>
+<br />
+<br />
+
+<p>
+The above figure can be produced by the following code.
+
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">test_Rectangle</span>():
+    L <span style="color: #666666">=</span> <span style="color: #666666">3.0</span>
+    W <span style="color: #666666">=</span> <span style="color: #666666">4.0</span>
+
+    drawing_tool<span style="color: #666666">.</span>set_coordinate_system(
+        xmin<span style="color: #666666">=0</span>, xmax<span style="color: #666666">=2*</span>W, ymin<span style="color: #666666">=-</span>L<span style="color: #666666">/2</span>, ymax<span style="color: #666666">=2*</span>L,
+        axis<span style="color: #666666">=</span><span style="color: #008000">True</span>, instruction_file<span style="color: #666666">=</span><span style="color: #BA2121">&#39;tmp_Rectangle.py&#39;</span>)
+    drawing_tool<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;blue&#39;</span>)
+    drawing_tool<span style="color: #666666">.</span>set_grid(<span style="color: #008000">True</span>)
+
+    xpos <span style="color: #666666">=</span> W<span style="color: #666666">/2</span>
+    r <span style="color: #666666">=</span> Rectangle(lower_left_corner<span style="color: #666666">=</span>(xpos,<span style="color: #666666">0</span>), width<span style="color: #666666">=</span>W, height<span style="color: #666666">=</span>L)
+    r<span style="color: #666666">.</span>draw()
+    r<span style="color: #666666">.</span>draw_dimensions()
+    drawing_tool<span style="color: #666666">.</span>display(<span style="color: #BA2121">&#39;Rectangle&#39;</span>)
+</pre></div>
+<p>
+The <code>draw_dimension</code> method adds explanation of dimensions and various
+important argument in the construction of a shape.
+
+<h2 id="___sec12">Triangle </h2>
+
+<p>
+<center><p><img src="fig-tut/Triangle.png" align="bottom" width=500></p></center>
+
+<p>
+<br />
+<br />
+
+<p>
+The code below produces the figure.
+
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">test_Triangle</span>():
+    L <span style="color: #666666">=</span> <span style="color: #666666">3.0</span>
+    W <span style="color: #666666">=</span> <span style="color: #666666">4.0</span>
+
+    drawing_tool<span style="color: #666666">.</span>set_coordinate_system(
+        xmin<span style="color: #666666">=0</span>, xmax<span style="color: #666666">=2*</span>W, ymin<span style="color: #666666">=-</span>L<span style="color: #666666">/2</span>, ymax<span style="color: #666666">=1.2*</span>L,
+        axis<span style="color: #666666">=</span><span style="color: #008000">True</span>, instruction_file<span style="color: #666666">=</span><span style="color: #BA2121">&#39;tmp_Triangle.py&#39;</span>)
+    drawing_tool<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;blue&#39;</span>)
+    drawing_tool<span style="color: #666666">.</span>set_grid(<span style="color: #008000">True</span>)
+
+    xpos <span style="color: #666666">=</span> <span style="color: #666666">1</span>
+    t <span style="color: #666666">=</span> Triangle(p1<span style="color: #666666">=</span>(W<span style="color: #666666">/2</span>,<span style="color: #666666">0</span>), p2<span style="color: #666666">=</span>(<span style="color: #666666">3*</span>W<span style="color: #666666">/2</span>,W<span style="color: #666666">/2</span>), p3<span style="color: #666666">=</span>(<span style="color: #666666">4*</span>W<span style="color: #666666">/5.</span>,L))
+    t<span style="color: #666666">.</span>draw()
+    t<span style="color: #666666">.</span>draw_dimensions()
+    drawing_tool<span style="color: #666666">.</span>display(<span style="color: #BA2121">&#39;Triangle&#39;</span>)
+</pre></div>
+<p>
+Here, the <code>draw_dimension</code> method writes the name of the corners at the
+position of the corners, which does not always look nice (the present figure
+is an example). For a high-quality sketch one would add some spacing
+to the location of the p1, p2, and even p3 texts.
+
+<h2 id="___sec13">Arc </h2>
+
+<p>
+<center><p><img src="fig-tut/Arc.png" align="bottom" width=400></p></center>
+
+<p>
+<br />
+<br />
+
+<p>
+An arc like the one above is produced by
+
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">test_Arc</span>():
+    L <span style="color: #666666">=</span> <span style="color: #666666">4.0</span>
+    W <span style="color: #666666">=</span> <span style="color: #666666">4.0</span>
+
+    drawing_tool<span style="color: #666666">.</span>set_coordinate_system(
+        xmin<span style="color: #666666">=-</span>W<span style="color: #666666">/2</span>, xmax<span style="color: #666666">=</span>W, ymin<span style="color: #666666">=-</span>L<span style="color: #666666">/2</span>, ymax<span style="color: #666666">=1.5*</span>L,
+        axis<span style="color: #666666">=</span><span style="color: #008000">True</span>, instruction_file<span style="color: #666666">=</span><span style="color: #BA2121">&#39;tmp_Arc.py&#39;</span>)
+    drawing_tool<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;blue&#39;</span>)
+    drawing_tool<span style="color: #666666">.</span>set_grid(<span style="color: #008000">True</span>)
+
+    center <span style="color: #666666">=</span> point(<span style="color: #666666">0</span>,<span style="color: #666666">0</span>)
+    radius <span style="color: #666666">=</span> L<span style="color: #666666">/2</span>
+    start_angle <span style="color: #666666">=</span> <span style="color: #666666">60</span>
+    arc_angle <span style="color: #666666">=</span> <span style="color: #666666">45</span>
+    a <span style="color: #666666">=</span> Arc(center, radius, start_angle, arc_angle)
+    a<span style="color: #666666">.</span>set_arrow(<span style="color: #BA2121">&#39;-&gt;&#39;</span>)
+    a<span style="color: #666666">.</span>draw()
+
+    R1 <span style="color: #666666">=</span> <span style="color: #666666">1.25*</span>radius
+    R2 <span style="color: #666666">=</span> <span style="color: #666666">1.5*</span>radius
+    R <span style="color: #666666">=</span> <span style="color: #666666">2*</span>radius
+    a<span style="color: #666666">.</span>dimensions <span style="color: #666666">=</span> {
+        <span style="color: #BA2121">&#39;start_angle&#39;</span>: Arc_wText(
+            <span style="color: #BA2121">&#39;start_angle&#39;</span>, center, R1, start_angle<span style="color: #666666">=0</span>,
+            arc_angle<span style="color: #666666">=</span>start_angle, text_spacing<span style="color: #666666">=1/10.</span>),
+        <span style="color: #BA2121">&#39;arc_angle&#39;</span>: Arc_wText(
+            <span style="color: #BA2121">&#39;arc_angle&#39;</span>, center, R2, start_angle<span style="color: #666666">=</span>start_angle,
+            arc_angle<span style="color: #666666">=</span>arc_angle, text_spacing<span style="color: #666666">=1/20.</span>),
+        <span style="color: #BA2121">&#39;r=0&#39;</span>: Line(center, center <span style="color: #666666">+</span>
+                    point(R<span style="color: #666666">*</span>cos(radians(start_angle)),
+                          R<span style="color: #666666">*</span>sin(radians(start_angle)))),
+        <span style="color: #BA2121">&#39;r=start_angle&#39;</span>: Line(center, center <span style="color: #666666">+</span>
+                              point(R<span style="color: #666666">*</span>cos(radians(start_angle<span style="color: #666666">+</span>arc_angle)),
+                                    R<span style="color: #666666">*</span>sin(radians(start_angle<span style="color: #666666">+</span>arc_angle)))),
+        <span style="color: #BA2121">&#39;r=start+arc_angle&#39;</span>:  Line(center, center <span style="color: #666666">+</span>
+                                   point(R, <span style="color: #666666">0</span>))<span style="color: #666666">.</span>set_linestyle(<span style="color: #BA2121">&#39;dashed&#39;</span>),
+        <span style="color: #BA2121">&#39;radius&#39;</span>: Distance_wText(center, a(<span style="color: #666666">0</span>), <span style="color: #BA2121">&#39;radius&#39;</span>, text_spacing<span style="color: #666666">=1/40.</span>),
+        <span style="color: #BA2121">&#39;center&#39;</span>: Text(<span style="color: #BA2121">&#39;center&#39;</span>, center<span style="color: #666666">-</span>point(radius<span style="color: #666666">/10.</span>, radius<span style="color: #666666">/10.</span>)),
+        }
+    <span style="color: #008000; font-weight: bold">for</span> dimension <span style="color: #AA22FF; font-weight: bold">in</span> a<span style="color: #666666">.</span>dimensions:
+        dim <span style="color: #666666">=</span> a<span style="color: #666666">.</span>dimensions[dimension]
+        dim<span style="color: #666666">.</span>set_linestyle(<span style="color: #BA2121">&#39;dashed&#39;</span>)
+        dim<span style="color: #666666">.</span>set_linewidth(<span style="color: #666666">1</span>)
+        dim<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;black&#39;</span>)
+
+    a<span style="color: #666666">.</span>draw_dimensions()
+    drawing_tool<span style="color: #666666">.</span>display(<span style="color: #BA2121">&#39;Arc&#39;</span>)
+</pre></div>
+
+<h2 id="___sec14">Spring </h2>
+
+<p>
+<center><p><img src="fig-tut/Spring.png" align="bottom" width=800></p></center>
+
+<p>
+<br />
+<br />
+
+<p>
+The code for making this spring is
+
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">test_Spring</span>():
+    L <span style="color: #666666">=</span> <span style="color: #666666">5.0</span>
+    W <span style="color: #666666">=</span> <span style="color: #666666">2.0</span>
+
+    drawing_tool<span style="color: #666666">.</span>set_coordinate_system(
+        xmin<span style="color: #666666">=0</span>, xmax<span style="color: #666666">=7*</span>W, ymin<span style="color: #666666">=-</span>L<span style="color: #666666">/2</span>, ymax<span style="color: #666666">=1.5*</span>L,
+        axis<span style="color: #666666">=</span><span style="color: #008000">True</span>, instruction_file<span style="color: #666666">=</span><span style="color: #BA2121">&#39;tmp_Spring.py&#39;</span>)
+    drawing_tool<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;blue&#39;</span>)
+    drawing_tool<span style="color: #666666">.</span>set_grid(<span style="color: #008000">True</span>)
+
+    xpos <span style="color: #666666">=</span> W
+    s1 <span style="color: #666666">=</span> Spring((W,<span style="color: #666666">0</span>), L, teeth<span style="color: #666666">=</span><span style="color: #008000">True</span>)
+    s1_title <span style="color: #666666">=</span> Text(<span style="color: #BA2121">&#39;Default Spring&#39;</span>,
+                    s1<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">&#39;end&#39;</span>] <span style="color: #666666">+</span> point(<span style="color: #666666">0</span>,L<span style="color: #666666">/10</span>))
+    s1<span style="color: #666666">.</span>draw()
+    s1_title<span style="color: #666666">.</span>draw()
+    <span style="color: #408080; font-style: italic">#s1.draw_dimensions()</span>
+    xpos <span style="color: #666666">+=</span> <span style="color: #666666">3*</span>W
+    s2 <span style="color: #666666">=</span> Spring(start<span style="color: #666666">=</span>(xpos,<span style="color: #666666">0</span>), length<span style="color: #666666">=</span>L, width<span style="color: #666666">=</span>W<span style="color: #666666">/2.</span>,
+                bar_length<span style="color: #666666">=</span>L<span style="color: #666666">/6.</span>, teeth<span style="color: #666666">=</span><span style="color: #008000">False</span>)
+    s2<span style="color: #666666">.</span>draw()
+    s2<span style="color: #666666">.</span>draw_dimensions()
+    drawing_tool<span style="color: #666666">.</span>display(<span style="color: #BA2121">&#39;Spring&#39;</span>)
+</pre></div>
+
+<h2 id="___sec15">Dashpot </h2>
+
+<p>
+<center><p><img src="fig-tut/Dashpot.png" align="bottom" width=600></p></center>
+
+<p>
+<br />
+<br />
+
+<p>
+This dashpot is produced by
+
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">test_Dashpot</span>():
+    L <span style="color: #666666">=</span> <span style="color: #666666">5.0</span>
+    W <span style="color: #666666">=</span> <span style="color: #666666">2.0</span>
+    xpos <span style="color: #666666">=</span> <span style="color: #666666">0</span>
+
+    drawing_tool<span style="color: #666666">.</span>set_coordinate_system(
+        xmin<span style="color: #666666">=</span>xpos, xmax<span style="color: #666666">=</span>xpos<span style="color: #666666">+5.5*</span>W, ymin<span style="color: #666666">=-</span>L<span style="color: #666666">/2</span>, ymax<span style="color: #666666">=1.5*</span>L,
+        axis<span style="color: #666666">=</span><span style="color: #008000">True</span>, instruction_file<span style="color: #666666">=</span><span style="color: #BA2121">&#39;tmp_Dashpot.py&#39;</span>)
+    drawing_tool<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">&#39;blue&#39;</span>)
+    drawing_tool<span style="color: #666666">.</span>set_grid(<span style="color: #008000">True</span>)
+
+    <span style="color: #408080; font-style: italic"># Default (simple) dashpot</span>
+    xpos <span style="color: #666666">=</span> <span style="color: #666666">1.5</span>
+    d1 <span style="color: #666666">=</span> Dashpot(start<span style="color: #666666">=</span>(xpos,<span style="color: #666666">0</span>), total_length<span style="color: #666666">=</span>L)
+    d1_title <span style="color: #666666">=</span> Text(<span style="color: #BA2121">&#39;Dashpot (default)&#39;</span>,
+                    d1<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">&#39;end&#39;</span>] <span style="color: #666666">+</span> point(<span style="color: #666666">0</span>,L<span style="color: #666666">/10</span>))
+    d1<span style="color: #666666">.</span>draw()
+    d1_title<span style="color: #666666">.</span>draw()
+
+    <span style="color: #408080; font-style: italic"># Dashpot for animation with fixed bar_length, dashpot_length and</span>
+    <span style="color: #408080; font-style: italic"># prescribed piston_pos</span>
+    xpos <span style="color: #666666">+=</span> <span style="color: #666666">2.5*</span>W
+    d2 <span style="color: #666666">=</span> Dashpot(start<span style="color: #666666">=</span>(xpos,<span style="color: #666666">0</span>), total_length<span style="color: #666666">=1.2*</span>L, width<span style="color: #666666">=</span>W<span style="color: #666666">/2</span>,
+                 bar_length<span style="color: #666666">=</span>W, dashpot_length<span style="color: #666666">=</span>L<span style="color: #666666">/2</span>, piston_pos<span style="color: #666666">=2*</span>W)
+    d2<span style="color: #666666">.</span>draw()
+    d2<span style="color: #666666">.</span>draw_dimensions()
+
+    drawing_tool<span style="color: #666666">.</span>display(<span style="color: #BA2121">&#39;Dashpot&#39;</span>)
+</pre></div>
+
+<h2 id="___sec16">Wavy </h2>
+
+<p>
+Looks strange. Fix x axis.
+
+<h2 id="___sec17">Stochastic curves </h2>
+
+<p>
+The <code>StochasticWavyCurve</code> object offers three precomputed
+graphics that have a random variation:
+
+<p>
+<br />
+<br />
+
+<p>
+<center><p><img src="fig-tut/StochasticWavyCurve.png" align="bottom" width=600></p></center>
+
+<p>
+<br />
+<br />
+
+<p>
+The usage is simple. The construction
+
+<p>
+
+<!-- code=python (!bc pycod) typeset with pygments style "default" -->
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">curve <span style="color: #666666">=</span> StochasticWavyCurve(curve_no<span style="color: #666666">=1</span>, percentage<span style="color: #666666">=40</span>)
+</pre></div>
+<p>
+picks the second curve (the three are numbered 0, 1, and 2),
+and the first 40% of that curve. In case one desires another extent
+of the axis, one can just scale the coordinates directly as these
+are stored in the arrays <code>curve.x[curve_no]</code> and
+<code>curve.y[curve_no]</code>.
+
+<p>
+<p>
+<!-- begin bottom navigation -->
+<table style="width: 100%"><tr><td>
+<div style="text-align: left;"><a href="._pysketcher001.html"><img src="http://hplgit.github.io/doconce/bundled/html_images/prev1.png" border=0 alt="&laquo; Previous"></a></div>
+</td><td>
+<div style="text-align: right;"><a href="._pysketcher003.html"><img src="http://hplgit.github.io/doconce/bundled/html_images/next1.png" border=0 alt="Next &raquo;"></a></div>
+</td></tr></table>
+<!-- end bottom navigation -->
+</p>
+
+<!-- ------------------- end of main content --------------- -->
+
+
+</body>
+</html>
+    
+

File diff suppressed because it is too large
+ 896 - 0
doc/pub/tutorial/._pysketcher003.html


+ 8 - 8
doc/pub/tutorial/html/genindex.html

@@ -53,14 +53,14 @@
 <![endif]-->
 
   
-   <style type="text/css">
-     div.admonition {
-       background-color: whiteSmoke;
-       border: 1px solid #bababa;
-     }
-   </style>
-  </head>
-
+       <style type="text/css">
+         div.admonition {
+           background-color: whiteSmoke;
+           border: 1px solid #bababa;
+         }
+       </style>
+      </head>
+    
   <body>
 
     <div class="related">

+ 8 - 8
doc/pub/tutorial/html/index.html

@@ -52,14 +52,14 @@
 <![endif]-->
 
   
-   <style type="text/css">
-     div.admonition {
-       background-color: whiteSmoke;
-       border: 1px solid #bababa;
-     }
-   </style>
-  </head>
-
+       <style type="text/css">
+         div.admonition {
+           background-color: whiteSmoke;
+           border: 1px solid #bababa;
+         }
+       </style>
+      </head>
+    
   <body>
 
     <div class="related">

BIN
doc/pub/tutorial/html/objects.inv


+ 8 - 8
doc/pub/tutorial/html/search.html

@@ -57,14 +57,14 @@
 
 
   
-   <style type="text/css">
-     div.admonition {
-       background-color: whiteSmoke;
-       border: 1px solid #bababa;
-     }
-   </style>
-  </head>
-
+       <style type="text/css">
+         div.admonition {
+           background-color: whiteSmoke;
+           border: 1px solid #bababa;
+         }
+       </style>
+      </head>
+    
   <body>
 
     <div class="related">

File diff suppressed because it is too large
+ 1 - 1
doc/pub/tutorial/html/searchindex.js


+ 197 - 0
doc/pub/tutorial/pysketcher.html

@@ -0,0 +1,197 @@
+<!--
+Automatically generated HTML file from DocOnce source
+(https://github.com/hplgit/doconce/)
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="DocOnce: https://github.com/hplgit/doconce/" />
+<meta name="description" content="Using Pysketcher to Create Principal Sketches of Physics Problems">
+<meta name="keywords" content="tree data structure,recursive function calls">
+
+<title>Using Pysketcher to Create Principal Sketches of Physics Problems</title>
+
+
+<style type="text/css">
+/* blueish style */
+
+/* Color definitions:  http://www.december.com/html/spec/color0.html
+   CSS examples:       http://www.w3schools.com/css/css_examples.asp */
+
+body {
+  margin-top: 1.0em;
+  background-color: #ffffff;
+  font-family: Helvetica, Arial, FreeSans, san-serif;
+  color: #000000;
+}
+h1 { font-size: 1.8em; color: #1e36ce; }
+h2 { font-size: 1.6em; color: #1e36ce; }
+h3 { font-size: 1.4em; color: #1e36ce; }
+a { color: #1e36ce; text-decoration:none; }
+tt { font-family: "Courier New", Courier; }
+/* pre style removed because it will interfer with pygments */
+p { text-indent: 0px; }
+hr { border: 0; width: 80%; border-bottom: 1px solid #aaa}
+p.caption { width: 80%; font-style: normal; text-align: left; }
+hr.figure { border: 0; width: 80%; border-bottom: 1px solid #aaa}
+
+div { text-align: justify; text-justify: inter-word; }
+</style>
+
+
+</head>
+
+<!-- tocinfo
+{'highest level': 1,
+ 'sections': [(' A First Glimpse of Pysketcher ', 1, None, '___sec0'),
+              (' Basic Construction of Sketches ', 2, None, '___sec1'),
+              (' Basic Drawing ', 3, None, '___sec2'),
+              (' Groups of Objects ', 3, None, '___sec3'),
+              (' Changing Line Styles and Colors ', 3, None, '___sec4'),
+              (' The Figure Composition as an Object Hierarchy ',
+               3,
+               None,
+               '___sec5'),
+              (' Animation: Translating the Vehicle ', 3, None, '___sec6'),
+              (' Animation: Rolling the Wheels ',
+               3,
+               'sketcher:vehicle1:anim',
+               'sketcher:vehicle1:anim'),
+              (' Basic Shapes ', 1, None, '___sec8'),
+              (' Axis ', 2, None, '___sec9'),
+              (' Distance with Text ', 2, None, '___sec10'),
+              (' Rectangle ', 2, None, '___sec11'),
+              (' Triangle ', 2, None, '___sec12'),
+              (' Arc ', 2, None, '___sec13'),
+              (' Spring ', 2, None, '___sec14'),
+              (' Dashpot ', 2, None, '___sec15'),
+              (' Wavy ', 2, None, '___sec16'),
+              (' Stochastic curves ', 2, None, '___sec17'),
+              (' Inner Workings of the Pysketcher Tool ',
+               1,
+               None,
+               '___sec18'),
+              (' Example of Classes for Geometric Objects ',
+               2,
+               None,
+               '___sec19'),
+              (' Simple Geometric Objects ', 3, None, '___sec20'),
+              (' Class Curve ', 3, None, '___sec21'),
+              (' Compound Geometric Objects ', 3, None, '___sec22'),
+              (' Adding Functionality via Recursion ', 2, None, '___sec23'),
+              (' Basic Principles of Recursion ', 3, None, '___sec24'),
+              (' Explaining Recursion ', 3, None, '___sec25'),
+              (' Scaling, Translating, and Rotating a Figure ',
+               2,
+               'sketcher:scaling',
+               'sketcher:scaling'),
+              (' Scaling ', 3, None, '___sec27'),
+              (' Translation ', 3, None, '___sec28'),
+              (' Rotation ', 3, None, '___sec29')]}
+end of tocinfo -->
+
+<body>
+
+
+
+<script type="text/x-mathjax-config">
+MathJax.Hub.Config({
+  TeX: {
+     equationNumbers: {  autoNumber: "none"  },
+     extensions: ["AMSmath.js", "AMSsymbols.js", "autobold.js", "color.js"]
+  }
+});
+</script>
+<script type="text/javascript"
+ src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
+</script>
+
+
+
+    
+<a name="part0000"></a>
+<p>
+<!-- begin top navigation -->
+<table style="width: 100%"><tr><td>
+</td><td>
+<div style="text-align: right;"><a href="._pysketcher001.html"><img src="http://hplgit.github.io/doconce/bundled/html_images/next1.png" border=0 alt="Next &raquo;"></a></div>
+</td></tr></table>
+<!-- end top navigation -->
+</p>
+
+<p>
+<!-- ------------------- main content ---------------------- -->
+
+
+
+<center><h1>Using Pysketcher to Create Principal Sketches of Physics Problems</h1></center>  <!-- document title -->
+
+<p>
+<!-- author(s): Hans Petter Langtangen -->
+
+<center>
+<b>Hans Petter Langtangen</b> [1, 2]
+</center>
+
+<p>
+<!-- institution(s) -->
+
+<center>[1] <b>Center for Biomedical Computing, Simula Research Laboratory</b></center>
+<center>[2] <b>Department of Informatics, University of Oslo</b></center>
+<p>
+<center><h4>Apr 27, 2015</h4></center> <!-- date -->
+<p>
+
+<!-- begin box -->
+<div style="width: 95%; padding: 10px; border: 1px solid #000; border-radius: 4px;">
+This document is derived from Chapter 9 in the book
+<a href="http://www.amazon.com/Scientific-Programming-Computational-Science-Engineering/dp/3642549586/ref=sr_1_2?s=books&ie=UTF8&qid=1407225588&sr=1-2&keywords=langtangen" target="_self">A Primer on Scientific Programming with Python</a>, by H. P. Langtangen,
+4th edition, Springer, 2014.
+</div>
+<!-- end box -->
+
+
+<p>
+<b>Abstract.</b> Pysketcher is a Python package which allows principal sketches of
+physics and mechanics problems to be realized through short programs
+instead of interactive (and potentially tedious and inaccurate)
+drawing.  Elements of the sketch, such as lines, circles, angles,
+forces, coordinate systems, etc., are realized as objects and
+collected in hierarchical structures. Parts of the hierarchical
+structures can easily change line styles and colors, or be copied,
+scaled, translated, and rotated. These features make it
+straightforward to move parts of the sketch to create animation,
+usually in accordance with the physics of the underlying problem.
+Exact dimensioning of the elements in the sketch is trivial to obtain
+since distances are specified in computer code.
+
+<p>
+Pysketcher is easy to learn from a number of examples. Beyond
+essential Python programming and a knowledge about mechanics problems,
+no further background is required.
+
+<p>
+<!-- Task (can be questions): make sketches of physical problems, see fig -->
+<!-- through user-friendly composition of basic shapes -->
+<!-- Desired knowledge: plotting curves, basic OO (ch. X.Y, ...) -->
+<!-- Required knowledge? -->
+<!-- Learning Goals: these targets the inner workings of pysketcher, -->
+<!-- which is just a part of this document... -->
+
+<p>
+<p>
+<!-- begin bottom navigation -->
+<table style="width: 100%"><tr><td>
+</td><td>
+<div style="text-align: right;"><a href="._pysketcher001.html"><img src="http://hplgit.github.io/doconce/bundled/html_images/next1.png" border=0 alt="Next &raquo;"></a></div>
+</td></tr></table>
+<!-- end bottom navigation -->
+</p>
+
+<!-- ------------------- end of main content --------------- -->
+
+
+</body>
+</html>
+    
+

BIN
doc/pub/tutorial/pysketcher.pdf


+ 21 - 0
doc/src/tut/basics.do.txt

@@ -80,11 +80,32 @@ several elements: two circles, two rectangles, and a ``ground'' element.
 
 FIGURE: [fig-tut/vehicle0_dim, width=600] Sketch of a simple figure. label{sketcher:fig:vehicle0}
 
+When the sketch is defined in terms of computer code, it is natural to
+parameterize geometric features, such as the radius of the wheel ($R$),
+the center point of the left wheel ($w_1$), as well as the height ($H$) and
+length ($L$) of the main part. The simple vehicle in
+Figure ref{sketcher:fig:vehicle0} is quickly drawn in almost any interactive
+tool. However, if we want to change the radius of the wheels, you need a
+sophisticated drawing tool to avoid redrawing the whole figure, while
+in computer code this is a matter of changing the $R$ parameter and
+rerunning the program.
+For example, Figure ref{sketcher:fig:vehicle0b} shows
+a variation of the drawing in
+Figure ref{sketcher:fig:vehicle0} obtained by just setting
+$R=0.5$, $L=5$, $H=2$, and $R=2$. Being able
+to quickly change geometric sizes is key to many problem settings in
+physics and engineering, but then a program must define the geometry.
+
+
+FIGURE: [fig-tut/vehicle_v2, width=500 frac=0.6] Redrawing a figure with other geometric parameters. label{sketcher:fig:vehicle0b}
+
+
 === Basic Drawing ===
 
 A typical program creating these five elements is shown next.
 After importing the `pysketcher` package, the first task is always to
 define a coordinate system:
+
 !bc pycod
 from pysketcher import *
 

+ 43 - 3
doc/src/tut/classes.do.txt

@@ -1,5 +1,12 @@
 ======= Basic Shapes =======
 
+This section presents many of the basic shapes in Pysketcher:
+`Axis`, `Distance_wText`, `Rectangle`, 	`Triangle`, `Arc`,
+`Spring`, `Dashpot`, and `Wavy`.
+Each shape is demonstrated with a figure and a
+unit test that shows how the figure is constructed in Python code.
+
+
 ===== Axis =====
 
 The `Axis` object gives the possibility draw a single axis to
@@ -7,8 +14,14 @@ notify a coordinate system. Here is an example where we
 draw $x$ and $y$ axis of three coordinate systems of different
 rotation:
 
+<linebreak>
+<linebreak>
+
 FIGURE: [fig-tut/Axis, width=500 frac=0.7]
 
+<linebreak>
+<linebreak>
+
 The corresponding code looks like this:
 
 @@@CODE ../../../pysketcher/shapes.py fromto: def test_Axis@drawing_tool.savefig\('tmp_Axis'\)
@@ -20,8 +33,16 @@ a distance in a sketch, with an additional text in the middle of the arrow.
 
 The figure
 
+
+<linebreak>
+<linebreak>
+
 FIGURE: [fig-tut/Distance_wText, width=500 frac=0.7]
 
+<linebreak>
+<linebreak>
+
+
 was produced by this code:
 
 @@@CODE ../../../pysketcher/shapes.py fromto: def test_Distance_wText@drawing_tool.savefig\('tmp_Distance
@@ -34,6 +55,9 @@ the appearance of the text that goes with the distance arrow.
 
 FIGURE: [fig-tut/Rectangle, width=500 frac=0.7]
 
+<linebreak>
+<linebreak>
+
 The above figure can be produced by the following code.
 
 @@@CODE ../../../pysketcher/shapes.py fromto: def test_Rectangle@drawing_tool.savefig\('tmp_Rectangle
@@ -45,6 +69,9 @@ important argument in the construction of a shape.
 
 FIGURE: [fig-tut/Triangle, width=500 frac=0.7]
 
+<linebreak>
+<linebreak>
+
 The code below produces the figure.
 
 @@@CODE ../../../pysketcher/shapes.py fromto: def test_Triangle@drawing_tool.savefig\('tmp_Triangle
@@ -55,11 +82,12 @@ to the location of the p1, p2, and even p3 texts.
 
 ===== Arc =====
 
-An arc like
-
 FIGURE: [fig-tut/Arc, width=400 frac=0.5]
 
-is produced by
+<linebreak>
+<linebreak>
+
+An arc like the one above is produced by
 
 @@@CODE ../../../pysketcher/shapes.py fromto: def test_Arc@drawing_tool.savefig\('tmp_Arc
 
@@ -67,6 +95,9 @@ is produced by
 
 FIGURE: [fig-tut/Spring, width=800 frac=1]
 
+<linebreak>
+<linebreak>
+
 The code for making this spring is
 
 @@@CODE ../../../pysketcher/shapes.py fromto: def test_Spring@drawing_tool.savefig\('tmp_Spring
@@ -75,6 +106,9 @@ The code for making this spring is
 
 FIGURE: [fig-tut/Dashpot, width=600 frac=0.8]
 
+<linebreak>
+<linebreak>
+
 This dashpot is produced by
 
 @@@CODE ../../../pysketcher/shapes.py fromto: def test_Dashpot@drawing_tool.savefig\('tmp_Dashpot
@@ -88,8 +122,14 @@ Looks strange. Fix x axis.
 The `StochasticWavyCurve` object offers three precomputed
 graphics that have a random variation:
 
+<linebreak>
+<linebreak>
+
 FIGURE: [fig-tut/StochasticWavyCurve.png, width=600 frac=1]
 
+<linebreak>
+<linebreak>
+
 The usage is simple. The construction
 
 !bc pycod

BIN
doc/src/tut/fig-tut/vehicle_v1.pdf


BIN
doc/src/tut/fig-tut/vehicle_v1.png


BIN
doc/src/tut/fig-tut/vehicle_v2.pdf


BIN
doc/src/tut/fig-tut/vehicle_v2.png


BIN
doc/src/tut/fig-tut/vehicle_v23.pdf


BIN
doc/src/tut/fig-tut/vehicle_v23.png


BIN
doc/src/tut/fig-tut/vehicle_v3.pdf


BIN
doc/src/tut/fig-tut/vehicle_v3.png


+ 3 - 0
doc/src/tut/main_sketcher.do.txt

@@ -41,8 +41,11 @@ no further background is required.
 # Learning Goals: these targets the inner workings of pysketcher,
 # which is just a part of this document...
 
+!split
 # #include "basics.do.txt"
 
+!split
 # #include "classes.do.txt"
 
+!split
 # #include "implementation.do.txt"

+ 19 - 13
doc/src/tut/make.sh

@@ -7,23 +7,29 @@ if [ $? -ne 0 ]; then
   exit 1
 fi
 
-main=main_sketcher
-doconce format html $main
+name=main_sketcher
+doconce format html $name
 
-cp .ptex2tex.cfg-minted .ptex2tex.cfg
-doconce format pdflatex $main --skip_inline_comments
-ptex2tex -DMINTED $main
-pdflatex -shell-escape $main
-makeindex $main
-pdflatex -shell-escape $main
-pdflatex -shell-escape $main
+#cp .ptex2tex.cfg-minted .ptex2tex.cfg
+doconce format pdflatex $name --skip_inline_comments --latex_code_style=pyg
+#ptex2tex -DMINTED $name
+pdflatex -shell-escape $name
+makeindex $name
+pdflatex -shell-escape $name
+pdflatex -shell-escape $name
+cp $name.pdf pysketcher.pdf
 
-doconce format sphinx $main --skip_inline_comments
-doconce sphinx_dir author="H. P. Langtangen" version=0.1 theme=pyramid $main
+html=pysketcher
+doconce format html $name --skip_inline_comments --html_style=boostrap_bluegray --html_output=$html
+doconce split_html ${html}.html
+
+doconce format sphinx $name --skip_inline_comments
+doconce sphinx_dir author="H. P. Langtangen" version=0.1 theme=pyramid $name
 python automake_sphinx.py
 
+# Publish
 dest=../../pub/tutorial
-cp ${main}.pdf $dest/pysketcher.pdf
-#cp $main.html ../../tutorial/pysketcher.html
+name=pysketcher
+cp ${name}.html ._${name}*.html ${name}.pdf $dest/
 rm -rf $dest/html
 cp -r sphinx-rootdir/_build/html $dest/html

+ 10 - 0
doc/src/tut/src-tut/README.txt

@@ -0,0 +1,10 @@
+vehicle0.py: draw vehicle, change colors, let it move
+
+vehicle0_dim.py: draw vehicle and add dimensions used in the sketch
+
+vehicle0_scaling.py: example on how to easily make different vehicles
+from the same code
+
+vehicle1.py: as vehicle0.py, but rolling wheels
+
+vehicle2.py: how to make the vehicle drawing a shape in the Shape hierarchy

+ 42 - 0
doc/src/tut/src-tut/vehicle0_scaling.py

@@ -0,0 +1,42 @@
+from pysketcher import *
+
+def draw_vehicle(
+    R=1,    # radius of wheel
+    L=4,    # distance between wheels
+    H=2,    # height of vehicle body
+    w_1=5,  # position of front wheel
+    ):
+
+    xmax = w_1 + 2*L + 3*R
+    drawing_tool.set_coordinate_system(xmin=0, xmax=xmax,
+                                       ymin=-1, ymax=2*R + 3*H,
+                                       axis=False)
+
+    wheel1 = Circle(center=(w_1, R), radius=R)
+    wheel2 = wheel1.copy()
+    wheel2.translate((L,0))
+
+    under = Rectangle(lower_left_corner=(w_1-2*R, 2*R),
+                      width=2*R + L + 2*R, height=H)
+    over  = Rectangle(lower_left_corner=(w_1, 2*R + H),
+                      width=2.5*R, height=1.25*H)
+
+    wheels = Composition({'wheel1': wheel1, 'wheel2': wheel2})
+    body = Composition({'under': under, 'over': over})
+
+    vehicle = Composition({'wheels': wheels, 'body': body})
+    ground = Wall(x=[R, xmax], y=[0, 0], thickness=-0.3*R)
+
+    fig = Composition({'vehicle': vehicle, 'ground': ground})
+    return fig
+
+#fig = draw_vehicle(R=1, L=4, H=2, w_1=8)
+#fig = draw_vehicle(R=0.5, L=5, H=2, w_1=8)
+fig = draw_vehicle(R=2, L=7, H=1, w_1=10)
+fig.draw()  # send all figures to plotting backend
+
+drawing_tool.display()
+drawing_tool.savefig('tmp1.png')
+drawing_tool.savefig('tmp1.pdf')
+
+raw_input()

BIN
examples/FE_comic_strip.pdf


BIN
examples/FE_comic_strip.png


BIN
examples/FE_noncomic_strip.pdf


BIN
examples/FE_noncomic_strip.png


+ 88 - 0
examples/ForwardEuler.py

@@ -0,0 +1,88 @@
+"""Comic strip for illustrating Euler's method for ODEs."""
+
+from pysketcher import *
+import numpy as np
+xkcd = True
+
+xmin = 0
+drawing_tool.set_coordinate_system(xmin=xmin, xmax=4,
+                                   ymin=0, ymax=2.5,
+                                   axis=True, xkcd=xkcd)
+drawing_tool.set_linecolor('blue')
+
+def ForwardEuler(I, a, T, dt):
+    u = [I]
+    t = [0]
+    while t[-1] <= T:
+        u_new = u[-1] - a*dt*u[-1]
+        u.append(u_new)
+        t.append(t[-1] + dt)
+    return np.array(u), np.array(t)
+
+def make_fig(dt=0.5, heading=''):
+    I = 2
+    a = 0.5
+    T_e = 3
+    T_FE = 1
+    t_fine = np.linspace(0, T_e, 101)
+    u_e = I*np.exp(-a*t_fine)
+
+    u, t = ForwardEuler(I, a, T_FE, dt)
+
+    # y = slope*(x - x0) + y0
+    # u_extrapolated = -a*u[-1]*(t - t[-1]) + u[-1]
+    t_future = t[-1] + 1.5   # let the line be longer than one step
+    line = Line((t[-1], u[-1]), (t_future, -a*u[-1]*(t_future - t[-1]) + u[-1]))
+
+    circles = {
+        i: Circle((t[i], u[i]), 0.05).set_linecolor('red').set_filled_curves('red')
+        for i in range(1, len(u))}
+    # Add next predicted point
+    t_next = t[-1] + dt
+    u_next = -a*u[-1]*(t_next - t[-1]) + u[-1]
+    circles[0] = Circle((t_next, u_next), 0.05).\
+                 set_linecolor('red').set_filled_curves('red')
+    circles = Composition(circles)
+
+    curves = Composition(dict(
+        exact=Curve(t_fine, u_e).set_linestyle('dashed'),
+        numerical=Curve(t, u),
+        extrapolation=line.set_linecolor('red').set_linewidth(3)))
+
+    text_exact = Text_wArrow("exact solution", (2.5, 1), (2.5, I*np.exp(-a*2.5)),
+                             alignment='left')
+
+    text_predict = Text_wArrow("Here we know the slope:\n$u'=f(u,t)$!\nLet the solution continue\nalong that slope.",
+                               (1.7, 1.7), (t[-1], u[-1]),
+                               alignment='left')
+    text_next = Text_wArrow("This is the next\npredicted point",
+                            (1, 0.25), (t_next, u_next),
+                            alignment='left')
+
+    text_comment = Text(heading, (0.3, 2.05), alignment='left')
+
+    fig = Composition(dict(curves=curves,
+                           circles=circles,
+                           exact=text_exact,
+                           predict=text_predict,
+                           next=text_next,
+                           comment=text_comment))
+    return fig
+
+fig = make_fig(dt=0.5, heading="Differential equations $u'=f(u,t)$\nare hard to solve,\nbut not with programming!")
+fig.draw()
+drawing_tool.display()
+drawing_tool.savefig('tmp1')
+
+drawing_tool.erase()
+fig = make_fig(dt=0.24, heading='Just reduce the time step\nto make more accurate\npredictions!')
+fig.draw()
+drawing_tool.display()
+drawing_tool.savefig('tmp2')
+
+import os
+comic = 'comic' if xkcd else 'non_comic'
+os.system('doconce combine_images pdf -2 tmp1 tmp2 FE_%s_strip' % comic)
+os.system('doconce combine_images png -2 tmp1 tmp2 FE_%s_strip' % comic)
+
+raw_input()

+ 11 - 11
examples/beam2.py

@@ -45,22 +45,22 @@ M1.set_linecolor('black')
 ab_level = point(0, 3*h)
 a_dim = Distance_wText(A - ab_level, B - ab_level, '$a$')
 b_dim = Distance_wText(B - ab_level, C - ab_level, '$b$')
-dims = Compose({'a': a_dim, 'b': b_dim})
-symbols = Compose({'R1': R1, 'R2': R2, 'M1': M1,
-                   'w': load, 'w text': load_text,
-                   'A': Text('$A$', A+point(0.7*h,-0.9*h)),
-                   'B': Text('$B$', support.mid_support-point(h,0)),
-                   'C': Text('$C$', C+point(h/2,-h/2))})
+dims = Composition({'a': a_dim, 'b': b_dim})
+symbols = Composition({'R1': R1, 'R2': R2, 'M1': M1,
+                       'w': load, 'w text': load_text,
+                       'A': Text('$A$', A+point(0.7*h,-0.9*h)),
+                       'B': Text('$B$', support.mid_support-point(h,0)),
+                       'C': Text('$C$', C+point(h/2,-h/2))})
 
 x_axis = Axis(A + point(L+h, H/2), 2*H, '$x$',).set_linecolor('black')
 y_axis = Axis(A + point(0,H/2), 3.5*H, '$y$',
               below=False, rotation_angle=90).set_linecolor('black')
-axes = Compose({'x axis': x_axis, 'y axis': y_axis})
+axes = Composition({'x axis': x_axis, 'y axis': y_axis})
 
-annotations = Compose({'dims': dims, 'symbols': symbols,
-                'axes': axes})
-fig = Compose({'beam': beam, 'support': support,
-               'clamped end': clamped, 'load': load})
+annotations = Composition({'dims': dims, 'symbols': symbols,
+                           'axes': axes})
+fig = Composition({'beam': beam, 'support': support,
+                   'clamped end': clamped, 'load': load})
 
 def deflection(x, a, b, w):
     import numpy as np

+ 87 - 0
examples/integral.py

@@ -0,0 +1,87 @@
+"""Comic strip for illustrating numerical integration."""
+
+from pysketcher import *
+xdcd = True
+
+def f(x):
+    return 3*np.exp(-x**4)
+
+xmin = -2
+drawing_tool.set_coordinate_system(xmin=xmin, xmax=4,
+                                   ymin=0, ymax=4,
+                                   axis=True, xkcd=xkcd)
+drawing_tool.set_linecolor('blue')
+
+import numpy as np
+x = np.linspace(xmin, 3, 201)
+y = f(x)
+curve = Curve(x, y)
+
+x2 = np.linspace(xmin, 0.2, 201)
+y2 = f(x2)
+x2 = x2.tolist()
+y2 = y2.tolist()
+x2.append(x2[-1])
+y2.append(0)
+x2.append(xmin)
+y2.append(0)
+#x2 = np.array(x2)
+#y2 = np.array(y2)
+filled = Curve(x2, y2).set_filled_curves(pattern='/')
+
+text1 = Text_wArrow('The integral $\int_{-\infty}^{0.2} 3e^{-x^4}dx$\nis impossible to calculate\nby hand but so easy with\na program!', (1.5, 3.5), (-0.2, 1), alignment='left')
+
+fig = Composition(dict(curve=curve, integral=filled, comment=text1))
+fig.draw()
+drawing_tool.display()
+drawing_tool.savefig('tmp1')
+
+#raw_input()
+
+# Draw piecewise curve for midpoint rule
+def piecewise_curve_for_midpoint_rule(N):
+    dx = (0.2 - xmin)/float(N)
+    x3_double = []
+    y3_double = []
+    y_prev = 0
+    for i in range(N):
+        x = xmin + i*dx
+        x3_double.append(x)
+        y3_double.append(y_prev)
+        x3_double.append(x)
+        y_next = 0.5*(f(x) + f(xmin+(i+1)*dx))
+        y3_double.append(y_next)
+        y_prev = y_next
+    x = xmin + (i+1)*dx
+    x3_double.append(x)
+    y3_double.append(y_prev)
+    x3_double.append(x)
+    y3_double.append(0)
+    # Back to start
+    x3_double.append(xmin)
+    y3_double.append(0)
+    midpoint_curve = Curve(x3_double, y3_double).set_filled_curves(pattern='/').set_linecolor('red')
+    return midpoint_curve
+
+text2 = Text_wArrow('We just draw some rectangles\nto approximate the area\nunder the curve and sum up\nthe rectangular areas!', (1.2, 3.5), (-0.2, 1), alignment='left')
+
+drawing_tool.erase()
+fig = Composition(dict(curve=curve, integral=piecewise_curve_for_midpoint_rule(N=4), comment=text2))
+fig.draw()
+drawing_tool.display()
+drawing_tool.savefig('tmp2')
+
+text3 = Text_wArrow('Just add more rectangles\ngo get the integral\nmore accurate!', (1.5, 3.5), (-0.2, 1), alignment='left')
+
+drawing_tool.erase()
+fig = Composition(dict(curve=curve, integral=piecewise_curve_for_midpoint_rule(N=10), comment=text3))
+fig.draw()
+drawing_tool.display()
+drawing_tool.savefig('tmp3')
+
+import os
+comic = 'comic' if xkcd else 'non_comic'
+os.system('doconce combine_images pdf -3 tmp1 tmp2 tmp3 integral_%s_strip' % comic)
+os.system('doconce combine_images png -3 tmp1 tmp2 tmp3 integral_%s_strip' % comic)
+
+raw_input()

BIN
examples/integral_comic_strip.pdf


BIN
examples/integral_comic_strip.png


BIN
examples/integral_noncomic_strip.pdf


BIN
examples/integral_noncomic_strip.png


+ 5 - 1
pysketcher/MatplotlibDraw.py

@@ -57,7 +57,8 @@ class MatplotlibDraw:
         self.ax.set_ylim(minmax['ymin']-y_space/2., minmax['ymax']+y_space/2.)
 
     def set_coordinate_system(self, xmin, xmax, ymin, ymax, axis=False,
-                              instruction_file=None, new_figure=True):
+                              instruction_file=None, new_figure=True,
+                              xkcd=False):
         """
         Define the drawing area [xmin,xmax]x[ymin,ymax].
         axis: None or False means that axes with tickmarks
@@ -76,6 +77,9 @@ class MatplotlibDraw:
                 self.instruction_file.close()  # make new py file for commands
 
         self.mpl = mpl
+        if xkcd:
+            self.mpl.xkcd()
+
         self.xmin, self.xmax, self.ymin, self.ymax = \
              float(xmin), float(xmax), float(ymin), float(ymax)
         self.xrange = self.xmax - self.xmin