|
@@ -1,960 +0,0 @@
|
|
|
-<!--
|
|
|
|
|
-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>
|
|
|
|
|
-
|
|
|
|
|
-<!-- Bootstrap style: bootswatch_readable -->
|
|
|
|
|
-<link href="http://netdna.bootstrapcdn.com/bootswatch/3.1.1/readable/bootstrap.min.css" rel="stylesheet">
|
|
|
|
|
-<!-- not necessary
|
|
|
|
|
-<link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
|
|
|
|
|
--->
|
|
|
|
|
-
|
|
|
|
|
-<style type="text/css">
|
|
|
|
|
-
|
|
|
|
|
-/* Add scrollbar to dropdown menus in bootstrap navigation bar */
|
|
|
|
|
-.dropdown-menu {
|
|
|
|
|
- height: auto;
|
|
|
|
|
- max-height: 400px;
|
|
|
|
|
- overflow-x: hidden;
|
|
|
|
|
-}
|
|
|
|
|
-</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'),
|
|
|
|
|
- ('A simple pendulum',
|
|
|
|
|
- 1,
|
|
|
|
|
- 'sketcher:ex:pendulum',
|
|
|
|
|
- 'sketcher:ex:pendulum'),
|
|
|
|
|
- ('The basic physics sketch',
|
|
|
|
|
- 2,
|
|
|
|
|
- 'sketcher:ex:pendulum:basic',
|
|
|
|
|
- 'sketcher:ex:pendulum:basic'),
|
|
|
|
|
- ('The body diagram', 2, None, '___sec10'),
|
|
|
|
|
- ('Animated body diagram',
|
|
|
|
|
- 2,
|
|
|
|
|
- 'sketcher:ex:pendulum:anim',
|
|
|
|
|
- 'sketcher:ex:pendulum:anim'),
|
|
|
|
|
- ('Function for drawing the body diagram', 3, None, '___sec12'),
|
|
|
|
|
- ('Equations for the motion and forces', 3, None, '___sec13'),
|
|
|
|
|
- ('Numerical solution', 3, None, '___sec14'),
|
|
|
|
|
- ('Animation', 3, None, '___sec15'),
|
|
|
|
|
- ('Basic shapes', 1, None, '___sec16'),
|
|
|
|
|
- ('Axis', 2, None, '___sec17'),
|
|
|
|
|
- ('Distance with text', 2, None, '___sec18'),
|
|
|
|
|
- ('Rectangle', 2, None, '___sec19'),
|
|
|
|
|
- ('Triangle', 2, None, '___sec20'),
|
|
|
|
|
- ('Arc', 2, None, '___sec21'),
|
|
|
|
|
- ('Spring', 2, None, '___sec22'),
|
|
|
|
|
- ('Dashpot', 2, None, '___sec23'),
|
|
|
|
|
- ('Wavy', 2, None, '___sec24'),
|
|
|
|
|
- ('Stochastic curves', 2, None, '___sec25'),
|
|
|
|
|
- ('Inner workings of the Pysketcher tool', 1, None, '___sec26'),
|
|
|
|
|
- ('Example of classes for geometric objects',
|
|
|
|
|
- 2,
|
|
|
|
|
- None,
|
|
|
|
|
- '___sec27'),
|
|
|
|
|
- ('Simple geometric objects', 3, None, '___sec28'),
|
|
|
|
|
- ('Class curve', 3, None, '___sec29'),
|
|
|
|
|
- ('Compound geometric objects', 3, None, '___sec30'),
|
|
|
|
|
- ('Adding functionality via recursion', 2, None, '___sec31'),
|
|
|
|
|
- ('Basic principles of recursion', 3, None, '___sec32'),
|
|
|
|
|
- ('Explaining recursion', 3, None, '___sec33'),
|
|
|
|
|
- ('Scaling, translating, and rotating a figure',
|
|
|
|
|
- 2,
|
|
|
|
|
- 'sketcher:scaling',
|
|
|
|
|
- 'sketcher:scaling'),
|
|
|
|
|
- ('Scaling', 3, None, '___sec35'),
|
|
|
|
|
- ('Translation', 3, None, '___sec36'),
|
|
|
|
|
- ('Rotation', 3, None, '___sec37')]}
|
|
|
|
|
-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>
|
|
|
|
|
-
|
|
|
|
|
-<!-- newcommands.tex -->
|
|
|
|
|
-$$
|
|
|
|
|
-\newcommand{\half}{\frac{1}{2}}
|
|
|
|
|
-\newcommand{\tp}{\thinspace .}
|
|
|
|
|
-\newcommand{\rpos}{\boldsymbol{r}}
|
|
|
|
|
-\newcommand{\ii}{\boldsymbol{i}}
|
|
|
|
|
-\newcommand{\jj}{\boldsymbol{j}}
|
|
|
|
|
-\newcommand{\ir}{\boldsymbol{i}_r}
|
|
|
|
|
-\newcommand{\ith}{\boldsymbol{i}_{\theta}}
|
|
|
|
|
-$$
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-<!-- Bootstrap navigation bar -->
|
|
|
|
|
-<div class="navbar navbar-default navbar-fixed-top">
|
|
|
|
|
- <div class="navbar-header">
|
|
|
|
|
- <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse">
|
|
|
|
|
- <span class="icon-bar"></span>
|
|
|
|
|
- <span class="icon-bar"></span>
|
|
|
|
|
- <span class="icon-bar"></span>
|
|
|
|
|
- </button>
|
|
|
|
|
- <a class="navbar-brand" href="pysketcher.html">Using Pysketcher to Create Principal Sketches of Physics Problems</a>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- <div class="navbar-collapse collapse navbar-responsive-collapse">
|
|
|
|
|
- <ul class="nav navbar-nav navbar-right">
|
|
|
|
|
- <li class="dropdown">
|
|
|
|
|
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">Contents <b class="caret"></b></a>
|
|
|
|
|
- <ul class="dropdown-menu">
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec0" style="font-size: 80%;"><b>A first glimpse of Pysketcher</b></a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec1" style="font-size: 80%;"> Basic construction of sketches</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec2" style="font-size: 80%;"> Basic drawing</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec3" style="font-size: 80%;"> Groups of objects</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec4" style="font-size: 80%;"> Changing line styles and colors</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec5" style="font-size: 80%;"> The figure composition as an object hierarchy</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher002.html#___sec6" style="font-size: 80%;"> Animation: translating the vehicle</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher002.html#sketcher:vehicle1:anim" style="font-size: 80%;"> Animation: rolling the wheels</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="#sketcher:ex:pendulum" style="font-size: 80%;"><b>A simple pendulum</b></a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="#sketcher:ex:pendulum:basic" style="font-size: 80%;"> The basic physics sketch</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="#___sec10" style="font-size: 80%;"> The body diagram</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="#sketcher:ex:pendulum:anim" style="font-size: 80%;"> Animated body diagram</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="#___sec12" style="font-size: 80%;"> Function for drawing the body diagram</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="#___sec13" style="font-size: 80%;"> Equations for the motion and forces</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="#___sec14" style="font-size: 80%;"> Numerical solution</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="#___sec15" style="font-size: 80%;"> Animation</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec16" style="font-size: 80%;"><b>Basic shapes</b></a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec17" style="font-size: 80%;"> Axis</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec18" style="font-size: 80%;"> Distance with text</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec19" style="font-size: 80%;"> Rectangle</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec20" style="font-size: 80%;"> Triangle</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec21" style="font-size: 80%;"> Arc</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec22" style="font-size: 80%;"> Spring</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec23" style="font-size: 80%;"> Dashpot</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec24" style="font-size: 80%;"> Wavy</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher004.html#___sec25" style="font-size: 80%;"> Stochastic curves</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec26" style="font-size: 80%;"><b>Inner workings of the Pysketcher tool</b></a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec27" style="font-size: 80%;"> Example of classes for geometric objects</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec28" style="font-size: 80%;"> Simple geometric objects</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec29" style="font-size: 80%;"> Class curve</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec30" style="font-size: 80%;"> Compound geometric objects</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec31" style="font-size: 80%;"> Adding functionality via recursion</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec32" style="font-size: 80%;"> Basic principles of recursion</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec33" style="font-size: 80%;"> Explaining recursion</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher005.html#sketcher:scaling" style="font-size: 80%;"> Scaling, translating, and rotating a figure</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec35" style="font-size: 80%;"> Scaling</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec36" style="font-size: 80%;"> Translation</a></li>
|
|
|
|
|
- <!-- navigation toc: --> <li><a href="._pysketcher005.html#___sec37" style="font-size: 80%;"> Rotation</a></li>
|
|
|
|
|
-
|
|
|
|
|
- </ul>
|
|
|
|
|
- </li>
|
|
|
|
|
- </ul>
|
|
|
|
|
- </div>
|
|
|
|
|
-</div>
|
|
|
|
|
-</div> <!-- end of navigation bar -->
|
|
|
|
|
-
|
|
|
|
|
-<div class="container">
|
|
|
|
|
-
|
|
|
|
|
-<p> </p><p> </p><p> </p> <!-- add vertical space -->
|
|
|
|
|
-
|
|
|
|
|
-<a name="part0003"></a>
|
|
|
|
|
-<!-- !split -->
|
|
|
|
|
-
|
|
|
|
|
-<h1 id="sketcher:ex:pendulum">A simple pendulum</h1>
|
|
|
|
|
-
|
|
|
|
|
-<h2 id="sketcher:ex:pendulum:basic">The basic physics sketch</h2>
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-We now want to make a sketch of simple pendulum from physics, as shown
|
|
|
|
|
-in Figure <a href="#sketcher:ex:pendulum:fig1">8</a>. A body with mass \( m \) is attached
|
|
|
|
|
-to a massless, stiff rod, which can rotate about a point, causing the
|
|
|
|
|
-pendulum to oscillate.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-A suggested work flow is to
|
|
|
|
|
-first sketch the figure on a piece of paper and introduce a coordinate
|
|
|
|
|
-system. A simple coordinate system is indicated in Figure
|
|
|
|
|
-<a href="#sketcher:ex:pendulum:fig1wgrid">9</a>. In a code we introduce variables
|
|
|
|
|
-<code>W</code> and <code>H</code> for the width and height of the figure (i.e., extent of
|
|
|
|
|
-the coordinate system) and open the program 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">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>
|
|
|
|
|
-
|
|
|
|
|
-H <span style="color: #666666">=</span> <span style="color: #666666">7.</span>
|
|
|
|
|
-W <span style="color: #666666">=</span> <span style="color: #666666">6.</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,
|
|
|
|
|
- ymin<span style="color: #666666">=0</span>, ymax<span style="color: #666666">=</span>H,
|
|
|
|
|
- axis<span style="color: #666666">=</span><span style="color: #008000">True</span>)
|
|
|
|
|
-drawing_tool<span style="color: #666666">.</span>set_grid(<span style="color: #008000">True</span>)
|
|
|
|
|
-drawing_tool<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">'blue'</span>)
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-Note that when the sketch is ready for "production", we will (normally)
|
|
|
|
|
-set <code>axis=False</code> to remove the coordinate system and also remove the
|
|
|
|
|
-grid, i.e., delete or
|
|
|
|
|
-comment out the line <code>drawing_tool.set_grid(True)</code>.
|
|
|
|
|
-Also note that we in this example let all lines be blue by default.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-<center> <!-- figure -->
|
|
|
|
|
-<hr class="figure">
|
|
|
|
|
-<center><p class="caption">Figure 8: Sketch of a simple pendulum. <div id="sketcher:ex:pendulum:fig1"></div> </p></center>
|
|
|
|
|
-<p><img src="fig-tut/pendulum1.png" align="bottom" width=300></p>
|
|
|
|
|
-</center>
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-<center> <!-- figure -->
|
|
|
|
|
-<hr class="figure">
|
|
|
|
|
-<center><p class="caption">Figure 9: Sketch with assisting coordinate system. <div id="sketcher:ex:pendulum:fig1wgrid"></div> </p></center>
|
|
|
|
|
-<p><img src="fig-tut/pendulum1_wgrid.png" align="bottom" width=400></p>
|
|
|
|
|
-</center>
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-The next step is to introduce variables for key quantities in the sketch.
|
|
|
|
|
-Let <code>L</code> be the length of the pendulum, <code>P</code> the rotation point, and let
|
|
|
|
|
-<code>a</code> be the angle the pendulum makes with the vertical (measured in degrees).
|
|
|
|
|
-We may set
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
|
|
|
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">L <span style="color: #666666">=</span> <span style="color: #666666">5*</span>H<span style="color: #666666">/7</span> <span style="color: #408080; font-style: italic"># length</span>
|
|
|
|
|
-P <span style="color: #666666">=</span> (W<span style="color: #666666">/6</span>, <span style="color: #666666">0.85*</span>H) <span style="color: #408080; font-style: italic"># rotation point</span>
|
|
|
|
|
-a <span style="color: #666666">=</span> <span style="color: #666666">40</span> <span style="color: #408080; font-style: italic"># angle</span>
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-Be careful with integer division if you use Python 2! Fortunately, we
|
|
|
|
|
-started out with <code>float</code> objects for <code>W</code> and <code>H</code> so the expressions above
|
|
|
|
|
-are safe.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-What kind of objects do we need in this sketch? Looking at
|
|
|
|
|
-Figure <a href="#sketcher:ex:pendulum:fig1">8</a> we see that we need
|
|
|
|
|
-
|
|
|
|
|
-<ol>
|
|
|
|
|
-<li> a vertical, dashed line</li>
|
|
|
|
|
-<li> an arc with no text but dashed line to indicate the <em>path</em> of the
|
|
|
|
|
- mass</li>
|
|
|
|
|
-<li> an arc with name \( \theta \) to indicate the <em>angle</em></li>
|
|
|
|
|
-<li> a line, here called <em>rod</em>, from the rotation point to the mass</li>
|
|
|
|
|
-<li> a blue, filled circle representing the <em>mass</em></li>
|
|
|
|
|
-<li> a text \( m \) associated with the mass</li>
|
|
|
|
|
-<li> an indicator of the pendulum's <em>length</em> \( L \), visualized as
|
|
|
|
|
- a line with two arrows tips and the text \( L \)</li>
|
|
|
|
|
-<li> a gravity vector with the text \( g \)</li>
|
|
|
|
|
-</ol>
|
|
|
|
|
-
|
|
|
|
|
-Pysketcher has objects for each of these elements in our sketch.
|
|
|
|
|
-We start with the simplest element: the vertical line, going from
|
|
|
|
|
-<code>P</code> to <code>P</code> minus the length \( L \) in \( y \) direction:
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
|
|
|
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">vertical <span style="color: #666666">=</span> Line(P, P<span style="color: #666666">-</span>point(<span style="color: #666666">0</span>,L))
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-The class <code>point</code> is very convenient: it turns its two coordinates into
|
|
|
|
|
-a vector with which we can compute, and is therefore one of the most
|
|
|
|
|
-widely used Pysketcher objects.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-The path of the mass is an arc that can be made by
|
|
|
|
|
-Pysketcher's <code>Arc</code> object:
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
|
|
|
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">path <span style="color: #666666">=</span> Arc(P, L, <span style="color: #666666">-90</span>, a)
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-The first argument <code>P</code> is the center point, the second is the
|
|
|
|
|
-radius (<code>L</code> here), the next argument is the start angle, here
|
|
|
|
|
-it starts at -90 degrees, while the next argument is the angle of
|
|
|
|
|
-the arc, here <code>a</code>.
|
|
|
|
|
-For the path of the mass, we also need an arc object, but this
|
|
|
|
|
-time with an associated text. Pysketcher has a specialized object
|
|
|
|
|
-for this purpose, <code>Arc_wText</code>, since placing the text manually can
|
|
|
|
|
-be somewhat cumbersome.
|
|
|
|
|
-
|
|
|
|
|
-<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> Arc_wText(<span style="color: #BA2121">r'$\theta$'</span>, P, L<span style="color: #666666">/4</span>, <span style="color: #666666">-90</span>, a, text_spacing<span style="color: #666666">=1/30.</span>)
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-The arguments are as for <code>Arc</code> above, but the first one is the desired
|
|
|
|
|
-text. Remember to use a raw string since we want a LaTeX greek letter
|
|
|
|
|
-that contains a backslash.
|
|
|
|
|
-The <code>text_spacing</code> argument must often be tweaked. It is recommended
|
|
|
|
|
-to create only a few objects before rendering the sketch and then
|
|
|
|
|
-adjust spacings as one goes along.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-The rod is simply a line from <code>P</code> to the mass. We can easily
|
|
|
|
|
-compute the position of the mass from basic geometry considerations,
|
|
|
|
|
-but it is easier and safer to look up this point in other objects
|
|
|
|
|
-if it is already computed. In the present case,
|
|
|
|
|
-the <code>path</code> object stored its start and
|
|
|
|
|
-end points, so <code>path.geometric_features()['end']</code> is the end point
|
|
|
|
|
-of the path, which is the position of the mass. We can therefore
|
|
|
|
|
-create the rod simply as a line from <code>P</code> to this already computed end point:
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
|
|
|
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">mass_pt <span style="color: #666666">=</span> path<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">'end'</span>]
|
|
|
|
|
-rod <span style="color: #666666">=</span> Line(P, mass_pt)
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-The mass is a circle filled with color:
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
|
|
|
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">mass <span style="color: #666666">=</span> Circle(center<span style="color: #666666">=</span>mass_pt, radius<span style="color: #666666">=</span>L<span style="color: #666666">/20.</span>)
|
|
|
|
|
-mass<span style="color: #666666">.</span>set_filled_curves(color<span style="color: #666666">=</span><span style="color: #BA2121">'blue'</span>)
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-To place the \( m \) correctly, we go a small distance in the direction of
|
|
|
|
|
-the rod, from the center of the circle. To this end, we need to
|
|
|
|
|
-compute the direction. This is easiest done by computing a vector
|
|
|
|
|
-from <code>P</code> to the center of the circle and calling <code>unit_vec</code> to make
|
|
|
|
|
-a unit vector in this direction:
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
|
|
|
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">rod_vec <span style="color: #666666">=</span> rod<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">'end'</span>] <span style="color: #666666">-</span> \
|
|
|
|
|
- rod<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">'start'</span>]
|
|
|
|
|
-unit_rod_vec <span style="color: #666666">=</span> unit_vec(rod_vec)
|
|
|
|
|
-mass_symbol <span style="color: #666666">=</span> Text(<span style="color: #BA2121">'$m$'</span>, mass_pt <span style="color: #666666">+</span> L<span style="color: #666666">/10*</span>unit_rod_vec)
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-Again, the distance <code>L/10</code> is something one has to experiment with.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-The next object is the length measure with the text \( L \). Such length
|
|
|
|
|
-measures are represented by Pysketcher's <code>Distance_wText</code> object.
|
|
|
|
|
-An easy construction is to first place this length measure along the
|
|
|
|
|
-rod and then translate it a little distance (<code>L/15</code>) in the
|
|
|
|
|
-normal direction of the rod:
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
|
|
|
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">length <span style="color: #666666">=</span> Distance_wText(P, mass_pt, <span style="color: #BA2121">'$L$'</span>)
|
|
|
|
|
-length<span style="color: #666666">.</span>translate(L<span style="color: #666666">/15*</span>point(cos(radians(a)), sin(radians(a))))
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-For this translation we need a unit vector in the normal direction
|
|
|
|
|
-of the rod, which is from geometric considerations given by
|
|
|
|
|
-\( (\cos a, \sin a) \), when \( a \) is the angle of the pendulum.
|
|
|
|
|
-Alternatively, we could have found the normal vector as a vector that
|
|
|
|
|
-is normal to <code>unit_rod_vec</code>: <code>point(-unit_rod_vec[1],unit_rod_vec[0])</code>.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-The final object is the gravity force vector, which is so common
|
|
|
|
|
-in physics sketches that Pysketcher has a ready-made object: <code>Gravity</code>,
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
|
|
|
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">gravity <span style="color: #666666">=</span> Gravity(start<span style="color: #666666">=</span>P<span style="color: #666666">+</span>point(<span style="color: #666666">0.8*</span>L,<span style="color: #666666">0</span>), length<span style="color: #666666">=</span>L<span style="color: #666666">/3</span>)
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-Since blue is the default color for
|
|
|
|
|
-lines, we want the dashed lines (for <code>vertical</code> and <code>path</code>) to be black
|
|
|
|
|
-and with linewidth 1. These properties can be set one by one for each
|
|
|
|
|
-object, but we can also make a little helper function:
|
|
|
|
|
-
|
|
|
|
|
-<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">set_dashed_thin_blackline</span>(<span style="color: #666666">*</span>objects):
|
|
|
|
|
- <span style="color: #BA2121; font-style: italic">"""Set linestyle of objects to dashed, black, width=1."""</span>
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">for</span> obj <span style="color: #AA22FF; font-weight: bold">in</span> objects:
|
|
|
|
|
- obj<span style="color: #666666">.</span>set_linestyle(<span style="color: #BA2121">'dashed'</span>)
|
|
|
|
|
- obj<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">'black'</span>)
|
|
|
|
|
- obj<span style="color: #666666">.</span>set_linewidth(<span style="color: #666666">1</span>)
|
|
|
|
|
-
|
|
|
|
|
-set_dashed_thin_blackline(vertical, path)
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-Now, all objects are in place, so it remains to compose the final
|
|
|
|
|
-figure and draw the composition:
|
|
|
|
|
-
|
|
|
|
|
-<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">'body'</span>: mass, <span style="color: #BA2121">'rod'</span>: rod,
|
|
|
|
|
- <span style="color: #BA2121">'vertical'</span>: vertical, <span style="color: #BA2121">'theta'</span>: angle, <span style="color: #BA2121">'path'</span>: path,
|
|
|
|
|
- <span style="color: #BA2121">'g'</span>: gravity, <span style="color: #BA2121">'L'</span>: length, <span style="color: #BA2121">'m'</span>: mass_symbol})
|
|
|
|
|
-
|
|
|
|
|
-fig<span style="color: #666666">.</span>draw()
|
|
|
|
|
-drawing_tool<span style="color: #666666">.</span>display()
|
|
|
|
|
-drawing_tool<span style="color: #666666">.</span>savefig(<span style="color: #BA2121">'pendulum1'</span>)
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-
|
|
|
|
|
-<h2 id="___sec10">The body diagram </h2>
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-Now we want to isolate the mass and draw all the forces that act on it.
|
|
|
|
|
-Figure <a href="#sketcher:ex:pendulum:fig2wgrid">10</a> shows the desired result, but
|
|
|
|
|
-embedded in the coordinate system.
|
|
|
|
|
-We consider three types of forces: the gravity force, the force from the
|
|
|
|
|
-rod, and air resistance. The body diagram is key for deriving the
|
|
|
|
|
-equation of motion, so it is illustrative to add useful mathematical
|
|
|
|
|
-quantities needed in the derivation, such as the unit vectors in polar
|
|
|
|
|
-coordinates.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-<center> <!-- figure -->
|
|
|
|
|
-<hr class="figure">
|
|
|
|
|
-<center><p class="caption">Figure 10: Body diagram of a simple pendulum. <div id="sketcher:ex:pendulum:fig2wgrid"></div> </p></center>
|
|
|
|
|
-<p><img src="fig-tut/pendulum5_wgrid.png" align="bottom" width=300></p>
|
|
|
|
|
-</center>
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-We start by listing the objects in the sketch:
|
|
|
|
|
-
|
|
|
|
|
-<ol>
|
|
|
|
|
-<li> a text \( (x_0,y_0) \) representing the rotation point <code>P</code></li>
|
|
|
|
|
-<li> unit vector \( \boldsymbol{i}_r \) with text</li>
|
|
|
|
|
-<li> unit vector \( \boldsymbol{i}_\theta \) with text</li>
|
|
|
|
|
-<li> a dashed vertical line</li>
|
|
|
|
|
-<li> a dashed line along the rod</li>
|
|
|
|
|
-<li> an arc with text \( \theta \)</li>
|
|
|
|
|
-<li> the gravity force with text \( mg \)</li>
|
|
|
|
|
-<li> the force in the rod with text \( S \)</li>
|
|
|
|
|
-<li> the air resistance force with text \( \sim |v|v \)</li>
|
|
|
|
|
-</ol>
|
|
|
|
|
-
|
|
|
|
|
-The first object, \( (x_0,y_0) \), is simply a plain text where we have
|
|
|
|
|
-to experiment with its position. The unit vectors in polar coordinates
|
|
|
|
|
-may be drawn using the Pysketcher's <code>Force</code> object since it has an
|
|
|
|
|
-arrow with a text. The first three objects can then be made as follows:
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
|
|
|
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">x0y0 <span style="color: #666666">=</span> Text(<span style="color: #BA2121">'$(x_0,y_0)$'</span>, P <span style="color: #666666">+</span> point(<span style="color: #666666">-0.4</span>,<span style="color: #666666">-0.1</span>))
|
|
|
|
|
-ir <span style="color: #666666">=</span> Force(P, P <span style="color: #666666">+</span> L<span style="color: #666666">/10*</span>unit_vec(rod_vec),
|
|
|
|
|
- <span style="color: #BA2121">r'$\boldsymbol{i}_r$'</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">'end'</span>,
|
|
|
|
|
- text_spacing<span style="color: #666666">=</span>(<span style="color: #666666">0.015</span>,<span style="color: #666666">0</span>))
|
|
|
|
|
-ith <span style="color: #666666">=</span> Force(P, P <span style="color: #666666">+</span> L<span style="color: #666666">/10*</span>unit_vec((<span style="color: #666666">-</span>rod_vec[<span style="color: #666666">1</span>], rod_vec[<span style="color: #666666">0</span>])),
|
|
|
|
|
- <span style="color: #BA2121">r'$\boldsymbol{i}_{\theta}$'</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">'end'</span>,
|
|
|
|
|
- text_spacing<span style="color: #666666">=</span>(<span style="color: #666666">0.02</span>,<span style="color: #666666">0.005</span>))
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-Note that tweaking of the position of <code>x0y0</code> use absolute coordinates, so
|
|
|
|
|
-if <code>W</code> or <code>H</code> is changed in the beginning of the figure, the tweaked position
|
|
|
|
|
-will most likely not look good. A better solution would be to express
|
|
|
|
|
-the tweaked displacement <code>point(-0.4,-0.1)</code> in terms of <code>W</code> and <code>H</code>.
|
|
|
|
|
-The <code>text_spacing</code> values in the <code>Force</code> objects also use absolute
|
|
|
|
|
-coordinates. Very often, this is much more convenient when adjusting
|
|
|
|
|
-the objects, and global size parameters like <code>W</code> and <code>H</code> are in practice
|
|
|
|
|
-seldom changed, so the solution above is quite typical.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-The vertical, dashed line, the dashed rod, and the arc for \( \theta \)
|
|
|
|
|
-are made by
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
|
|
|
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">rod_start <span style="color: #666666">=</span> rod<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">'start'</span>] <span style="color: #408080; font-style: italic"># Point P</span>
|
|
|
|
|
-vertical2 <span style="color: #666666">=</span> Line(rod_start, rod_start <span style="color: #666666">+</span> point(<span style="color: #666666">0</span>,<span style="color: #666666">-</span>L<span style="color: #666666">/3</span>))
|
|
|
|
|
-set_dashed_thin_blackline(vertical2)
|
|
|
|
|
-set_dashed_thin_blackline(rod)
|
|
|
|
|
-angle2 <span style="color: #666666">=</span> Arc_wText(<span style="color: #BA2121">r'$\theta$'</span>, rod_start, L<span style="color: #666666">/6</span>, <span style="color: #666666">-90</span>, a,
|
|
|
|
|
- text_spacing<span style="color: #666666">=1/30.</span>)
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-Note how we reuse the earlier defined object <code>rod</code>.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-The forces are constructed as shown below.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
|
|
|
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">mg_force <span style="color: #666666">=</span> Force(mass_pt, mass_pt <span style="color: #666666">+</span> L<span style="color: #666666">/5*</span>point(<span style="color: #666666">0</span>,<span style="color: #666666">-1</span>),
|
|
|
|
|
- <span style="color: #BA2121">'$mg$'</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">'end'</span>)
|
|
|
|
|
-rod_force <span style="color: #666666">=</span> Force(mass_pt, mass_pt <span style="color: #666666">-</span> L<span style="color: #666666">/3*</span>unit_vec(rod_vec),
|
|
|
|
|
- <span style="color: #BA2121">'$S$'</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">'end'</span>,
|
|
|
|
|
- text_spacing<span style="color: #666666">=</span>(<span style="color: #666666">0.03</span>, <span style="color: #666666">0.01</span>))
|
|
|
|
|
-air_force <span style="color: #666666">=</span> Force(mass_pt, mass_pt <span style="color: #666666">-</span>
|
|
|
|
|
- L<span style="color: #666666">/6*</span>unit_vec((rod_vec[<span style="color: #666666">1</span>], <span style="color: #666666">-</span>rod_vec[<span style="color: #666666">0</span>])),
|
|
|
|
|
- <span style="color: #BA2121">'$\sim|v|v$'</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">'end'</span>,
|
|
|
|
|
- text_spacing<span style="color: #666666">=</span>(<span style="color: #666666">0.04</span>,<span style="color: #666666">0.005</span>))
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-Note that the drag force from the air is directed perpendicular to
|
|
|
|
|
-the rod, so we construct a unit vector in this direction directly from
|
|
|
|
|
-the <code>rod_vec</code> vector.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-All objects are in place, and we can compose a figure to be drawn:
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
|
|
|
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">body_diagram <span style="color: #666666">=</span> Composition(
|
|
|
|
|
- {<span style="color: #BA2121">'mg'</span>: mg_force, <span style="color: #BA2121">'S'</span>: rod_force, <span style="color: #BA2121">'rod'</span>: rod,
|
|
|
|
|
- <span style="color: #BA2121">'vertical'</span>: vertical2, <span style="color: #BA2121">'theta'</span>: angle2,
|
|
|
|
|
- <span style="color: #BA2121">'body'</span>: mass, <span style="color: #BA2121">'m'</span>: mass_symbol})
|
|
|
|
|
-
|
|
|
|
|
-body_diagram[<span style="color: #BA2121">'air'</span>] <span style="color: #666666">=</span> air_force
|
|
|
|
|
-body_diagram[<span style="color: #BA2121">'ir'</span>] <span style="color: #666666">=</span> ir
|
|
|
|
|
-body_diagram[<span style="color: #BA2121">'ith'</span>] <span style="color: #666666">=</span> ith
|
|
|
|
|
-body_diagram[<span style="color: #BA2121">'origin'</span>] <span style="color: #666666">=</span> x0y0
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-Here, we exemplify that we can start out with a composition as a
|
|
|
|
|
-dictionary, but (as in ordinary Python dictionaries) add new
|
|
|
|
|
-elements later when desired.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-<!-- FIGURE: [fig-tut/pendulum1.png, width=300 frac=0.5] Sketch of a simple pendulum. <div id="sketcher:ex:pendulum:fig2"></div> -->
|
|
|
|
|
-
|
|
|
|
|
-<h2 id="sketcher:ex:pendulum:anim">Animated body diagram</h2>
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-We want to make an animated body diagram so that we can see how forces
|
|
|
|
|
-develop in time according to the motion. This means that we must
|
|
|
|
|
-couple the sketch at each time level to a numerical solution for
|
|
|
|
|
-the motion of the pendulum.
|
|
|
|
|
-
|
|
|
|
|
-<h3 id="___sec12">Function for drawing the body diagram </h3>
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-The previous flat program for making sketches of the pendulum is not
|
|
|
|
|
-suitable when we want to make a sketch at a lot of different points
|
|
|
|
|
-in time, i.e., for a lot of different angles that the pendulum makes
|
|
|
|
|
-with the vertical. We therefore need to draw the body diagram in
|
|
|
|
|
-a function where the angle is a parameter. We also supply arrays
|
|
|
|
|
-containing the (numerically computed) values of the angle \( \theta \) and
|
|
|
|
|
-the forces at various time levels, plus the desired time point and level
|
|
|
|
|
-for this particular sketch:
|
|
|
|
|
-
|
|
|
|
|
-<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>
|
|
|
|
|
-
|
|
|
|
|
-H <span style="color: #666666">=</span> <span style="color: #666666">15.</span>
|
|
|
|
|
-W <span style="color: #666666">=</span> <span style="color: #666666">17.</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,
|
|
|
|
|
- ymin<span style="color: #666666">=0</span>, ymax<span style="color: #666666">=</span>H,
|
|
|
|
|
- axis<span style="color: #666666">=</span><span style="color: #008000">False</span>)
|
|
|
|
|
-
|
|
|
|
|
-<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">pendulum</span>(theta, S, mg, drag, t, time_level):
|
|
|
|
|
-
|
|
|
|
|
- drawing_tool<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">'blue'</span>)
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">math</span>
|
|
|
|
|
- a <span style="color: #666666">=</span> math<span style="color: #666666">.</span>degrees(theta[time_level])
|
|
|
|
|
- L <span style="color: #666666">=</span> <span style="color: #666666">0.4*</span>H <span style="color: #408080; font-style: italic"># length</span>
|
|
|
|
|
- P <span style="color: #666666">=</span> (W<span style="color: #666666">/2</span>, <span style="color: #666666">0.8*</span>H) <span style="color: #408080; font-style: italic"># rotation point</span>
|
|
|
|
|
-
|
|
|
|
|
- vertical <span style="color: #666666">=</span> Line(P, P<span style="color: #666666">-</span>point(<span style="color: #666666">0</span>,L))
|
|
|
|
|
- path <span style="color: #666666">=</span> Arc(P, L, <span style="color: #666666">-90</span>, a)
|
|
|
|
|
- angle <span style="color: #666666">=</span> Arc_wText(<span style="color: #BA2121">r'$\theta$'</span>, P, L<span style="color: #666666">/4</span>, <span style="color: #666666">-90</span>, a, text_spacing<span style="color: #666666">=1/30.</span>)
|
|
|
|
|
-
|
|
|
|
|
- mass_pt <span style="color: #666666">=</span> path<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">'end'</span>]
|
|
|
|
|
- rod <span style="color: #666666">=</span> Line(P, mass_pt)
|
|
|
|
|
-
|
|
|
|
|
- mass <span style="color: #666666">=</span> Circle(center<span style="color: #666666">=</span>mass_pt, radius<span style="color: #666666">=</span>L<span style="color: #666666">/20.</span>)
|
|
|
|
|
- mass<span style="color: #666666">.</span>set_filled_curves(color<span style="color: #666666">=</span><span style="color: #BA2121">'blue'</span>)
|
|
|
|
|
- rod_vec <span style="color: #666666">=</span> rod<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">'end'</span>] <span style="color: #666666">-</span> \
|
|
|
|
|
- rod<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">'start'</span>]
|
|
|
|
|
- unit_rod_vec <span style="color: #666666">=</span> unit_vec(rod_vec)
|
|
|
|
|
- mass_symbol <span style="color: #666666">=</span> Text(<span style="color: #BA2121">'$m$'</span>, mass_pt <span style="color: #666666">+</span> L<span style="color: #666666">/10*</span>unit_rod_vec)
|
|
|
|
|
-
|
|
|
|
|
- length <span style="color: #666666">=</span> Distance_wText(P, mass_pt, <span style="color: #BA2121">'$L$'</span>)
|
|
|
|
|
- <span style="color: #408080; font-style: italic"># Displace length indication</span>
|
|
|
|
|
- length<span style="color: #666666">.</span>translate(L<span style="color: #666666">/15*</span>point(cos(radians(a)), sin(radians(a))))
|
|
|
|
|
- gravity <span style="color: #666666">=</span> Gravity(start<span style="color: #666666">=</span>P<span style="color: #666666">+</span>point(<span style="color: #666666">0.8*</span>L,<span style="color: #666666">0</span>), length<span style="color: #666666">=</span>L<span style="color: #666666">/3</span>)
|
|
|
|
|
-
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">set_dashed_thin_blackline</span>(<span style="color: #666666">*</span>objects):
|
|
|
|
|
- <span style="color: #BA2121; font-style: italic">"""Set linestyle of objects to dashed, black, width=1."""</span>
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">for</span> obj <span style="color: #AA22FF; font-weight: bold">in</span> objects:
|
|
|
|
|
- obj<span style="color: #666666">.</span>set_linestyle(<span style="color: #BA2121">'dashed'</span>)
|
|
|
|
|
- obj<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">'black'</span>)
|
|
|
|
|
- obj<span style="color: #666666">.</span>set_linewidth(<span style="color: #666666">1</span>)
|
|
|
|
|
-
|
|
|
|
|
- set_dashed_thin_blackline(vertical, path)
|
|
|
|
|
-
|
|
|
|
|
- fig <span style="color: #666666">=</span> Composition(
|
|
|
|
|
- {<span style="color: #BA2121">'body'</span>: mass, <span style="color: #BA2121">'rod'</span>: rod,
|
|
|
|
|
- <span style="color: #BA2121">'vertical'</span>: vertical, <span style="color: #BA2121">'theta'</span>: angle, <span style="color: #BA2121">'path'</span>: path,
|
|
|
|
|
- <span style="color: #BA2121">'g'</span>: gravity, <span style="color: #BA2121">'L'</span>: length})
|
|
|
|
|
-
|
|
|
|
|
- <span style="color: #408080; font-style: italic">#fig.draw()</span>
|
|
|
|
|
- <span style="color: #408080; font-style: italic">#drawing_tool.display()</span>
|
|
|
|
|
- <span style="color: #408080; font-style: italic">#drawing_tool.savefig('tmp_pendulum1')</span>
|
|
|
|
|
-
|
|
|
|
|
- drawing_tool<span style="color: #666666">.</span>set_linecolor(<span style="color: #BA2121">'black'</span>)
|
|
|
|
|
-
|
|
|
|
|
- rod_start <span style="color: #666666">=</span> rod<span style="color: #666666">.</span>geometric_features()[<span style="color: #BA2121">'start'</span>] <span style="color: #408080; font-style: italic"># Point P</span>
|
|
|
|
|
- vertical2 <span style="color: #666666">=</span> Line(rod_start, rod_start <span style="color: #666666">+</span> point(<span style="color: #666666">0</span>,<span style="color: #666666">-</span>L<span style="color: #666666">/3</span>))
|
|
|
|
|
- set_dashed_thin_blackline(vertical2)
|
|
|
|
|
- set_dashed_thin_blackline(rod)
|
|
|
|
|
- angle2 <span style="color: #666666">=</span> Arc_wText(<span style="color: #BA2121">r'$\theta$'</span>, rod_start, L<span style="color: #666666">/6</span>, <span style="color: #666666">-90</span>, a,
|
|
|
|
|
- text_spacing<span style="color: #666666">=1/30.</span>)
|
|
|
|
|
-
|
|
|
|
|
- magnitude <span style="color: #666666">=</span> <span style="color: #666666">1.2*</span>L<span style="color: #666666">/2</span> <span style="color: #408080; font-style: italic"># length of a unit force in figure</span>
|
|
|
|
|
- force <span style="color: #666666">=</span> mg[time_level] <span style="color: #408080; font-style: italic"># constant (scaled eq: about 1)</span>
|
|
|
|
|
- force <span style="color: #666666">*=</span> magnitude
|
|
|
|
|
- mg_force <span style="color: #666666">=</span> Force(mass_pt, mass_pt <span style="color: #666666">+</span> force<span style="color: #666666">*</span>point(<span style="color: #666666">0</span>,<span style="color: #666666">-1</span>),
|
|
|
|
|
- <span style="color: #BA2121">''</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">'end'</span>)
|
|
|
|
|
- force <span style="color: #666666">=</span> S[time_level]
|
|
|
|
|
- force <span style="color: #666666">*=</span> magnitude
|
|
|
|
|
- rod_force <span style="color: #666666">=</span> Force(mass_pt, mass_pt <span style="color: #666666">-</span> force<span style="color: #666666">*</span>unit_vec(rod_vec),
|
|
|
|
|
- <span style="color: #BA2121">''</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">'end'</span>,
|
|
|
|
|
- text_spacing<span style="color: #666666">=</span>(<span style="color: #666666">0.03</span>, <span style="color: #666666">0.01</span>))
|
|
|
|
|
- force <span style="color: #666666">=</span> drag[time_level]
|
|
|
|
|
- force <span style="color: #666666">*=</span> magnitude
|
|
|
|
|
- <span style="color: #408080; font-style: italic">#print('drag(%g)=%g' % (t, drag[time_level]))</span>
|
|
|
|
|
- air_force <span style="color: #666666">=</span> Force(mass_pt, mass_pt <span style="color: #666666">-</span>
|
|
|
|
|
- force<span style="color: #666666">*</span>unit_vec((rod_vec[<span style="color: #666666">1</span>], <span style="color: #666666">-</span>rod_vec[<span style="color: #666666">0</span>])),
|
|
|
|
|
- <span style="color: #BA2121">''</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">'end'</span>,
|
|
|
|
|
- text_spacing<span style="color: #666666">=</span>(<span style="color: #666666">0.04</span>,<span style="color: #666666">0.005</span>))
|
|
|
|
|
-
|
|
|
|
|
- body_diagram <span style="color: #666666">=</span> Composition(
|
|
|
|
|
- {<span style="color: #BA2121">'mg'</span>: mg_force, <span style="color: #BA2121">'S'</span>: rod_force, <span style="color: #BA2121">'air'</span>: air_force,
|
|
|
|
|
- <span style="color: #BA2121">'rod'</span>: rod,
|
|
|
|
|
- <span style="color: #BA2121">'vertical'</span>: vertical2, <span style="color: #BA2121">'theta'</span>: angle2,
|
|
|
|
|
- <span style="color: #BA2121">'body'</span>: mass})
|
|
|
|
|
-
|
|
|
|
|
- x0y0 <span style="color: #666666">=</span> Text(<span style="color: #BA2121">'$(x_0,y_0)$'</span>, P <span style="color: #666666">+</span> point(<span style="color: #666666">-0.4</span>,<span style="color: #666666">-0.1</span>))
|
|
|
|
|
- ir <span style="color: #666666">=</span> Force(P, P <span style="color: #666666">+</span> L<span style="color: #666666">/10*</span>unit_vec(rod_vec),
|
|
|
|
|
- <span style="color: #BA2121">r'$\boldsymbol{i}_r$'</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">'end'</span>,
|
|
|
|
|
- text_spacing<span style="color: #666666">=</span>(<span style="color: #666666">0.015</span>,<span style="color: #666666">0</span>))
|
|
|
|
|
- ith <span style="color: #666666">=</span> Force(P, P <span style="color: #666666">+</span> L<span style="color: #666666">/10*</span>unit_vec((<span style="color: #666666">-</span>rod_vec[<span style="color: #666666">1</span>], rod_vec[<span style="color: #666666">0</span>])),
|
|
|
|
|
- <span style="color: #BA2121">r'$\boldsymbol{i}_{\theta}$'</span>, text_pos<span style="color: #666666">=</span><span style="color: #BA2121">'end'</span>,
|
|
|
|
|
- text_spacing<span style="color: #666666">=</span>(<span style="color: #666666">0.02</span>,<span style="color: #666666">0.005</span>))
|
|
|
|
|
-
|
|
|
|
|
- <span style="color: #408080; font-style: italic">#body_diagram['ir'] = ir</span>
|
|
|
|
|
- <span style="color: #408080; font-style: italic">#body_diagram['ith'] = ith</span>
|
|
|
|
|
- <span style="color: #408080; font-style: italic">#body_diagram['origin'] = x0y0</span>
|
|
|
|
|
-
|
|
|
|
|
- drawing_tool<span style="color: #666666">.</span>erase()
|
|
|
|
|
- body_diagram<span style="color: #666666">.</span>draw(verbose<span style="color: #666666">=0</span>)
|
|
|
|
|
- <span style="color: #408080; font-style: italic">#drawing_tool.display('Body diagram')</span>
|
|
|
|
|
- drawing_tool<span style="color: #666666">.</span>savefig(<span style="color: #BA2121">'tmp_</span><span style="color: #BB6688; font-weight: bold">%04d</span><span style="color: #BA2121">.png'</span> <span style="color: #666666">%</span> time_level, crop<span style="color: #666666">=</span><span style="color: #008000">False</span>)
|
|
|
|
|
- <span style="color: #408080; font-style: italic"># No cropping: otherwise movies will be very strange</span>
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-
|
|
|
|
|
-<h3 id="___sec13">Equations for the motion and forces </h3>
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-The modeling of the motion of a pendulum is most conveniently done in
|
|
|
|
|
-polar coordinates since then the unknown force in the rod is separated
|
|
|
|
|
-from the equation determining the motion \( \theta(t) \).
|
|
|
|
|
-The position vector for the mass is
|
|
|
|
|
-
|
|
|
|
|
-$$ \rpos = x_0\ii + y_0\jj + L\ir\tp$$
|
|
|
|
|
-
|
|
|
|
|
-The corresponding acceleration becomes
|
|
|
|
|
-
|
|
|
|
|
-$$ \ddot{\rpos} = L\ddot{\theta}{\ith} - L\dot{\theta^2}{\ir}\tp$$
|
|
|
|
|
-
|
|
|
|
|
-<!-- Note: the extra braces help to render the equation correctly in sphinx! -->
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-There are three forces on the mass: the gravity force
|
|
|
|
|
-\( mg\jj = mg(-\cos\theta\,\ir + \sin\theta\,\ith) \), the force in the rod
|
|
|
|
|
-\( -S\ir \), and the drag force because of air resistance:
|
|
|
|
|
-
|
|
|
|
|
-$$ -\half C_D \varrho \pi R^2 |v|v\,\ith,$$
|
|
|
|
|
-
|
|
|
|
|
-where \( C_D\approx 0.4 \) is the drag coefficient for a sphere, \( \varrho \)
|
|
|
|
|
-is the density of air, \( R \) is the radius of the mass, and \( v \) is the
|
|
|
|
|
-velocity (\( v=L\dot\theta \)). The drag force acts in \( -\ith \) direction
|
|
|
|
|
-when \( v>0 \).
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-Newton's second law of motion for the pendulum now becomes
|
|
|
|
|
-
|
|
|
|
|
-$$ mL\ddot\theta\ith - mL\dot\theta^2\ir = -mg(-\cos\theta\,\ir +
|
|
|
|
|
-\sin\theta\,\ith)
|
|
|
|
|
--S\ir - \half C_D \varrho \pi R^2 L^2|\dot\theta|\dot\theta\ith,$$
|
|
|
|
|
-
|
|
|
|
|
-which gives two component equations
|
|
|
|
|
-
|
|
|
|
|
-$$
|
|
|
|
|
-\begin{align}
|
|
|
|
|
-mL\ddot\theta + \half C_D \varrho \pi R^2 L^2|\dot\theta|\dot\theta +
|
|
|
|
|
-mg\sin\theta &= 0,
|
|
|
|
|
-\tag{1}\\
|
|
|
|
|
-S &= mL\dot\theta^2 + mg\cos\theta
|
|
|
|
|
-\tag{2}\tp
|
|
|
|
|
-\end{align}
|
|
|
|
|
-$$
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-It is almost always convenient to scale such equations. Introducing
|
|
|
|
|
-the dimensionless time
|
|
|
|
|
-
|
|
|
|
|
-$$ \bar t = \frac{t}{t_c},\quad t_c = \sqrt{\frac{L}{g}},$$
|
|
|
|
|
-
|
|
|
|
|
-leads to
|
|
|
|
|
-
|
|
|
|
|
-$$
|
|
|
|
|
-\begin{align}
|
|
|
|
|
-\frac{d^2\theta}{d\bar t^2} +
|
|
|
|
|
-\alpha\left\vert\frac{d\theta}{d\bar t}\right\vert\frac{d\theta}{d\bar t} +
|
|
|
|
|
-\sin\theta &= 0,
|
|
|
|
|
-\tag{3}\\
|
|
|
|
|
-\bar S &= \left(\frac{d\theta}{d\bar t}\right)^2
|
|
|
|
|
-+ \cos\theta,
|
|
|
|
|
-\tag{4}
|
|
|
|
|
-\end{align}
|
|
|
|
|
-$$
|
|
|
|
|
-
|
|
|
|
|
-where \( \alpha \) is a dimensionless drag coefficient
|
|
|
|
|
-
|
|
|
|
|
-$$ \alpha = \frac{C_D\varrho\pi R^2L}{2m},$$
|
|
|
|
|
-
|
|
|
|
|
-and \( \bar S \) is the scaled force
|
|
|
|
|
-
|
|
|
|
|
-$$ \bar S = \frac{S}{mg}\tp$$
|
|
|
|
|
-
|
|
|
|
|
-We see that \( \bar S = 1 \) for the equilibrium position \( \theta=0 \), so this
|
|
|
|
|
-scaling of \( S \) seems appropriate.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-The parameter \( \alpha \) is about
|
|
|
|
|
-the ratio of the drag force and the gravity force:
|
|
|
|
|
-
|
|
|
|
|
-$$ \frac{|\half C_D\varrho \pi R^2 |v|v|}{|mg|}\sim
|
|
|
|
|
-\frac{C_D\varrho \pi R^2 L^2 t_c^{-2}}{mg}
|
|
|
|
|
-\left|\frac{d\bar\theta}{d\bar t}\right|\frac{d\bar\theta}{d\bar t}
|
|
|
|
|
-\sim \frac{C_D\varrho \pi R^2 L}{2m}\theta_0^2 = \alpha \theta_0^2\tp$$
|
|
|
|
|
-
|
|
|
|
|
-(We have that \( \theta(t)/d\theta_0 \) is in \( [-1,1] \), so we expect
|
|
|
|
|
-since \( \theta_0^{-1}d\bar\theta/d\bar t \) to be around unity. Here,
|
|
|
|
|
-\( \theta_0=\theta(0) \).)
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-The next step is to write a numerical solver for
|
|
|
|
|
-<a href="#mjx-eqn-3">(3)</a>-<a href="#mjx-eqn-4">(4)</a>. To
|
|
|
|
|
-this end, we use the <a href="https://github.com/hplgit/odespy" target="_self">Odespy</a>
|
|
|
|
|
-package. The system of second-order ODEs must be expressed as a system
|
|
|
|
|
-of first-order ODEs. We realize that the unknown \( \bar S \) is decoupled
|
|
|
|
|
-from \( \theta \) in the sense that we can first use
|
|
|
|
|
-<a href="#mjx-eqn-3">(3)</a> to solve for \( \theta \) and
|
|
|
|
|
-then compute \( \bar S \) from <a href="#mjx-eqn-4">(4)</a>.
|
|
|
|
|
-The first-order ODEs become
|
|
|
|
|
-
|
|
|
|
|
-$$
|
|
|
|
|
-\begin{align}
|
|
|
|
|
-\frac{d\omega}{d\bar t} &= -\alpha\left\vert\omega\right\vert\omega
|
|
|
|
|
-- \sin\theta,
|
|
|
|
|
-\tag{5}\\
|
|
|
|
|
-\frac{d\theta}{d\bar t} &= \omega\tp
|
|
|
|
|
-\tag{6}
|
|
|
|
|
-\end{align}
|
|
|
|
|
-$$
|
|
|
|
|
-
|
|
|
|
|
-Then we compute
|
|
|
|
|
-
|
|
|
|
|
-$$
|
|
|
|
|
-\begin{equation}
|
|
|
|
|
-\bar S = \omega^2 + \cos\theta\tp
|
|
|
|
|
-\tag{7}
|
|
|
|
|
-\end{equation}
|
|
|
|
|
-$$
|
|
|
|
|
-
|
|
|
|
|
-The dimensionless air resistance force can also be computed:
|
|
|
|
|
-
|
|
|
|
|
-$$
|
|
|
|
|
-\begin{equation}
|
|
|
|
|
--\alpha|\omega|\omega\tp
|
|
|
|
|
-\tag{8}
|
|
|
|
|
-\end{equation}
|
|
|
|
|
-$$
|
|
|
|
|
-
|
|
|
|
|
-Since we scaled the force \( S \) by \( mg \), \( mg \) is the natural force scale,
|
|
|
|
|
-and the \( mg \) force itself is then unity.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-By updating \( \omega \) in the first equation, we can use an Euler-Cromer
|
|
|
|
|
-scheme on Odespy (all other schemes are independent of whether the
|
|
|
|
|
-\( \theta \) or \( \omega \) equation comes first).
|
|
|
|
|
-
|
|
|
|
|
-<h3 id="___sec14">Numerical solution </h3>
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-An appropriate solver 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">simulate_pendulum</span>(alpha, theta0, dt, T):
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">odespy</span>
|
|
|
|
|
-
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">f</span>(u, t, alpha):
|
|
|
|
|
- omega, theta <span style="color: #666666">=</span> u
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">return</span> [<span style="color: #666666">-</span>alpha<span style="color: #666666">*</span>omega<span style="color: #666666">*</span><span style="color: #008000">abs</span>(omega) <span style="color: #666666">-</span> sin(theta),
|
|
|
|
|
- omega]
|
|
|
|
|
-
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">numpy</span> <span style="color: #008000; font-weight: bold">as</span> <span style="color: #0000FF; font-weight: bold">np</span>
|
|
|
|
|
- Nt <span style="color: #666666">=</span> <span style="color: #008000">int</span>(<span style="color: #008000">round</span>(T<span style="color: #666666">/</span><span style="color: #008000">float</span>(dt)))
|
|
|
|
|
- t <span style="color: #666666">=</span> np<span style="color: #666666">.</span>linspace(<span style="color: #666666">0</span>, Nt<span style="color: #666666">*</span>dt, Nt<span style="color: #666666">+1</span>)
|
|
|
|
|
- solver <span style="color: #666666">=</span> odespy<span style="color: #666666">.</span>RK4(f, f_args<span style="color: #666666">=</span>[alpha])
|
|
|
|
|
- solver<span style="color: #666666">.</span>set_initial_condition([<span style="color: #666666">0</span>, theta0])
|
|
|
|
|
- u, t <span style="color: #666666">=</span> solver<span style="color: #666666">.</span>solve(t,
|
|
|
|
|
- terminate<span style="color: #666666">=</span><span style="color: #008000; font-weight: bold">lambda</span> u, t, n: <span style="color: #008000">abs</span>(u[n,<span style="color: #666666">1</span>]) <span style="color: #666666"><</span> <span style="color: #666666">1E-3</span>)
|
|
|
|
|
- omega <span style="color: #666666">=</span> u[:,<span style="color: #666666">0</span>]
|
|
|
|
|
- theta <span style="color: #666666">=</span> u[:,<span style="color: #666666">1</span>]
|
|
|
|
|
- S <span style="color: #666666">=</span> omega<span style="color: #666666">**2</span> <span style="color: #666666">+</span> np<span style="color: #666666">.</span>cos(theta)
|
|
|
|
|
- drag <span style="color: #666666">=</span> <span style="color: #666666">-</span>alpha<span style="color: #666666">*</span>np<span style="color: #666666">.</span>abs(omega)<span style="color: #666666">*</span>omega
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">return</span> t, theta, omega, S, drag
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-
|
|
|
|
|
-<h3 id="___sec15">Animation </h3>
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-We can finally traverse the time array and draw a body diagram
|
|
|
|
|
-at each time level. The resulting sketches are saved to files
|
|
|
|
|
-<code>tmp_%04d.png</code>, and these files can be combined to videos:
|
|
|
|
|
-
|
|
|
|
|
-<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">animate</span>():
|
|
|
|
|
- <span style="color: #408080; font-style: italic"># Clean up old plot files</span>
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">os</span><span style="color: #666666">,</span> <span style="color: #0000FF; font-weight: bold">glob</span>
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">for</span> filename <span style="color: #AA22FF; font-weight: bold">in</span> glob<span style="color: #666666">.</span>glob(<span style="color: #BA2121">'tmp_*.png'</span>) <span style="color: #666666">+</span> glob<span style="color: #666666">.</span>glob(<span style="color: #BA2121">'movie.*'</span>):
|
|
|
|
|
- os<span style="color: #666666">.</span>remove(filename)
|
|
|
|
|
- <span style="color: #408080; font-style: italic"># Solve problem</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> pi, radians, degrees
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">numpy</span> <span style="color: #008000; font-weight: bold">as</span> <span style="color: #0000FF; font-weight: bold">np</span>
|
|
|
|
|
- alpha <span style="color: #666666">=</span> <span style="color: #666666">0.4</span>
|
|
|
|
|
- period <span style="color: #666666">=</span> <span style="color: #666666">2*</span>pi
|
|
|
|
|
- T <span style="color: #666666">=</span> <span style="color: #666666">12*</span>period
|
|
|
|
|
- dt <span style="color: #666666">=</span> period<span style="color: #666666">/40</span>
|
|
|
|
|
- a <span style="color: #666666">=</span> <span style="color: #666666">70</span>
|
|
|
|
|
- theta0 <span style="color: #666666">=</span> radians(a)
|
|
|
|
|
- t, theta, omega, S, drag <span style="color: #666666">=</span> simulate_pendulum(alpha, theta0, dt, T)
|
|
|
|
|
- mg <span style="color: #666666">=</span> np<span style="color: #666666">.</span>ones(S<span style="color: #666666">.</span>size)
|
|
|
|
|
- <span style="color: #408080; font-style: italic"># Visualize drag force 5 times as large</span>
|
|
|
|
|
- drag <span style="color: #666666">*=</span> <span style="color: #666666">5</span>
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">'NOTE: drag force magnified 5 times!!'</span>)
|
|
|
|
|
-
|
|
|
|
|
- <span style="color: #408080; font-style: italic"># Draw animation</span>
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">time</span>
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">for</span> time_level, t_ <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #008000">enumerate</span>(t):
|
|
|
|
|
- pendulum(theta, S, mg, drag, t_, time_level)
|
|
|
|
|
- time<span style="color: #666666">.</span>sleep(<span style="color: #666666">0.2</span>)
|
|
|
|
|
-
|
|
|
|
|
- <span style="color: #408080; font-style: italic"># Make videos</span>
|
|
|
|
|
- prog <span style="color: #666666">=</span> <span style="color: #BA2121">'ffmpeg'</span>
|
|
|
|
|
- filename <span style="color: #666666">=</span> <span style="color: #BA2121">'tmp_</span><span style="color: #BB6688; font-weight: bold">%04d</span><span style="color: #BA2121">.png'</span>
|
|
|
|
|
- fps <span style="color: #666666">=</span> <span style="color: #666666">6</span>
|
|
|
|
|
- codecs <span style="color: #666666">=</span> {<span style="color: #BA2121">'flv'</span>: <span style="color: #BA2121">'flv'</span>, <span style="color: #BA2121">'mp4'</span>: <span style="color: #BA2121">'libx264'</span>,
|
|
|
|
|
- <span style="color: #BA2121">'webm'</span>: <span style="color: #BA2121">'libvpx'</span>, <span style="color: #BA2121">'ogg'</span>: <span style="color: #BA2121">'libtheora'</span>}
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">for</span> ext <span style="color: #AA22FF; font-weight: bold">in</span> codecs:
|
|
|
|
|
- lib <span style="color: #666666">=</span> codecs[ext]
|
|
|
|
|
- cmd <span style="color: #666666">=</span> <span style="color: #BA2121">'</span><span style="color: #BB6688; font-weight: bold">%(prog)s</span><span style="color: #BA2121"> -i </span><span style="color: #BB6688; font-weight: bold">%(filename)s</span><span style="color: #BA2121"> -r </span><span style="color: #BB6688; font-weight: bold">%(fps)s</span><span style="color: #BA2121"> '</span> <span style="color: #666666">%</span> <span style="color: #008000">vars</span>()
|
|
|
|
|
- cmd <span style="color: #666666">+=</span> <span style="color: #BA2121">'-vcodec </span><span style="color: #BB6688; font-weight: bold">%(lib)s</span><span style="color: #BA2121"> movie.</span><span style="color: #BB6688; font-weight: bold">%(ext)s</span><span style="color: #BA2121">'</span> <span style="color: #666666">%</span> <span style="color: #008000">vars</span>()
|
|
|
|
|
- <span style="color: #008000; font-weight: bold">print</span>(cmd)
|
|
|
|
|
- os<span style="color: #666666">.</span>system(cmd)
|
|
|
|
|
-</pre></div>
|
|
|
|
|
-<p>
|
|
|
|
|
-This time we did not use the <code>animate</code> function from Pysketcher, but
|
|
|
|
|
-stored each sketch in a file with <code>drawing_tool.savefig</code>. Note that
|
|
|
|
|
-the argument <code>crop=False</code> is key: otherwise each figure is cropped and
|
|
|
|
|
-it makes to sense to combine the images to a video. By default,
|
|
|
|
|
-Pysketcher crops (removes all exterior whitespace) from figures saved
|
|
|
|
|
-to file.
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-
|
|
|
|
|
-<div>
|
|
|
|
|
-<video loop controls width='640' height='365' preload='none'>
|
|
|
|
|
- <source src='https://github.com/hplgit/pysketcher/raw/master/doc/pub/tutorial/mov-tut/pendulum/movie.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
|
|
|
|
|
- <source src='https://github.com/hplgit/pysketcher/raw/master/doc/pub/tutorial/mov-tut/pendulum/movie.webm' type='video/webm; codecs="vp8, vorbis"'>
|
|
|
|
|
- <source src='https://github.com/hplgit/pysketcher/raw/master/doc/pub/tutorial/mov-tut/pendulum/movie.ogg' type='video/ogg; codecs="theora, vorbis"'>
|
|
|
|
|
-</video>
|
|
|
|
|
-</div>
|
|
|
|
|
-<p><em>The drag force is magnified 5 times (compared to \( mg \) and \( S \)!</em></p>
|
|
|
|
|
-
|
|
|
|
|
-<!-- Issue warning if in a Safari browser -->
|
|
|
|
|
-<script language="javascript">
|
|
|
|
|
-if (!!(window.safari)) {
|
|
|
|
|
- document.write("<div style=\"width: 95%%; padding: 10px; border: 1px solid #100; border-radius: 4px;\"><p><font color=\"red\">The above movie will not play in Safari - use Chrome, Firefox, or Opera.</font></p></div>")}
|
|
|
|
|
-</script>
|
|
|
|
|
-
|
|
|
|
|
-<p>
|
|
|
|
|
-<p>
|
|
|
|
|
-<!-- navigation buttons at the bottom of the page -->
|
|
|
|
|
-<ul class="pagination">
|
|
|
|
|
-<li><a href="._pysketcher002.html">«</a></li>
|
|
|
|
|
- <li><a href="._pysketcher000.html">1</a></li>
|
|
|
|
|
- <li><a href="._pysketcher001.html">2</a></li>
|
|
|
|
|
- <li><a href="._pysketcher002.html">3</a></li>
|
|
|
|
|
- <li class="active"><a href="._pysketcher003.html">4</a></li>
|
|
|
|
|
- <li><a href="._pysketcher004.html">5</a></li>
|
|
|
|
|
- <li><a href="._pysketcher005.html">6</a></li>
|
|
|
|
|
- <li><a href="._pysketcher004.html">»</a></li>
|
|
|
|
|
-</ul>
|
|
|
|
|
-<!-- ------------------- end of main content --------------- -->
|
|
|
|
|
-
|
|
|
|
|
-</div> <!-- end container -->
|
|
|
|
|
-<!-- include javascript, jQuery *first* -->
|
|
|
|
|
-<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
|
|
|
|
-<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
|
|
|
|
|
-
|
|
|
|
|
-<!-- Bootstrap footer
|
|
|
|
|
-<footer>
|
|
|
|
|
-<a href="http://..."><img width="250" align=right src="http://..."></a>
|
|
|
|
|
-</footer>
|
|
|
|
|
--->
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-</body>
|
|
|
|
|
-</html>
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|