/usr/share/doc/python3-pyx-doc/manual/graphics.html is in python3-pyx-doc 0.13-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Basic graphics — PyX 0.13 Manual</title>
<link rel="stylesheet" href="_static/pyx.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.13',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="PyX 0.13 Manual" href="index.html" />
<link rel="next" title="Module path" href="path.html" />
<link rel="prev" title="Introduction" href="intro.html" />
</head>
<body>
<div class="relatedtop">
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="path.html" title="Module path"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="intro.html" title="Introduction"
accesskey="P">previous</a> |</li>
<li><a href="http://pyx.sourceforge.net">PyX Homepage</a> »</li>
<li><a href="manual.html">PyX 0.13 Manual</a> »</li>
<li>Basic graphics</li>
</ul>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="basic-graphics">
<span id="graphics"></span><h1>Basic graphics<a class="headerlink" href="#basic-graphics" title="Permalink to this headline">¶</a></h1>
<div class="section" id="introduction">
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
<p>The path module allows one to construct PostScript-like <em>paths</em>, which are one
of the main building blocks for the generation of drawings. A PostScript path is
an arbitrary shape consisting of straight lines, arc segments and cubic Bézier
curves. Such a path does not have to be connected but may also comprise several
disconnected segments, which will be called <em>subpaths</em> in the following.</p>
<div class="admonition-todo admonition" id="index-0">
<p class="first admonition-title">Todo</p>
<p class="last">example for paths and subpaths (figure)</p>
</div>
<p>Usually, a path is constructed by passing a list of the path primitives
<tt class="xref py py-class docutils literal"><span class="pre">moveto</span></tt>, <tt class="xref py py-class docutils literal"><span class="pre">lineto</span></tt>, <tt class="xref py py-class docutils literal"><span class="pre">curveto</span></tt>, etc., to the constructor of
the <a class="reference internal" href="path.html#module-path" title="path"><tt class="xref py py-class docutils literal"><span class="pre">path</span></tt></a> class. The following code snippet, for instance, defines a
path <em>p</em> that consists of a straight line from the point <span class="math">\((0, 0)\)</span> to the
point <span class="math">\((1, 1)\)</span></p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">pyx</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">path</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">moveto</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
</pre></div>
</div>
<p>Equivalently, one can also use the predefined <a class="reference internal" href="path.html#module-path" title="path"><tt class="xref py py-class docutils literal"><span class="pre">path</span></tt></a> subclass
<tt class="xref py py-class docutils literal"><span class="pre">line</span></tt> and write</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">p</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">line</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
<p>While already some geometrical operations can be performed with this path (see
next section), another PyX object is needed in order to actually being able to
draw the path, namely an instance of the <a class="reference internal" href="canvas.html#module-canvas" title="canvas"><tt class="xref py py-class docutils literal"><span class="pre">canvas</span></tt></a> class. By convention,
we use the name <em>c</em> for this instance:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">c</span> <span class="o">=</span> <span class="n">canvas</span><span class="o">.</span><span class="n">canvas</span><span class="p">()</span>
</pre></div>
</div>
<p>In order to draw the path on the canvas, we use the <tt class="xref py py-meth docutils literal"><span class="pre">stroke()</span></tt> method of the
<a class="reference internal" href="canvas.html#module-canvas" title="canvas"><tt class="xref py py-class docutils literal"><span class="pre">canvas</span></tt></a> class, i.e.,</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
<span class="n">c</span><span class="o">.</span><span class="n">writeEPSfile</span><span class="p">(</span><span class="s">"line"</span><span class="p">)</span>
</pre></div>
</div>
<p>To complete the example, we have added a <tt class="xref py py-meth docutils literal"><span class="pre">writeEPSfile()</span></tt> call, which writes
the contents of the canvas to the file <tt class="file docutils literal"><span class="pre">line.eps</span></tt>. Note that an extension
<tt class="file docutils literal"><span class="pre">.eps</span></tt> is added automatically, if not already present in the given
filename. Similarly, if you want to generate a PDF file instead, use</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">c</span><span class="o">.</span><span class="n">writePDFfile</span><span class="p">(</span><span class="s">"line"</span><span class="p">)</span>
</pre></div>
</div>
<p>As a second example, let us define a path which consists of more than one
subpath:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">cross</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">path</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">moveto</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">rlineto</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span>
<span class="n">path</span><span class="o">.</span><span class="n">moveto</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">rlineto</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
</pre></div>
</div>
<p>The first subpath is again a straight line from <span class="math">\((0, 0)\)</span> to <span class="math">\((1,
1)\)</span>, with the only difference that we now have used the <tt class="xref py py-class docutils literal"><span class="pre">rlineto</span></tt> class,
whose arguments count relative from the last point in the path. The second
<tt class="xref py py-class docutils literal"><span class="pre">moveto</span></tt> instance opens a new subpath starting at the point <span class="math">\((1,
0)\)</span> and ending at <span class="math">\((0, 1)\)</span>. Note that although both lines intersect at the
point <span class="math">\((1/2, 1/2)\)</span>, they count as disconnected subpaths. The general rule
is that each occurrence of a <tt class="xref py py-class docutils literal"><span class="pre">moveto</span></tt> instance opens a new subpath. This
means that if one wants to draw a rectangle, one should not use</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">rect1</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">path</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">moveto</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span>
<span class="n">path</span><span class="o">.</span><span class="n">moveto</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span>
<span class="n">path</span><span class="o">.</span><span class="n">moveto</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
<span class="n">path</span><span class="o">.</span><span class="n">moveto</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
</pre></div>
</div>
<p>which would construct a rectangle out of four disconnected subpaths (see Fig.
<a class="reference internal" href="#fig-rects"><em>Rectangle example</em></a> a). In a better solution (see Fig. <a class="reference internal" href="#fig-rects"><em>Rectangle example</em></a> b), the
pen is not lifted between the first and the last point:</p>
<div class="figure align-center" id="fig-rects">
<img alt="_images/rects.png" src="_images/rects.png" />
<p class="caption">Rectangle example</p>
<div class="legend">
Rectangle consisting of (a) four separate lines, (b) one open path, and (c) one closed path. (d) Filling a path always closes it automatically.</div>
</div>
<div class="highlight-python"><div class="highlight"><pre><span class="n">rect2</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">path</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">moveto</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span>
<span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
<span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
</pre></div>
</div>
<p>However, as one can see in the lower left corner of Fig. <a class="reference internal" href="#fig-rects"><em>Rectangle example</em></a> b,
the rectangle is still incomplete. It needs to be closed, which can be done
explicitly by using for the last straight line of the rectangle (from the point
<span class="math">\((0, 1)\)</span> back to the origin at <span class="math">\((0, 0)\)</span>) the <tt class="xref py py-class docutils literal"><span class="pre">closepath</span></tt>
directive:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">rect3</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">path</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">moveto</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span>
<span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
<span class="n">path</span><span class="o">.</span><span class="n">closepath</span><span class="p">())</span>
</pre></div>
</div>
<p>The <tt class="xref py py-class docutils literal"><span class="pre">closepath</span></tt> directive adds a straight line from the current point to
the first point of the current subpath and furthermore <em>closes</em> the sub path,
i.e., it joins the beginning and the end of the line segment. This results in
the intended rectangle shown in Fig. <a class="reference internal" href="#fig-rects"><em>Rectangle example</em></a> c. Note that filling the
path implicitly closes every open subpath, as is shown for a single subpath in
Fig. <a class="reference internal" href="#fig-rects"><em>Rectangle example</em></a> d), which results from</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">rect2</span><span class="p">,</span> <span class="p">[</span><span class="n">deco</span><span class="o">.</span><span class="n">filled</span><span class="p">([</span><span class="n">color</span><span class="o">.</span><span class="n">grey</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)])])</span>
</pre></div>
</div>
<p>Here, we supply as second argument of the <tt class="xref py py-meth docutils literal"><span class="pre">stroke()</span></tt> method a list which in
the present case only consists of a single element, namely the so called
decorator <tt class="xref py py-class docutils literal"><span class="pre">deco.filled</span></tt>. As its name says, this decorator specifies that
the path is not only being stroked but also filled with the given color. More
information about decorators, styles and other attributes which can be passed as
elements of the list can be found in Sect. <a class="reference internal" href="#graphics-attributes"><em>Attributes: Styles and Decorations</em></a>. More
details on the available path elements can be found in Sect.
<a class="reference internal" href="path.html#path-pathitem"><em>Path elements</em></a>.</p>
<p>To conclude this section, we should not forget to mention that rectangles are,
of course, predefined in PyX, so above we could have as well written</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">rect2</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">rect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
<p>Here, the first two arguments specify the origin of the rectangle while the
second two arguments define its width and height, respectively. For more details
on the predefined paths, we refer the reader to Sect. <a class="reference internal" href="path.html#path-predefined"><em>Predefined paths</em></a>.</p>
</div>
<div class="section" id="path-operations">
<h2>Path operations<a class="headerlink" href="#path-operations" title="Permalink to this headline">¶</a></h2>
<p>Often, one wants to perform geometrical operations with a path before placing it
on a canvas by stroking or filling it. For instance, one might want to
intersect one path with another one, split the paths at the intersection points,
and then join the segments together in a new way. PyX supports such tasks by
means of a number of path methods, which we will introduce in the following.</p>
<p>Suppose you want to draw the radii to the intersection points of a circle with a
straight line. This task can be done using the following code which results in
Fig. <a class="reference internal" href="#fig-radii"><em>Example: Intersection of circle with line yielding two radii</em></a></p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">pyx</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">canvas</span><span class="o">.</span><span class="n">canvas</span><span class="p">()</span>
<span class="n">circle</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">circle</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">line</span><span class="p">(</span><span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">circle</span><span class="p">,</span> <span class="p">[</span><span class="n">style</span><span class="o">.</span><span class="n">linewidth</span><span class="o">.</span><span class="n">Thick</span><span class="p">])</span>
<span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="p">[</span><span class="n">style</span><span class="o">.</span><span class="n">linewidth</span><span class="o">.</span><span class="n">Thick</span><span class="p">])</span>
<span class="n">isects_circle</span><span class="p">,</span> <span class="n">isects_line</span> <span class="o">=</span> <span class="n">circle</span><span class="o">.</span><span class="n">intersect</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="k">for</span> <span class="n">isect</span> <span class="ow">in</span> <span class="n">isects_circle</span><span class="p">:</span>
<span class="n">isectx</span><span class="p">,</span> <span class="n">isecty</span> <span class="o">=</span> <span class="n">circle</span><span class="o">.</span><span class="n">at</span><span class="p">(</span><span class="n">isect</span><span class="p">)</span>
<span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">line</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">isectx</span><span class="p">,</span> <span class="n">isecty</span><span class="p">))</span>
<span class="n">c</span><span class="o">.</span><span class="n">writePDFfile</span><span class="p">()</span>
</pre></div>
</div>
<div class="figure align-center" id="fig-radii">
<img alt="_images/radii.png" src="_images/radii.png" />
<p class="caption">Example: Intersection of circle with line yielding two radii</p>
</div>
<p>Here, the basic elements, a circle around the point <span class="math">\((0, 0)\)</span> with radius
<span class="math">\(2\)</span> and a straight line, are defined. Then, passing the <em>line</em>, to the
<tt class="xref py py-meth docutils literal"><span class="pre">intersect()</span></tt> method of <em>circle</em>, we obtain a tuple of parameter values of
the intersection points. The first element of the tuple is a list of parameter
values for the path whose <tt class="xref py py-meth docutils literal"><span class="pre">intersect()</span></tt> method has been called, the second
element is the corresponding list for the path passed as argument to this
method. In the present example, we only need one list of parameter values,
namely <em>isects_circle</em>. Using the <tt class="xref py py-meth docutils literal"><span class="pre">at()</span></tt> path method to obtain the point
corresponding to the parameter value, we draw the radii for the different
intersection points.</p>
<p>Another powerful feature of PyX is its ability to split paths at a given set of
parameters. For instance, in order to fill in the previous example the segment
of the circle delimited by the straight line (cf. Fig. <a class="reference internal" href="#fig-radii2"><em>Example: Intersection of circle with line yielding radii and circle segment</em></a>), one
first has to construct a path corresponding to the outline of this segment. The
following code snippet yields this <em>segment</em></p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">arc1</span><span class="p">,</span> <span class="n">arc2</span> <span class="o">=</span> <span class="n">circle</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">isects_circle</span><span class="p">)</span>
<span class="k">if</span> <span class="n">arc1</span><span class="o">.</span><span class="n">arclen</span><span class="p">()</span> <span class="o"><</span> <span class="n">arc2</span><span class="o">.</span><span class="n">arclen</span><span class="p">():</span>
<span class="n">arc</span> <span class="o">=</span> <span class="n">arc1</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">arc</span> <span class="o">=</span> <span class="n">arc2</span>
<span class="n">isects_line</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span>
<span class="n">line1</span><span class="p">,</span> <span class="n">line2</span><span class="p">,</span> <span class="n">line3</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">isects_line</span><span class="p">)</span>
<span class="n">segment</span> <span class="o">=</span> <span class="n">line2</span> <span class="o"><<</span> <span class="n">arc</span>
</pre></div>
</div>
<div class="figure align-center" id="fig-radii2">
<img alt="_images/radii2.png" src="_images/radii2.png" />
<p class="caption">Example: Intersection of circle with line yielding radii and circle segment</p>
</div>
<p>Here, we first split the circle using the <tt class="xref py py-meth docutils literal"><span class="pre">split()</span></tt> method passing the list
of parameters obtained above. Since the circle is closed, this yields two arc
segments. We then use the <tt class="xref py py-meth docutils literal"><span class="pre">arclen()</span></tt>, which returns the arc length of the
path, to find the shorter of the two arcs. Before splitting the line, we have to
take into account that the <tt class="xref py py-meth docutils literal"><span class="pre">split()</span></tt> method only accepts a sorted list of
parameters. Finally, we join the straight line and the arc segment. For this, we
make use of the <tt class="docutils literal"><span class="pre"><<</span></tt> operator, which not only adds the paths (which could be
done using <tt class="docutils literal"><span class="pre">line2</span> <span class="pre">+</span> <span class="pre">arc</span></tt>), but also joins the last subpath of <em>line2</em> and the
first one of <em>arc</em>. Thus, <em>segment</em> consists of only a single subpath and
filling works as expected.</p>
<p>An important issue when operating on paths is the parametrisation used.
Internally, PyX uses a parametrisation which uses an interval of length
<span class="math">\(1\)</span> for each path element of a path. For instance, for a simple straight
line, the possible parameter values range from <span class="math">\(0\)</span> to <span class="math">\(1\)</span>,
corresponding to the first and last point, respectively, of the line. Appending
another straight line, would extend this range to a maximal value of <span class="math">\(2\)</span>.</p>
<p>However, the situation becomes more complicated if more complex objects like a
circle are involved. Then, one could be tempted to assume that again the
parameter value ranges from <span class="math">\(0\)</span> to <span class="math">\(1\)</span>, because the predefined
circle consists just of one <tt class="xref py py-class docutils literal"><span class="pre">arc</span></tt> together with a <tt class="xref py py-class docutils literal"><span class="pre">closepath</span></tt>
element. However, this is not the case: the actual range is much larger. The
reason for this behaviour lies in the internal path handling of PyX: Before
performing any non-trivial geometrical operation on a path, it will
automatically be converted into an instance of the <tt class="xref py py-class docutils literal"><span class="pre">normpath</span></tt> class (see
also Sect. <a class="reference internal" href="path.html#path.normpath" title="path.normpath"><tt class="xref py py-class docutils literal"><span class="pre">path.normpath</span></tt></a>). These so generated paths are already separated
in their subpaths and only contain straight lines and Bézier curve segments.
XXX explain normpathparams and things like p.begin(), p.end()-1,</p>
<p>A more geometrical way of accessing a point on the path is to use the arc length
of the path segment from the first point of the path to the given point. Thus,
all PyX path methods that accept a parameter value also allow the user to pass
an arc length. For instance,</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">math</span> <span class="kn">import</span> <span class="n">pi</span>
<span class="n">r</span> <span class="o">=</span> <span class="mi">2</span>
<span class="n">pt1</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">circle</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span><span class="o">.</span><span class="n">at</span><span class="p">(</span><span class="n">r</span><span class="o">*</span><span class="n">pi</span><span class="p">)</span>
<span class="n">pt2</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">circle</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span><span class="o">.</span><span class="n">at</span><span class="p">(</span><span class="n">r</span><span class="o">*</span><span class="mi">3</span><span class="o">*</span><span class="n">pi</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span>
<span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">path</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">moveto</span><span class="p">(</span><span class="o">*</span><span class="n">pt1</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">lineto</span><span class="p">(</span><span class="o">*</span><span class="n">pt2</span><span class="p">)))</span>
</pre></div>
</div>
<p>will draw a straight line from a point at angle <span class="math">\(180\)</span> degrees (in radians
<span class="math">\(\pi\)</span>) to another point at angle <span class="math">\(270\)</span> degrees (in radians
<span class="math">\(3\pi/2\)</span>) on a circle with radius <span class="math">\(r=2\)</span>. Note however, that the
mapping from an arc length to a point is in general discontinuous at the beginning
and the end of a subpath, and thus PyX does not guarantee any particular result
for this boundary case.</p>
<p>More information on the available path methods can be found in Sect. <a class="reference internal" href="path.html#postscript-like-paths"><em>Class path — PostScript-like paths</em></a>.</p>
</div>
<div class="section" id="attributes-styles-and-decorations">
<span id="graphics-attributes"></span><h2>Attributes: Styles and Decorations<a class="headerlink" href="#attributes-styles-and-decorations" title="Permalink to this headline">¶</a></h2>
<p>Attributes define properties of a given object when it is being used. Typically,
there are different kinds of attributes which are usually orthogonal to each
other, while for one type of attribute, several choices are possible. An example
is the stroking of a path. There, linewidth and linestyle are different kind of
attributes. The linewidth might be thin, normal, thick, etc., and the linestyle
might be solid, dashed etc.</p>
<p>Attributes always occur in lists passed as an optional keyword argument to a
method or a function. Usually, attributes are the first keyword argument, so one
can just pass the list without specifying the keyword. Again, for the path
example, a typical call looks like</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="p">[</span><span class="n">style</span><span class="o">.</span><span class="n">linewidth</span><span class="o">.</span><span class="n">Thick</span><span class="p">,</span> <span class="n">style</span><span class="o">.</span><span class="n">linestyle</span><span class="o">.</span><span class="n">dashed</span><span class="p">])</span>
</pre></div>
</div>
<p>Here, we also encounter another feature of PyX’s attribute system. For many
attributes useful default values are stored as member variables of the actual
attribute. For instance, <tt class="docutils literal"><span class="pre">style.linewidth.Thick</span></tt> is equivalent to
<tt class="docutils literal"><span class="pre">style.linewidth(0.04,</span> <span class="pre">type="w",</span> <span class="pre">unit="cm")</span></tt>, that is <span class="math">\(0.04\)</span> width cm
(see Sect. <a class="reference internal" href="unit.html#id1"><em>Module unit</em></a> for more information about PyX’s unit system).</p>
<p>Another important feature of PyX attributes is what is call attributed merging.
A trivial example is the following:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c"># the following two lines are equivalent</span>
<span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="p">[</span><span class="n">style</span><span class="o">.</span><span class="n">linewidth</span><span class="o">.</span><span class="n">Thick</span><span class="p">,</span> <span class="n">style</span><span class="o">.</span><span class="n">linewidth</span><span class="o">.</span><span class="n">thin</span><span class="p">])</span>
<span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="p">[</span><span class="n">style</span><span class="o">.</span><span class="n">linewidth</span><span class="o">.</span><span class="n">thin</span><span class="p">])</span>
</pre></div>
</div>
<p>Here, the <tt class="docutils literal"><span class="pre">style.linewidth.thin</span></tt> attribute overrides the preceding
<tt class="docutils literal"><span class="pre">style.linewidth.Thick</span></tt> declaration. This is especially important in more
complex cases where PyX defines default attributes for a certain operation. When
calling the corresponding methods with an attribute list, this list is appended
to the list of defaults. This way, the user can easily override certain
defaults, while leaving the other default values intact. In addition, every
attribute kind defines a special clear attribute, which allows to selectively
delete a default value. For path stroking this looks like</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c"># the following two lines are equivalent</span>
<span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="p">[</span><span class="n">style</span><span class="o">.</span><span class="n">linewidth</span><span class="o">.</span><span class="n">Thick</span><span class="p">,</span> <span class="n">style</span><span class="o">.</span><span class="n">linewidth</span><span class="o">.</span><span class="n">clear</span><span class="p">])</span>
<span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</pre></div>
</div>
<p>The clear attribute is also provided by the base classes of the various styles.
For instance, <tt class="xref py py-class docutils literal"><span class="pre">style.strokestyle.clear</span></tt> clears all strokestyle subclasses
i.e. <tt class="xref py py-class docutils literal"><span class="pre">style.linewidth</span></tt> and <tt class="xref py py-class docutils literal"><span class="pre">style.linestyle</span></tt>. Since all
attributes derive from <tt class="xref py py-class docutils literal"><span class="pre">attr.attr</span></tt>, you can remove all defaults using
<tt class="docutils literal"><span class="pre">attr.clear</span></tt>. An overview over the most important attribute types provided by
PyX is given in the following table.</p>
<table border="1" class="docutils">
<colgroup>
<col width="29%" />
<col width="34%" />
<col width="37%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Attribute category</th>
<th class="head">description</th>
<th class="head">examples</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><tt class="xref py py-class docutils literal"><span class="pre">deco.deco</span></tt></td>
<td>decorator specifying the way
the path is drawn</td>
<td><tt class="xref py py-class docutils literal"><span class="pre">deco.stroked</span></tt>,
<tt class="xref py py-class docutils literal"><span class="pre">deco.filled</span></tt>,
<tt class="xref py py-class docutils literal"><span class="pre">deco.arrow</span></tt>,
<tt class="xref py py-class docutils literal"><span class="pre">deco.text</span></tt></td>
</tr>
<tr class="row-odd"><td><tt class="xref py py-class docutils literal"><span class="pre">style.strokestyle</span></tt></td>
<td>style used for path stroking</td>
<td><tt class="xref py py-class docutils literal"><span class="pre">style.linecap</span></tt>,
<tt class="xref py py-class docutils literal"><span class="pre">style.linejoin</span></tt>,
<tt class="xref py py-class docutils literal"><span class="pre">style.miterlimit</span></tt>,
<tt class="xref py py-class docutils literal"><span class="pre">style.dash</span></tt>,
<tt class="xref py py-class docutils literal"><span class="pre">style.linestyle</span></tt>,
<tt class="xref py py-class docutils literal"><span class="pre">style.linewidth</span></tt>,
<tt class="xref py py-class docutils literal"><span class="pre">color.color</span></tt></td>
</tr>
<tr class="row-even"><td><tt class="xref py py-class docutils literal"><span class="pre">style.fillstyle</span></tt></td>
<td>style used for path filling</td>
<td><tt class="xref py py-class docutils literal"><span class="pre">color.color</span></tt>,
<tt class="xref py py-class docutils literal"><span class="pre">pattern.pattern</span></tt></td>
</tr>
<tr class="row-odd"><td><tt class="xref py py-class docutils literal"><span class="pre">style.filltype</span></tt></td>
<td>type of path filling</td>
<td><tt class="docutils literal"><span class="pre">style.fillrule.nonzero_winding</span></tt>
(default),
<tt class="docutils literal"><span class="pre">style.fillrule.even_odd</span></tt></td>
</tr>
<tr class="row-even"><td><a class="reference internal" href="deformer.html#deformer.deformer" title="deformer.deformer"><tt class="xref py py-class docutils literal"><span class="pre">deformer.deformer</span></tt></a></td>
<td>operations changing the shape
of the path</td>
<td><a class="reference internal" href="deformer.html#deformer.cycloid" title="deformer.cycloid"><tt class="xref py py-class docutils literal"><span class="pre">deformer.cycloid</span></tt></a>,
<a class="reference internal" href="deformer.html#deformer.smoothed" title="deformer.smoothed"><tt class="xref py py-class docutils literal"><span class="pre">deformer.smoothed</span></tt></a></td>
</tr>
<tr class="row-odd"><td><tt class="xref py py-class docutils literal"><span class="pre">text.textattr</span></tt></td>
<td>attributes used for typesetting</td>
<td><a class="reference internal" href="text.html#text.halign" title="text.halign"><tt class="xref py py-class docutils literal"><span class="pre">text.halign</span></tt></a>,
<a class="reference internal" href="text.html#text.valign" title="text.valign"><tt class="xref py py-class docutils literal"><span class="pre">text.valign</span></tt></a>,
<a class="reference internal" href="text.html#text.mathmode" title="text.mathmode"><tt class="xref py py-class docutils literal"><span class="pre">text.mathmode</span></tt></a>,
<a class="reference internal" href="text.html#text.phantom" title="text.phantom"><tt class="xref py py-class docutils literal"><span class="pre">text.phantom</span></tt></a>,
<a class="reference internal" href="text.html#text.size" title="text.size"><tt class="xref py py-class docutils literal"><span class="pre">text.size</span></tt></a>,
<a class="reference internal" href="text.html#text.parbox" title="text.parbox"><tt class="xref py py-class docutils literal"><span class="pre">text.parbox</span></tt></a></td>
</tr>
<tr class="row-even"><td><a class="reference internal" href="trafo.html#trafo.trafo" title="trafo.trafo"><tt class="xref py py-class docutils literal"><span class="pre">trafo.trafo</span></tt></a></td>
<td>transformations applied when
drawing object</td>
<td><a class="reference internal" href="trafo.html#trafo.mirror" title="trafo.mirror"><tt class="xref py py-class docutils literal"><span class="pre">trafo.mirror</span></tt></a>,
<a class="reference internal" href="trafo.html#trafo.rotate" title="trafo.rotate"><tt class="xref py py-class docutils literal"><span class="pre">trafo.rotate</span></tt></a>,
<a class="reference internal" href="trafo.html#trafo.scale" title="trafo.scale"><tt class="xref py py-class docutils literal"><span class="pre">trafo.scale</span></tt></a>,
<a class="reference internal" href="trafo.html#trafo.slant" title="trafo.slant"><tt class="xref py py-class docutils literal"><span class="pre">trafo.slant</span></tt></a>,
<a class="reference internal" href="trafo.html#trafo.translate" title="trafo.translate"><tt class="xref py py-class docutils literal"><span class="pre">trafo.translate</span></tt></a></td>
</tr>
</tbody>
</table>
<div class="admonition-todo admonition" id="index-1">
<p class="first admonition-title">Todo</p>
<p class="last">specify which classes in the table are in fact instances</p>
</div>
<p>Note that operations usually allow for certain attribute categories only. For
example when stroking a path, text attributes are not allowed, while stroke
attributes and decorators are. Some attributes might belong to several attribute
categories like colours, which are both, stroke and fill attributes.</p>
<p>Last, we discuss another important feature of PyX’s attribute system. In order
to allow the easy customisation of predefined attributes, it is possible to
create a modified attribute by calling of an attribute instance, thereby
specifying new parameters. A typical example is to modify the way a path is
stroked or filled by constructing appropriate <tt class="xref py py-class docutils literal"><span class="pre">deco.stroked</span></tt> or
<tt class="xref py py-class docutils literal"><span class="pre">deco.filled</span></tt> instances. For instance, the code</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="p">[</span><span class="n">deco</span><span class="o">.</span><span class="n">filled</span><span class="p">([</span><span class="n">color</span><span class="o">.</span><span class="n">rgb</span><span class="o">.</span><span class="n">green</span><span class="p">])])</span>
</pre></div>
</div>
<p>draws a path filled in green with a black outline. Here, <tt class="docutils literal"><span class="pre">deco.filled</span></tt> is
already an instance which is modified to fill with the given color. Note that
an equivalent version would be</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">c</span><span class="o">.</span><span class="n">draw</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="p">[</span><span class="n">deco</span><span class="o">.</span><span class="n">stroked</span><span class="p">,</span> <span class="n">deco</span><span class="o">.</span><span class="n">filled</span><span class="p">([</span><span class="n">color</span><span class="o">.</span><span class="n">rgb</span><span class="o">.</span><span class="n">green</span><span class="p">])])</span>
</pre></div>
</div>
<p>In particular, you can see that <tt class="xref py py-class docutils literal"><span class="pre">deco.stroked</span></tt> is already an attribute
instance, since otherwise you were not allowed to pass it as a parameter to the
draw method. Another example where the modification of a decorator is useful
are arrows. For instance, the following code draws an arrow head with a more
acute angle (compared to the default value of <span class="math">\(45\)</span> degrees):</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">c</span><span class="o">.</span><span class="n">stroke</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="p">[</span><span class="n">deco</span><span class="o">.</span><span class="n">earrow</span><span class="p">(</span><span class="n">angle</span><span class="o">=</span><span class="mi">30</span><span class="p">)])</span>
</pre></div>
</div>
<div class="admonition-todo admonition" id="index-2">
<p class="first admonition-title">Todo</p>
<p class="last">changeable attributes</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<div class="sidebarbox">
<h3><a href="manual.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Basic graphics</a><ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#path-operations">Path operations</a></li>
<li><a class="reference internal" href="#attributes-styles-and-decorations">Attributes: Styles and Decorations</a></li>
</ul>
</li>
</ul>
</div>
<div class="sidebarbox">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/graphics.txt"
rel="nofollow">Show Source</a></li>
</ul></div>
<div class="sidebarbox">
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script></div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="relatedbottom">
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="path.html" title="Module path"
>next</a> |</li>
<li class="right" >
<a href="intro.html" title="Introduction"
>previous</a> |</li>
<li><a href="http://pyx.sourceforge.net">PyX Homepage</a> »</li>
<li><a href="manual.html">PyX 0.13 Manual</a> »</li>
<li>Basic graphics</li>
</ul>
</div>
</div>
<div class="footer">
© Copyright 2013, Jörg Lehmann, Michael Schindler, André Wobst.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>
|