played a little with settings for headstyle - causes strange numbers - check!!
[cluster_expansion_thesis.git] / little_helpers / tikz / sketch-0.2.161 / Doc / sketch.texi
blobb85d78048160ff227c531ced90fcf12d7098d2f1
1 \input texinfo   @c -*-texinfo-*-\r
2 @c %**start of header\r
3 @setfilename sketch.info\r
4 @include version.texi\r
5 @settitle Sketch\r
6 \r
7 @c an index for sketch commands\r
8 @defcodeindex sx\r
9 @defcodeindex op\r
10 @syncodeindex op sx\r
11 @c %**end of header\r
13 @copying\r
14 Copyright @copyright{} 2005, 2006, 2007, 2008 Eugene K. Ressler.\r
16 This manual is for @code{sketch}, version @value{VERSION},\r
17 @value{UPDATED}, a program that converts descriptions of simple\r
18 three-dimensional scenes into static drawings. This version generates\r
19 @code{PSTricks} or @code{PGF/TikZ} code suitable for use with the\r
20 @TeX{} document processing system.\r
22 @code{Sketch} is free software; you can redistribute it and/or modify\r
23 it under the terms of the GNU General Public License as published by\r
24 the Free Software Foundation; either version 3, or (at your option)\r
25 any later version.\r
27 Sketch is distributed in the hope that it will be useful,\r
28 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
30 GNU General Public License for more details.\r
32 You should have received a copy of the GNU General Public License\r
33 along with @code{sketch}; see the file COPYING.txt.  If not, see\r
34 @verb{|http://www.gnu.org/copyleft|}.\r
36 @end copying\r
38 @dircategory TeX\r
39 @direntry\r
40 * Sketch: (sketch).             Simple 3D sketching for TeX\r
41 @end direntry\r
42  \r
43 @titlepage\r
44 @title Sketch\r
45 @subtitle Simple 3D sketching\r
46 @subtitle Version @value{VERSION}, @value{UPDATED}\r
47 @author Gene Ressler\r
48 @page\r
49 @vskip 0pt plus 1fill\r
50 @insertcopying\r
51 @end titlepage\r
53 @c TOC\r
54 @contents\r
56 @ifnottex\r
57 @node Top, About sketch, (dir), (dir)\r
58 @top Sketch\r
60 @insertcopying\r
61 @end ifnottex\r
63 @menu\r
64 * About sketch::                Why sketch exists and what it does.\r
65 * Introduction by example::     Most features shown as working code.\r
66 * Input language::              Syntax and semantics of @code{sketch} commands. \r
67 * Building a drawing::          How to use @code{sketch} productively.\r
68 * Command line::                Options and their usage.\r
69 * Installing sketch::           Building and installing from sources.\r
70 * Index of syntax::             \r
71 * Index::                       \r
73 @detailmenu\r
74  --- The Detailed Node Listing ---\r
76 About sketch\r
78 * Reporting bugs::              Let use know what's wrong!\r
79 * Contributions::               How you can help@dots{}.\r
81 Introduction by example\r
83 * Hello world::                 Simplest possible @code{sketch} program.\r
84 * Drawing options::             Controlling object appearance.\r
85 * Drawing a solid::             Drawing an object with 3d appearance.\r
86 * Special objects::             Laying @TeX{} over, in, or under drawings.\r
87 * Object transforms::           Rotate, translate, scale, and others.\r
88 * Repeated objects::            Making transformed copies.\r
89 * Swept objects::               Sweeping objects in space to make new shapes.\r
91 Swept objects\r
93 * Point sweeps::                Swept points make lines and polygons.\r
94 * Polyline sweeps::             Swept lines make surfaces.\r
95 * Nested sweeps::               Swept sweeps are useful!\r
96 * Polygon sweeps::              Swept polygons make solids...\r
97 * Polyline sweeps with closure::  and so do closed polyline sweeps.\r
98 * Affine arithmetic::           Sketch useful math expression.\r
99 * More to learn::               Check out the Mobius strip!\r
101 Input language\r
103 * Language basics::             Case, space, comments, include files.\r
104 * Drawables::                   Things that can be drawn.\r
105 * Definitions::                 Giving things names.\r
106 * Global environment::          Affect the entire drawing.\r
108 Basics \r
110 * Identifiers::                 Names for things.\r
111 * Key and reserved words::      Names you shouldn't use.\r
112 * Literals::                    Constants and constructors.\r
113 * Arithmetic::                  Rules for expressions.\r
114 * Options::                     Modifying object appearance.\r
116 Literals\r
118 * Scalar literals::             Just the numbers.\r
119 * Point and vector literals::   3d quantities.\r
120 * Transform literals::          Matrix form.\r
122 Arithmetic expressions\r
124 * Two-operand (binary) forms::  A op B\r
125 * Unary forms::                 op A (and others)\r
127 Options\r
129 * PSTricks options::            Options inherited from @code{PSTricks}.\r
130 * TikZ/PGF options::            Options inherited from @code{TikZ/PGF}.\r
131 * Dots in TikZ/PGF::            Sketch uses @code{TikZ/PGF} circles for dots.\r
132 * TikZ/PGF user-defined styles::  Support for @code{TikZ/PGF} named, user-defined styles.\r
133 * Transparency::                See-through polygons.\r
134 * Internal options::            Options used by @code{sketch}.\r
136 Point lists\r
138 * Drawables::                   Things that are drawn.\r
139 * Definitions::                 Things with names.\r
141 Drawables\r
143 * Dots::                        Draw dots.\r
144 * Lines::                       Draw polylines.\r
145 * Curves::                      Draw curves.\r
146 * Polygons::                    Draw polygons.\r
147 * Specials::                    Embed raw @LaTeX{} and @code{PSTricks}.\r
148 * Sweeps::                      Draw sweeps of dots and polylines.\r
149 * Blocks::                      Group other drawables.\r
150 * Repeats::                     Draw transformed copies of objects.\r
151 * Puts::                        Draw one object transformed.\r
153 Sweeps\r
155 * Swept points::                Swept points make lines or polygons.\r
156 * Swept lines::                 Swept lines make open or closed surfaces.\r
157 * Swept polygons::              Swept polygons make closed surfaces.\r
158 * Swept blocks::                Swept block @equiv{} block of sweeps.\r
159 * Sweep face splitting::        Fixing warped faces with triangles.\r
161 Definitions\r
163 * Forms of definitions::        Different defs for different purposes.\r
164 * Forms of references::         How references denote types.\r
166 Global environment\r
168 * Global options::              Attributes of the entire drawing.\r
169 * Camera::                      A final camera transformation of the scene.\r
170 * Picture box::                 Setting the bounding box and 2d clipping.\r
171 * Frame::                       Adding a box around the drawing.\r
172 * Language::                    Setting the output language.\r
174 Building a drawing\r
176 * Overview::                    Building a substantial drawing.\r
177 * A technical drawing::         An example with fine placement.\r
178 * A hierarchical model::        An example with sweeps and puts.\r
179 * Caveats::                     Where trouble can occur.\r
181 Caveats\r
183 * Limits on error detection::   What sketch doesn't do.\r
184 * Clipping::                    No clipping at present.\r
185 * Hidden surface removal::      Imperfections to fix.\r
187 Hidden surface removal and polygon splitting\r
189 * Statistics::                  Performance numbers on depth sort.\r
190 * Bugs and anomalies::          Imperfections in this implementation.\r
192 @end detailmenu\r
193 @end menu\r
195 @node About sketch, Introduction by example, Top, Top\r
196 @comment  node-name,  next,  previous,  up\r
197 @chapter About sketch\r
199 @menu\r
200 * Reporting bugs::              Let use know what's wrong!\r
201 * Contributions::               How you can help@dots{}.\r
202 @end menu\r
204 @code{Sketch} is a small, simple system for producing line drawings of\r
205 two- or three-dimensional objects and scenes.  It began as a way to\r
206 make illustrations for a textbook after we could find no suitable\r
207 tool for this purpose.  Existing scene processors emphasized GUIs\r
208 and/or photo-realism, both un-useful to us.  We wanted to produce\r
209 finely wrought, mathematically-based illustrations with no extraneous\r
210 detail.\r
212 @code{Sketch} accepts a tiny scene description language and generates\r
213 @code{PSTricks} or @code{TikZ/PGF} code for @LaTeX{}.  The\r
214 @code{sketch} language is similar to @code{PSTricks}, making it easy\r
215 to learn for current @code{PSTricks} users.  See\r
216 @cindex PSTricks\r
217 @verb{|www.pstricks.de|} for information on @code{PSTricks}.\r
218 @code{TikZ/PGF} are also very similar except for details of syntax.\r
219 See\r
220 @cindex TikZ/PGF\r
221 @verb{|http://sourceforge.net/projects/pgf|}.  One can easily lay raw\r
222 @code{PSTricks} or @code{TikZ/PGF} output over, in, or under\r
223 @code{sketch} drawings, providing the full power of @LaTeX{} text and\r
224 mathematics formatting in a three-dimensional setting.\r
226 @node Reporting bugs, Contributions, About sketch, About sketch\r
227 @comment  node-name,  next,  previous,  up\r
228 @section Reporting bugs and recommending improvements.\r
229 Report bugs and make suggestions at\r
230 our Google Group @verb{|http://groups.google.com/group/sketch-users|}.\r
231 A second method that will probably produce a slower\r
232 response is email to @verb{|sketch@frontiernet.net|}.\r
233 We will try to respond, but can't promise.  In any event, don't be\r
234 offended if a reply is not forthcoming.  We're just busy and will get\r
235 to your suggestion eventually.\r
237 For bugs, attach a @code{sketch} input file that causes the bad\r
238 behavior.  Embed comments that explain what to look for in\r
239 the behavior of @code{sketch} or its output.\r
241 A recommendation for improvement from one unknown person counts as one\r
242 vote. We use overall vote tallies to decide what to do next as\r
243 resources permit.  We reserve the right to a assign any number of votes\r
244 to suggestions from people who have been helpful and supportive in the\r
245 past.\r
247 @node Contributions,  , Reporting bugs, About sketch\r
248 @comment  node-name,  next,  previous,  up\r
249 @section Contributions\r
250 If you intend to implement an enhancement of your own, that's\r
251 terrific!  Consider collaborating with us first to see if we're\r
252 already working on your idea or if we can use your work in the\r
253 official release.\r
255 @center @image{ex000}\r
256 @anchor{Solid coil example}\r
258 @node Introduction by example, Input language, About sketch, Top\r
259 @comment  node-name,  next,  previous,  up\r
260 @chapter Introduction by example\r
261 The @code{sketch} input language will seem familiar to users of the\r
262 @code{PSTricks} package for @LaTeX{}.  The following program draws a\r
263 triangular polygon pierced by a line.\r
264 @verbatim\r
265   polygon(0,0,1)(1,0,0)(0,1,0)\r
266   line(-1,-1,-1)(2,2,2)\r
267 @end verbatim\r
268 @noindent\r
269 The coordinate system \r
270 @cindex coordinate system, right-handed\r
271 @cindex right-hand coordinate system\r
272 is a standard right-handed Cartesian one.\r
274 @center @image{ex010}\r
276 @menu\r
277 * Hello world::                 Simplest possible @code{sketch} program.\r
278 * Drawing options::             Controlling object appearance.\r
279 * Drawing a solid::             Drawing an object with 3d appearance.\r
280 * Special objects::             Laying @TeX{} over, in, or under drawings.\r
281 * Object transforms::           Rotate, translate, scale, and others.\r
282 * Repeated objects::            Making transformed copies.\r
283 * Swept objects::               Sweeping objects in space to make new shapes.\r
284 @end menu\r
286 @node Hello world, Drawing options, Introduction by example, Introduction by example\r
287 @comment  node-name,  next,  previous,  up\r
288 @section Hello world\r
289 The @code{sketch} program above is nearly the simplest one possible,\r
290 the equivalent of a ``hello world''\r
291 @cindex hello world\r
292 @cindex program, hello world\r
293 program you might find at the start of a programming language text.\r
294 If it is saved in the file @file{simple.sk}, then the command\r
295 @cindex command line, @code{sketch}\r
296 @cindex running @code{sketch}\r
297 @verbatim\r
298   sketch simple.sk -o simple.tex\r
299 @end verbatim\r
300 @noindent\r
301 creates a file @file{simple.tex} containing @code{PSTricks} commands to\r
302 draw these objects on paper.  The contents of @file{simple.tex}\r
303 look like this.\r
304 @verbatim\r
305   \begin{pspicture}(-1,-1)(2,2)\r
306   \pstVerb{1 setlinejoin}\r
307   \psline(-1,-1)(.333,.333)\r
308   \pspolygon[fillstyle=solid,fillcolor=white](0,0)(1,0)(0,1)\r
309   \psline(.333,.333)(2,2)\r
310   \end{pspicture}\r
311 @end verbatim\r
312 @noindent\r
313 The hidden surface algorithm \r
314 @cindex hidden surface algorithm\r
315 of @code{sketch} has split \r
316 @cindex splitting, line and surface\r
317 the line into\r
318 two pieces and ordered the three resulting objects so that the correct\r
319 portion of the line is hidden.\r
321 If you've noticed that the projection we are using seems equivalent to\r
322 erasing the @math{z}-coordinate of the three-dimensional input points,\r
323 pat yourself on the back.  You are correct.  This is called a\r
324 @dfn{parallel projection}.\r
325 @cindex parallel projection\r
326 @cindex projection, parallel\r
327 The @math{z}-coordinate axis is pointing straight out of the paper at\r
328 us, while the @math{x}- and @math{y}-axes point to the right and up as\r
329 usual.\r
331 The resulting picture file can be included in a @LaTeX{} document with\r
332 @verb{|\input{simple}|}.  Alternately, adding the command line option\r
333 @option{-T}@footnote{Or for European users of A4 size paper,\r
334 @option{-Te}.} \r
335 @cindex command line option\r
336 @cindex option, command line\r
337 causes the @code{pspicture} to be wrapped in a short\r
338 but complete document, ready to run though @LaTeX{}.\r
339 @cindex document template\r
340 @cindex template, document\r
341 In a finished, typeset document, the picture looks like this.  (The\r
342 axes have been added in light gray.)\r
344 @center @image{ex020}\r
346 @noindent\r
347 It is important to know that only the ``outside'' \r
348 @cindex outside of a polygon\r
349 @cindex polygon, outside of\r
350 of a polygon is\r
351 normally drawn.  The @dfn{outside} is where the vertices given in the\r
352 @code{polygon} \r
353 @sxindex polygon\r
354 command appear in @emph{counter-clockwise} \r
355 @cindex counter-clockwise polygon vertex order\r
356 @cindex polygon vertex order\r
357 @cindex order, polygon vertex\r
358 order.  Thus, if the command above had been\r
359 @verbatim\r
360   polygon(0,1,0)(1,0,0)(0,0,1)\r
361 @end verbatim\r
362 @noindent\r
363 the polygon would not appear in the picture at all.  It would have\r
364 been @dfn{culled}\r
365 @cindex culling\r
366 from the scene.  This culling behavior may seem\r
367 strange, but stay tuned.\r
369 @node Drawing options, Drawing a solid, Hello world, Introduction by example\r
370 @comment  node-name,  next,  previous,  up\r
371 @section Options\r
372 Many @code{PSTricks} and @code{TikZ/PGF} options \r
373 @cindex option\r
374 work just fine in @code{sketch}. If generating @code{PSTricks}, the code\r
375 @sxindex line\r
376 @verbatim\r
377   polygon[fillcolor=lightgray,linewidth=3pt](0,0,1)(1,0,0)(0,1,0)\r
378   line[linestyle=dotted](-1,-1,-1)(2,2,2)\r
379 @end verbatim\r
380 @noindent\r
381 produces\r
383 @center @image{ex030}\r
385 To produce @code{TikZ/PGF}, the corresponding code is \r
386 @verbatim\r
387   polygon[fill=lightgray,line width=3pt](0,0,1)(1,0,0)(0,1,0)\r
388   line[style=dotted](-1,-1,-1)(2,2,2)\r
389   global { language tikz }\r
390 @end verbatim\r
391 @noindent\r
392 The final @code{global} \r
393 @cindex options, global\r
394 @cindex global options\r
395 instructs @code{sketch} to produce @code{TikZ/PGF} code as output\r
396 rather than the default, @code{PSTricks}.  Note that @code{polygon}\r
397 fill color and @code{line} style options both conform to @code{TikZ}\r
398 syntax rules.  The resulting @code{TikZ/PGF} output is\r
399 @verbatim\r
400   \begin{tikzpicture}[join=round]\r
401   \draw[dotted](-1,-1)--(.333,.333);\r
402   \filldraw[fill=lightgray,line width=3pt](0,0)--(1,0)--(0,1)--cycle;\r
403   \draw[dotted](.333,.333)--(2,2);\r
404   \end{tikzpicture}\r
405 @end verbatim\r
406 @noindent\r
407 The remaining examples of this manual are in PSTricks style.\r
409 @node Drawing a solid, Special objects, Drawing options, Introduction by example\r
410 @comment  node-name,  next,  previous,  up\r
411 @section Drawing a solid\r
412 Let's try something more exciting.  @code{Sketch} has no notion of a\r
413 solid, \r
414 @cindex solid\r
415 but polygonal @dfn{faces} \r
416 @cindex faces\r
417 can be used to represent the\r
418 boundary of a solid.  To the previous example, let's add three more\r
419 triangular polygons to make the faces of an irregular tetrahedron.\r
420 @cindex tetrahedron\r
421 @sxindex def\r
422 @sxindex polygon\r
423 @verbatim\r
424   % vertices of the tetrahedron\r
425   def p1 (0,0,1) def p2 (1,0,0)\r
426   def p3 (0,1,0) def p4 (-.3,-.5,-.8)\r
428   % faces of the tetrahedron.\r
429   polygon(p1)(p2)(p3) % original front polygon\r
430   polygon(p1)(p4)(p2) % bottom\r
431   polygon(p1)(p3)(p4) % left\r
432   polygon(p3)(p2)(p4) % rear\r
434   % line to pierce the tetrahedron\r
435   line[linecolor=red](-1,-1,-1)(2,2,2)\r
436 @end verbatim\r
437 @noindent\r
438 This example uses @dfn{definitions}, \r
439 @cindex definition\r
440 which begin with \r
441 @code{def}.\r
442 @sxindex def\r
443 These @dfn{define} or give names to points, \r
444 @cindex definition, point\r
445 @cindex point definition\r
446 which are then available\r
447 as @dfn{references} \r
448 @cindex reference, point\r
449 by enclosing the names in parentheses,\r
450 e.g.@ @verb{|(foo)|}.\r
451 @sxindex (foo)@r{, point reference}\r
452 The parentheses denote that the names refer to points; they are\r
453 required.  There can be no\r
454 @cindex white space\r
455 white space between them and the name.\r
457 As you can see, comments \r
458 @cindex comments\r
459 start with @verb{|%|} as in @TeX{} and extend\r
460 to the end of the line (though @verb{|#|} will work as well).  White\r
461 space, \r
462 @cindex white space\r
463 including spaces, tabs and blank lines, has no effect in the @code{sketch}\r
464 language.\r
466 @center @image{ex040}\r
468 @noindent\r
469 If we look inside the @TeX{} file produced by @code{sketch}, there\r
470 will be only three polygons.  The fourth has been \r
471 @cindex culling\r
472 culled because it is\r
473 a ``back face'' \r
474 @cindex back face\r
475 of the tetrahedron, invisible to our view.  It is\r
476 unnecessary, and so it is removed.\r
478 In some drawings, polygons act as zero-thickness solid surfaces with\r
479 both sides visible rather than as the faces of solid objects, where\r
480 back faces can be culled.  For zero-thickness solids, culling \r
481 @cindex culling\r
482 is a\r
483 problem.  One solution is to use a pair of @code{sketch} polygons for\r
484 each zero-thickness face, identical except with opposite vertex\r
485 orders.  This is unwieldy and expensive.  A better way is to\r
486 set the @code{sketch} internal option @code{cull} to @code{false} in\r
487 the usual @code{PSTricks} manner.\r
488 @opindex cull\r
489 @verbatim\r
490   polygon[cull=false](p1)(p2)(p3)\r
491 @end verbatim\r
492 @noindent\r
493 The following shows the same helix\r
494 @cindex helix\r
495 shape drawn first with\r
496 @verb{|cull=true|} (the default) and then @verb{|cull=false|}.\r
498 @center @image{ex045} @anchor{Helix with cull set false then true} \r
500 @noindent\r
501 We'll soon see how to produce these helixes with a few lines \r
502 of @code{sketch} language code.\r
504 It may be tempting to turn culling off gratuitously so that vertex order\r
505 can be ignored.  This is not a good idea because output file size and\r
506 @TeX{} and Postscript processing time both depend on the number of\r
507 output polygons.  Culling usually improves performance by a factor of\r
508 two.  On the other hand, globally setting @code{cull=false} is \r
509 reasonable while debugging.  See @ref{Global options} and \r
510 @ref{Limits on error detection}.\r
512 @node Special objects, Object transforms, Drawing a solid, Introduction by example\r
513 @comment  node-name,  next,  previous,  up\r
514 @section Special objects\r
515 We can add labels \r
516 @cindex labels\r
517 to a drawing by using @verb{|special|} \r
518 @sxindex special\r
519 @cindex special object\r
520 objects, which provide a way to embed raw @LaTeX{} and @code{PSTricks}\r
521 code.  Adding this to the tetrahedron does the trick.\r
522 @verbatim\r
523   special |\footnotesize\r
524            \uput{2pt}[ur]#1{$P1$}\r
525            \uput[r]#2{$P2$}\r
526            \uput[u]#3{$P3$}\r
527            \uput[d]#4{$P4$}|\r
528     (p1)(p2)(p3)(p4)\r
529 @end verbatim\r
530 @noindent\r
531 Here is the result.\r
533 @center @image{ex042}\r
535 There are several details to note here.  First, the quoting convention\r
536 @cindex quoting, special\r
537 for the raw code is similar to the @LaTeX{} @verb{|\verb|} command.  The\r
538 first non-white space character following @verb{|special|} is\r
539 understood to be the quote character, \r
540 in this case @samp{|}.  The raw\r
541 text continues until this character recurs.\r
543 Second, the argument references \r
544 @cindex argument, special\r
545 @verb{|#1|}, @verb{|#2|}, @verb{|#3|},\r
546 and @verb{|#4|} refer to points in the list that follow.  This is\r
547 similar to @TeX{} macro syntax.  The transformed and two-dimensional\r
548 projections of these three-dimensional points are substituted \r
549 @cindex substitution, special\r
550 @cindex special argument substitution\r
551 in the final output.  An argument reference of the form @verb{|#1-2|}\r
552 is replaced with the angle in degrees of the two-dimensional vector\r
553 that connects the projections of the two respective argument points,\r
554 here @verb{|#1|} and @verb{|#2|}.  The substituted angle is enclosed\r
555 in curly braces @code{@{ @}}\r
557 By default, @code{special} objects are printed last, overlaying all\r
558 other objects in the scene.  If you specify the internal option\r
559 @cindex internal option\r
560 @cindex option, internal\r
561 @code{lay=in}, the hidden surface algorithm \r
562 @opindex lay\r
563 @cindex hidden surface algorithm\r
564 considers the entire special object to be the first point\r
565 (@verb{|#1|}) in the argument list.  If that point is behind (of\r
566 smaller @math{z}-component than) any drawable, then the entire special\r
567 object is drawn before that drawable, so the drawable obscures parts of\r
568 the special object that overlaps it.  In our example, @verb{|p1|} is\r
569 the front-most point in the scene (has the largest\r
570 @math{z}-component), so adding @code{lay=in} has no effect.  \r
572 With option @code{lay=under}, a special is drawn @emph{before}, hence\r
573 appears @emph{under} any of the objects handled by the hidden surface\r
574 algorithm.  This is how the light gray axes were added to the ``hello\r
575 world'' example @ref{Hello world}.\r
577 @verb{|Special|} objects are powerful, with many possible uses.\r
579 @node Object transforms, Repeated objects, Special objects, Introduction by example\r
580 @comment  node-name,  next,  previous,  up\r
581 @section Transforms\r
582 @cindex transform\r
583 Now let's add a second copy of the pierced tetrahedron.  We'll rotate\r
584 the copy 90 degrees about the @math{x}-axis with the origin as\r
585 @dfn{center of rotation}\r
586 @cindex center of rotation\r
587 @cindex rotation, center of\r
588 so we can see the back,\r
589 then translate it to the right---in the positive\r
590 @math{x}-direction---so it doesn't collide with the original. To help\r
591 us see what's going on, make the back side gray.\r
592 @sxindex def\r
593 @sxindex put\r
594 @sxindex line\r
595 @sxindex polygon\r
596 @opindex linecolor\r
597 @opindex fillcolor\r
598 @sxindex rotate\r
599 @sxindex translate\r
600 @sxindex then\r
601 @verbatim\r
602   def pierced_tetrahedron {\r
603     def p1 (0,0,1) def p2 (1,0,0)\r
604     def p3 (0,1,0) def p4 (-.3,-.5,-.8)\r
605     polygon(p1)(p2)(p3)                      % original\r
606     polygon(p1)(p4)(p2)                      % bottom\r
607     polygon(p1)(p3)(p4)                      % left\r
608     polygon[fillcolor=lightgray](p3)(p2)(p4) % rear\r
609     line[linecolor=red](-1,-1,-1)(2,2,2)\r
610   }\r
611   {pierced_tetrahedron}  % tetrahedron in original position\r
612   put { rotate(90, (0,0,0), [1,0,0]) % copy in new position\r
613         then translate([2.5,0,0]) } {pierced_tetrahedron}\r
614 @end verbatim\r
615 @noindent\r
616 Here the entire code of the previous example has been wrapped in a\r
617 definition by forming a @dfn{block} \r
618 @cindex block\r
619 @sxindex @{ @}@r{, block drawable}\r
620 with braces (a single item would not need them).  The point\r
621 definitions nested inside the braces are @dfn{lexically scoped}.\r
622 @cindex lexical scope\r
623 @cindex scope, identifier\r
624 Their meaning extends only to the end of the block.  The outer\r
625 @verb{|def|} is called a @dfn{drawable}\r
626 @cindex drawable\r
627 definition \r
628 @cindex definition, drawable\r
629 @cindex drawable definition\r
630 because it describes something that can be drawn.\r
632 A drawable definition by itself causes nothing to happen until its\r
633 name is referenced.  Drawable references must be enclosed in curly\r
634 braces, e.g.@ @verb{|{foo}|}, with no intervening\r
635 @cindex white space\r
636 white space.  In the code\r
637 above, the first reference \r
638 @cindex reference, drawable\r
639 @verb{|{pierced_tetrahedron}|} \r
640 @sxindex @{foo@}@r{, drawable reference}\r
641 is a plain\r
642 one. Its effect is merely to duplicate the earlier drawing.  Almost\r
643 any series of @code{sketch} commands @verb{|stuff|} may be replaced\r
644 with @verb{|def foo { stuff } {foo}|} without changing its meaning.\r
646 The @verb{|put|} command supplies a second reference, this time with\r
647 a @dfn{transform} applied first.  The @verb{|rotate|}\r
648 @sxindex rotate\r
649 @cindex rotation\r
650 transform turns the tetrahedron 90 degrees about the origin.  The\r
651 axis of rotation \r
652 @cindex axis, rotation\r
653 is the vector @math{[1,0,0]}.  By the @dfn{right\r
654 hand rule}, \r
655 @cindex right hand rule\r
656 this causes the top of the tetrahedron to rotate toward\r
657 the viewer and the bottom away.  The rule receives its name from the\r
658 following definition:\r
659 @quotation\r
660 @anchor{Right hand rule}\r
661 @strong{Right hand rule.}  If the right hand is wrapped around any\r
662 axis with the thumb pointing in the axis direction, then the fingers\r
663 curl in the direction of positive rotation about that axis.\r
664 @end quotation\r
665 The @verb{|translate|} \r
666 @sxindex translate\r
667 @cindex translation transform\r
668 @cindex transform, translation\r
669 transform moves the pyramid laterally to\r
670 the right by adding the vector \r
671 @cindex vector\r
672 @math{[2.5,0,0]} to each vertex\r
673 coordinate.  The result is shown here.\r
675 @center @image{ex050}\r
677 @node  Repeated objects, Swept objects, Object transforms, Introduction by example\r
678 @comment  node-name,  next,  previous,  up\r
679 @section Repeated objects\r
680 To draw seven instances of the tetrahedron, each differing from the\r
681 last by the same transform, replace the last two commands of the\r
682 previous example with\r
683 @sxindex repeat\r
684 @sxindex rotate\r
685 @sxindex translate\r
686 @verbatim\r
687   repeat { 7, rotate(15, (0,0,0), [1,0,0]) % copy in new position\r
688               then translate([2,0,0]) } {pierced_tetrahedron}\r
689 @end verbatim\r
690 @noindent\r
691 And the result@enddots{}\r
693 @center @image{ex060}\r
695 @node  Swept objects,  , Repeated objects, Introduction by example\r
696 @comment  node-name,  next,  previous,  up\r
697 @section Swept objects\r
698 @cindex swept object\r
699 @cindex sweep\r
700 Many familiar shapes can be generated by sweeping simpler ones through\r
701 space and considering the resulting path, surface, or volume.\r
702 @code{Sketch} implements this idea in the @verb{|sweep|} command.\r
703 @sxindex sweep\r
704 @sxindex rotate\r
705 @verbatim\r
706   def n_segs 8\r
707   sweep { n_segs, rotate(180 / n_segs, (0,0,0), [0,0,1]) } (1,0,0)\r
708 @end verbatim\r
709 @noindent\r
710 This code sweeps the point @math{(1,0,0)} \r
711 @cindex point sweep\r
712 @cindex swept point\r
713 eight times by rotating it\r
714 @math{180/8 = 22.5} degrees each time and connecting the resulting\r
715 points with line segments.  The @verb{|def|} used here is a\r
716 @dfn{scalar} definition.\r
717 @cindex definition, scalar\r
718 @cindex scalar definition\r
719 References to\r
720 @cindex reference, scalar\r
721 scalars have no enclosing brackets at all.\r
723 @menu\r
724 * Point sweeps::                Swept points make lines and polygons.\r
725 * Polyline sweeps::             Swept lines make surfaces.\r
726 * Nested sweeps::               Swept sweeps are useful!\r
727 * Polygon sweeps::              Swept polygons make solids...\r
728 * Polyline sweeps with closure::  and so do closed polyline sweeps.\r
729 * Affine arithmetic::           Sketch useful math expression.\r
730 * More to learn::               Check out the Mobius strip!\r
731 @end menu\r
733 @node Point sweeps, Polyline sweeps, Swept objects, Swept objects\r
734 @comment  node-name,  next,  previous,  up\r
735 @subsection Point sweeps\r
736 Sweeping a point makes a one-dimensional path, which is a polyline.\r
737 Since we have swept with a rotation, the result is a circular arc.\r
738 Here is what it looks like.\r
740 @center @image{ex070}\r
742 This is the first example we have seen of @code{sketch} arithmetic.\r
743 The expression @verb{|180 / n_segs|} causes the eight rotations to add\r
744 to 180.  If you're paying attention, you'll have already noted that\r
745 there are @emph{nine} points, producing eight line segments.\r
747 You can cause the swept point to generate a single polygon rather than\r
748 a polyline by using the @dfn{closure tag} @verb{|<>|} \r
749 @sxindex <>@r{, closure tag}\r
750 @cindex closure tag, @code{<>}\r
751 after the number\r
752 of swept objects. Code and result follow\r
753 @sxindex def\r
754 @sxindex rotate\r
755 @sxindex sweep\r
756 @verbatim\r
757   def n_segs 8\r
758   sweep { n_segs<>, rotate(180 / n_segs, (0,0,0), [0,0,1]) } (1,0,0)\r
759 @end verbatim\r
760 @center @image{ex080}\r
762 @node Polyline sweeps, Nested sweeps, Point sweeps, Swept objects\r
763 @comment  node-name,  next,  previous,  up\r
764 @subsection Polyline sweeps\r
765 Sweeping a polyline produces a \r
766 @cindex line sweep\r
767 @cindex swept line\r
768 @cindex surface\r
769 surface composed of many faces.  \r
770 @cindex faces\r
771 The unbroken helix in the\r
772 example @ref{Helix with cull set false then true} is produced by this\r
773 code (plus a surrounding @verb{|put|} rotation to make an interesting\r
774 view; this has been omitted).\r
775 @sxindex def\r
776 @sxindex sweep\r
777 @sxindex rotate\r
778 @sxindex translate\r
779 @opindex cull\r
780 @opindex linewidth\r
781 @verbatim\r
782   def K [0,0,1]\r
783   sweep[cull=false] {\r
784     60, \r
785     rotate(10, (0,0,0), [K]) then translate(1/6 * [K]) \r
786   } line[linewidth=2pt](-1,0)(1,0)\r
787 @end verbatim\r
788 @noindent\r
789 Again, 60 segments of the helix \r
790 @cindex helix\r
791 are produced by connecting 61\r
792 instances of the swept line.  Options \r
793 @cindex options, sweep\r
794 applied to the sweep, here\r
795 @verb{|cull=false|}, are treated as options for the generated polygon\r
796 or polyline.  Options of the swept line itself, here\r
797 @verb{|linewidth=2pt|}, are ignored, though with a warning. This\r
798 @verb{|def|} is a @dfn{vector} definition, \r
799 @cindex definition, vector\r
800 @cindex vector definition\r
801 which must be referenced\r
802 with square brackets, e.g.@ @verb{|[foo]|}.\r
803 @cindex reference, vector\r
804 @sxindex [foo]@r{, vector reference}\r
806 @node Nested sweeps, Polygon sweeps, Polyline sweeps, Swept objects\r
807 @comment  node-name,  next,  previous,  up\r
808 @subsection Nested sweeps\r
809 When the center point of rotation is omitted, \r
810 @cindex center of rotation\r
811 @cindex rotation, center of\r
812 the origin is assumed.\r
813 When a point has only two coordinates, they are taken as\r
814 @math{x}@tie{}and @math{y},@tie{}with @math{z=0} assumed.  A toroid \r
815 @cindex toroid\r
816 is therefore obtained with this code.\r
817 @sxindex def\r
818 @sxindex sweep\r
819 @sxindex rotate\r
820 @verbatim\r
821   def n_toroid_segs 20   def n_circle_segs 16\r
822   def r_minor 1          def r_major 1.5\r
823   sweep { n_toroid_segs, rotate(360 / n_toroid_segs, [0,1,0]) }\r
824     sweep { n_circle_segs, rotate(360 / n_circle_segs, (r_major,0,0)) } \r
825       (r_major + r_minor, 0)\r
826 @end verbatim\r
827 @indent\r
828 For intuition, the idea of the code is to sketch a circle to the right\r
829 of the origin in the @math{xy}-plane, then rotate that circle ``out of\r
830 the plane'' about the @math{y}-axis to make the final figure.  This\r
831 produces the following.  (A view rotation and some axes have been\r
832 added.)\r
834 @center @image{ex090}\r
836 This example also shows that the swept object may itself be another\r
837 @code{sweep}.\r
838 @sxindex sweep\r
839 @cindex nesting, swept object\r
840 In fact, it may be @emph{any} @code{sketch} expression that results in\r
841 a list of one or more points or, alternately, a list of one or more\r
842 polylines and polygons.  The latter kind of list can be created with a\r
843 @verb{|{ }|}-enclosed block, perhaps following a \r
844 @sxindex put\r
845 @verb{|put|} or\r
846 @sxindex repeat\r
847 @verb{|repeat|}.\r
848 @sxindex @{ @}@r{, block drawable}\r
850 @node Polygon sweeps, Polyline sweeps with closure, Nested sweeps, Swept objects\r
851 @comment  node-name,  next,  previous,  up\r
852 @subsection Polygon sweeps\r
853 Sweeping a polygon \r
854 @cindex polygon sweep\r
855 @cindex swept polygon\r
856 creates a closed surface with polygons at the ends,\r
857 which are just copies of the original, appropriately\r
858 positioned.  @xref{Solid coil example}. \r
859 @cindex options, swept object\r
860 Options on the swept polygon,\r
861 if they exist, are applied to the ends.  Otherwise the sweep options\r
862 @cindex options, sweep\r
863 are used throughout.\r
865 @node Polyline sweeps with closure, Affine arithmetic, Polygon sweeps, Swept objects\r
866 @comment  node-name,  next,  previous,  up\r
867 @subsection Polyline sweeps with closure\r
868 A polyline sweep with a closure tag \r
869 @sxindex <>@r{, closure tag}\r
870 @cindex closure tag, @code{<>}\r
871 creates another kind of closed\r
872 surface.  First, the polyline segments are connected by faces, just as\r
873 without the closure tag.  Then, each set of end points is joined to\r
874 make a polygon, one for each end.  A code for several views of a\r
875 cylindrical prism follows.\r
876 @sxindex def\r
877 @sxindex repeat\r
878 @sxindex rotate\r
879 @sxindex then\r
880 @sxindex translate\r
881 @sxindex sweep\r
882 @sxindex line\r
883 @opindex fillcolor\r
884 @verbatim\r
885   def n_cyl_segs 20  def n_views 5  def I [1,0,0]\r
886   def endopts [fillcolor=lightgray]\r
887   repeat { n_views, rotate(180/n_views, [I]) then translate([I] * 2.1) } \r
888     sweep[endopts]{ n_cyl_segs<>, rotate(360/n_cyl_segs, [0,1,0]) } \r
889       line[fillcolor=white](1,-1)(1,1)\r
890 @end verbatim\r
891 @noindent\r
892 It produces this drawing.\r
894 @center @image{ex110}\r
896 @noindent\r
897 The options of the swept line, if any, are applied to the faces\r
898 produced by sweeping the line, but not the end polygons.  Otherwise,\r
899 the sweep options are applied throughout.\r
900 @cindex options, swept object\r
901 The @verb{|def|} in this example is an @dfn{option} definition.\r
902 @cindex definition, options\r
903 @cindex options definition\r
904 References to options must be enclosed in square brackets, e.g.@tie{}\r
905 @verb{|[foo]|}.\r
906 @cindex reference, options\r
907 @sxindex [foo]@r{, options reference}\r
908 You can concatenate several sets of options with a single\r
909 reference, e.g.@tie{}\r
910 @verb{|[color, size, style]|}\r
911 would cause the option definitions for @code{color}, @code{size},\r
912 and @code{style} to appear in sequence in the output \r
913 created by the @code{sketch} command containing the reference.\r
914 Happily, the syntax of @code{sketch} is such that\r
915 options references can never be confused with vector references.  While\r
916 not apparent in this example, options references are useful when\r
917 defining many objects with a similar appearance.\r
919 @node Affine arithmetic, More to learn, Polyline sweeps with closure, Swept objects\r
920 @comment  node-name,  next,  previous,  up\r
921 @subsection Affine arithmetic\r
922 The arithmetic @verb{|[I] * 2.1|} above hints at a larger truth.\r
923 @code{Sketch} operators work on scalars, vectors, points, and\r
924 transforms according to the general rules of @dfn{affine algebra}.\r
925 @cindex affine arithmetic\r
926 This can be helpful for setting up diagrams with computed geometry.\r
927 For example, if you have triangle vertices @verb{|(p1)|} through\r
928 @verb{|(p3)|} and need to draw a unit normal vector pointing out of\r
929 the center of the triangle, this code does the trick.\r
930 @sxindex def\r
931 @sxindex polygon\r
932 @sxindex line\r
933 @opindex arrows\r
934 @verbatim\r
935   def p1 (1,0,0)  def p2 (0,0.5,0)  def p3 (-0.5,-1,2)\r
936   def O (0,0,0)\r
937   def N unit( ((p3) - (p2)) * ((p1) - (p2)) )\r
938   def n1 ((p1)-(O) + (p2)-(O) + (p3)-(O)) / 3 + (O)\r
939   def n2 (n1)+[N]\r
940   polygon(p1)(p2)(p3)\r
941   line[arrows=*->](n1)(n2)\r
942 @end verbatim\r
943 @noindent\r
944 The first line computes the cross product of two edge vectors of the\r
945 triangle and scales it to unit length.  The second computes the\r
946 average of the vertices.  Note that subtraction and addition of the\r
947 origin effectively convert vectors to points and @emph{vice versa}.\r
948 The line command draws the normal at the correct spot.\r
950 @center @image{ex100}\r
952 Two caveats regarding this example remain.  First, the only way to use\r
953 @code{PSTricks}-style arrows is with @verb{|arrows=|}.  \r
954 @opindex arrows\r
955 The alternative syntax for @code{PSTricks} arrows is not allowed in\r
956 @verb{|sketch|}. Second, you might like to eliminate the third\r
957 @verb{|def|} and write instead the following.\r
958 @verbatim\r
959   line[arrows=*->](n1) (n1)+[N]\r
960 @end verbatim\r
961 @noindent\r
962 This is not allowed.  The point lists in drawables may consist only of\r
963 explicit points or point references.  You may, however, use arithmetic\r
964 to calculate point components.  The following works, though it's\r
965 a little cumbersome.\r
966 @verbatim\r
967   line[arrows=*->](n1)((n1)'x+(N)'x, (n1)'y+(N)'y, (n1)'z+(N)'z)\r
968 @end verbatim\r
969 @noindent\r
970 Obviously, the @dfn{tick operator} \r
971 @cindex tick operator (@code{'})\r
972 @sxindex 'x@r{,} 'y@r{, and }'z\r
973 @samp{'x} extracts components of points and\r
974 vectors. \r
976 @node More to learn,  , Affine arithmetic, Swept objects\r
977 @comment  node-name,  next,  previous,  up\r
978 @subsection More to learn\r
979 This is not the end of the story on sweeps!  We invite the reader into\r
980 the main body of this documentation @ref{Sweeps} to learn more.\r
982 @center @image{ex120}\r
984 @noindent\r
985 Who knows where you'll finish?\r
987 @node Input language, Building a drawing, Introduction by example, Top\r
988 @comment  node-name,  next,  previous,  up\r
989 @chapter Input language\r
990 This chapter describes the @code{sketch} input language in detail.\r
992 @menu\r
993 * Language basics::             Case, space, comments, include files.\r
994 * Drawables::                   Things that can be drawn.\r
995 * Definitions::                 Giving things names.\r
996 * Global environment::          Affect the entire drawing.\r
997 @end menu\r
999 @node Language basics, Drawables, Input language, Input language\r
1000 @comment  node-name,  next,  previous,  up\r
1001 @section Basics \r
1002 @code{Sketch} input is plain ASCII text, usually stored in an input\r
1003 file.  \r
1004 @cindex input file\r
1005 @cindex file, input\r
1006 It describes a @dfn{scene},\r
1007 so the sketch language is a @dfn{scene description\r
1008 language}.\r
1009 @cindex scene description language\r
1010 @cindex language, scene description\r
1011 @code{Sketch} input is also @dfn{declarative}.\r
1012 @cindex declarative language\r
1013 @cindex language, declarative\r
1014 It merely\r
1015 declares what the scene ought to look like when drawing is complete\r
1016 and says very little about how @code{sketch} should do its work.\r
1017 @code{Sketch} commands are not executed sequentially as in the usual\r
1018 programming language.  They merely contribute to that declaration.\r
1020 A few syntactic details are important.  Case is significant in the\r
1021 @code{sketch} language.  With a few exceptions, white space is not.\r
1022 This includes line breaks.\r
1023 @cindex white space\r
1024 Comments begin with @code{%} or @code{#} and extend to the end of the\r
1025 line.  You can disable a chunk of syntactically correct @code{sketch}\r
1026 code by enclosing it in a @code{def}.\r
1027 @cindex comments\r
1028 There is a simple ``include file'' mechanism. \r
1029 @cindex include file\r
1030 @cindex file, include\r
1031 The command\r
1032 @sxindex input\r
1033 @verbatim\r
1034   input{otherfile.sk}\r
1035 @end verbatim\r
1036 @noindent\r
1037 causes the contents of @file{otherfile.sk} to be inserted as though\r
1038 they were part of the current file.\r
1040 @menu\r
1041 * Identifiers::                 Names for things.\r
1042 * Key and reserved words::      Names you shouldn't use.\r
1043 * Literals::                    Constants and constructors.\r
1044 * Arithmetic::                  Rules for expressions.\r
1045 * Options::                     Modifying object appearance.\r
1046 @end menu\r
1048 @node Identifiers, Key and reserved words, Language basics, Language basics\r
1049 @comment  node-name,  next,  previous,  up\r
1050 @subsection Identifiers\r
1051 Identifiers in @code{sketch} are references to earlier-defined\r
1052 options, scalars, points, vectors, transforms, drawables, and tags.\r
1053 @cindex identifiers\r
1054 Definitions are explained in @ref{Definitions}.\r
1056 An identifier consists of a leading letter followed by letters,\r
1057 numbers and underscores.  The last character may @emph{not} be an\r
1058 underscore.  Keywords cannot be used as identifiers, and reserved\r
1059 words ought to be avoided. @xref{Key and reserved words}.\r
1061 @node Key and reserved words, Literals, Identifiers, Language basics\r
1062 @comment  node-name,  next,  previous,  up\r
1063 @subsection Key and reserved words\r
1064 @cindex keywords\r
1065 The keywords of @code{sketch} are @code{picturebox} @code{curve}\r
1066 @code{def} @code{dots} @code{frame} @code{global} @code{input}\r
1067 @code{line} @code{polygon} @code{put} @code{repeat} @code{set}\r
1068 @code{sweep} and @code{then}.  The @code{sketch} parser will note a\r
1069 syntax error if any of these are used in place of a proper identifier.\r
1071 In addition, there are reserved words \r
1072 @cindex reserved words\r
1073 that can currently be defined by the user, but with the risk that\r
1074 future versions of @code{sketch} will reject those definitions.  The\r
1075 reserved words are @code{atan2} @code{cos} @code{inverse}\r
1076 @code{perspective} @code{project} @code{rotate} @code{scale}\r
1077 @code{sin} @code{special} @code{sqrt} @code{translate} @code{unit} and\r
1078 @code{view}.\r
1080 @node Literals, Arithmetic, Key and reserved words, Language basics\r
1081 @comment  node-name,  next,  previous,  up\r
1082 @subsection Literals\r
1083 Literals in @code{sketch} include scalars, points, vectors, and\r
1084 transforms.  Literals, along with defined object references,\r
1085 are used in arithmetic expressions.  @xref{Arithmetic}.\r
1087 @menu\r
1088 * Scalar literals::             Just the numbers.\r
1089 * Point and vector literals::   3d quantities.\r
1090 * Transform literals::          Matrix form.\r
1091 @end menu\r
1093 @node Scalar literals, Point and vector literals, Literals, Literals\r
1094 @comment  node-name,  next,  previous,  up\r
1095 @subsubsection Scalar literals\r
1096 @cindex scalar literal\r
1097 @cindex literal, scalar\r
1098 Scalar literals are positive floating point numbers with syntax\r
1099 according to C conventions.  The following are some examples.\r
1100 @example\r
1101 0 1004 .001 8.3143 3. 1.60E-19 6.02e+23 \r
1102 @end example\r
1103 @noindent\r
1104 Scalar literals may not contain embedded spaces.\r
1106 @node Point and vector literals, Transform literals, Scalar literals, Literals\r
1107 @comment  node-name,  next,  previous,  up\r
1108 @subsubsection Point and vector literals\r
1109 @cindex point literal\r
1110 @cindex literal, point\r
1111 @cindex vector literal\r
1112 @cindex literal, vector\r
1113 Points and vector literals have these forms respectively.\r
1114 @example\r
1115 (@i{X},@i{Y},@i{Z})  [@i{X},@i{Y},@i{Z}]\r
1116 @end example\r
1117 @noindent\r
1118 Each of the components is itself a scalar expression.  The\r
1119 @math{z}-components are optional and default to zero.\r
1121 @node Transform literals,  , Point and vector literals, Literals\r
1122 @comment  node-name,  next,  previous,  up\r
1123 @subsubsection Transform literals\r
1124 @cindex transform literal\r
1125 @cindex literal, transform\r
1126 Most transform literals are formed by @dfn{constructors}.\r
1127 @cindex constructor\r
1128 These are summarized in the following table.\r
1129 @multitable {@code{[[@math{a_{11}},@math{a_{12}},@math{a_{13}},@math{a_{14}}],}}{point,vector,vector}{Long column meant to wrap but does it?  Maybe.}\r
1130 @headitem Constructor @tab Param types @tab Description\r
1131 @item @code{rotate(A,P,X)} \r
1132  @sxindex rotate\r
1133  @cindex rotation transform\r
1134  @cindex transform, rotation\r
1135  @tab scalar,point,vector \r
1136  @tab Rotate @code{A} degrees about point @code{P} with axis @code{X}\r
1137    according to the right hand rule. @xref{Right hand rule}.\r
1138    @code{P} and @code{X} are both optional and default to the origin and\r
1139    the @math{z}-axis respectively.\r
1140 @item @code{translate(X)} \r
1141  @sxindex translate\r
1142  @cindex translation transform\r
1143  @cindex transform, translation\r
1144  @tab vector \r
1145  @tab Translate by @code{X}.\r
1146 @item @code{scale(S)} \r
1147  @sxindex scale\r
1148  @cindex scale transform\r
1149  @cindex transform, scale\r
1150  @tab scalar\r
1151  @tab Scale uniformly by factor @code{S}.\r
1152 @item @code{scale(V)} \r
1153  @sxindex scale\r
1154  @cindex scale transform\r
1155  @cindex transform, scale\r
1156  @tab vector\r
1157  @tab Scale along each axis by components of @code{V}.\r
1158 @item @code{project()} \r
1159  @sxindex project\r
1160  @cindex parallel projection\r
1161  @cindex projection, parallel\r
1162  @tab ---\r
1163  @tab Same as @code{scale([1,1,0])}.\r
1164 @item @code{project(S)} \r
1165  @sxindex project\r
1166  @cindex perspective projection\r
1167  @cindex projection, perspective\r
1168  @tab scalar\r
1169  @tab Perspective projection with view center at origin and projection\r
1170  plane @math{z=-@code{S}}.\r
1171 @item @code{perspective(S)} \r
1172  @sxindex perspective\r
1173  @cindex perspective projection\r
1174  @cindex projection, perspective\r
1175  @tab scalar\r
1176  @tab Perspective @emph{transform} identical to @code{project(S)}\r
1177  except that the @math{z}-coordinate of the transformed result is\r
1178  @dfn{pseudodepth}, usable by the hidden surface algorithm. \r
1179  @cindex hidden surface algorithm\r
1180 @item @code{view(E,D,U)} \r
1181  @sxindex view\r
1182  @cindex view transform\r
1183  @cindex transform, view\r
1184  @tab point,vector,vector\r
1185  @tab View transform similar to that of @code{OpenGL}'s.  The\r
1186 @emph{eye point} @code{E} is translated to the origin while a rotation\r
1187 is also applied that makes the @emph{view direction vector} @code{D}\r
1188 and the @emph{view ``up'' vector} @code{U} point in the negative\r
1189 @math{z}- and the @math{y}-directions respectively.  If @code{U} is\r
1190 omitted, it defaults to @math{[0,1,0]}. When @code{U} is omitted,\r
1191 @code{D} may be also; it defaults to @code{(0,0,0)-(E)}, a vector\r
1192 pointing from the eye toward the origin.\r
1193 @item @code{view(E,L,U)} \r
1194  @sxindex view\r
1195  @cindex view transform\r
1196  @cindex transform, view\r
1197  @tab point,point,vector\r
1198  @tab An alternate form of @code{view(E,D,U)} above where \r
1199  the view direction parameter @code{D} is replaced with a\r
1200 ``look at'' point @code{L}, i.e., a point where the viewer is focusing\r
1201 her attention.  This form of view is equivalent to\r
1202 @code{view(E, (L)-(E), U)}, where @code{(L)-(E)} is a direction\r
1203 vector. @code{U} is optional and defaults to @math{[0,1,0]}.\r
1204 @item\r
1205 @code{[[@math{a_{11}},@math{a_{12}},@math{a_{13}},@math{a_{14}}]}@*\r
1206 @code{@w{ }[@math{a_{21}},@math{a_{22}},@math{a_{23}},@math{a_{24}}]}@*\r
1207 @code{@w{ }[@math{a_{31}},@math{a_{32}},@math{a_{33}},@math{a_{34}}]}@*\r
1208 @code{@w{ }[@math{a_{41}},@math{a_{42}},@math{a_{43}},@math{a_{44}}]]}@*\r
1209   @sxindex [[ ][ ][ ][ ]]@r{, transform literal}\r
1210   @cindex direct transform\r
1211   @cindex transform, direct\r
1212   @tab 16 scalars \r
1213   @tab Direct transform matrix definition. Each\r
1214   of the @math{a_{ij}} is a scalar expression. See text for details.\r
1215 @end multitable\r
1216 @noindent\r
1217 The @code{project} \r
1218 @sxindex project\r
1219 constructor is not generally useful because it\r
1220 defeats hidden surface removal by collapsing the scene onto a single\r
1221 plane.  It is a special purpose transform for drawing pictures of\r
1222 scenes where three-dimensional objects are being projected onto\r
1223 planes.  See, for example, @ref{Overview}.\r
1225 The direct transform constructor \r
1226 @sxindex [[ ][ ][ ][ ]]@r{, transform literal}\r
1227 @cindex direct transform\r
1228 @cindex transform, direct\r
1229 allows direct entry of a 4x4 transformation matrix. Most 3d graphics\r
1230 systems, including @code{sketch}, use 4-dimensional homogeneous\r
1231 coordinates internally. These are transformed by multiplication with\r
1232 4x4 matrices.  The built-in constructors (@code{rotate}, @code{scale},\r
1233 etc.) are all translated internally to such 4x4 matrices. For more\r
1234 information on homogeneous coordinate transformations, see any good\r
1235 computer graphics textbook. The direct transform feature of\r
1236 @code{sketch} allows you to enter a matrix of your own choice. There\r
1237 are not many cases where this is useful, but if you do need it, you\r
1238 need it badly!\r
1240 @node Arithmetic, Options, Literals, Language basics\r
1241 @subsection Arithmetic expressions\r
1242 Arithmetic expressions over @code{sketch} literals and\r
1243 defined identifiers are summarized in the following tables.\r
1245 @menu\r
1246 * Two-operand (binary) forms::  A op B\r
1247 * Unary forms::                 op A (and others)\r
1248 @end menu\r
1250 @node Two-operand (binary) forms, Unary forms, Arithmetic, Arithmetic\r
1251 @comment  node-name,  next,  previous,  up\r
1252 @subsubsection Two-operand (binary) forms and precedence\r
1253 Most two-operand binary \r
1254 @cindex binary form\r
1255 @cindex two-operand form\r
1256 forms have meanings dependent on the types of\r
1257 their arguments.  An exhaustive summary of the possibilities is given\r
1258 in the following table.\r
1259 @multitable {transform}{@code{then}}{transform}{transform}{a long description that really ought to wrap but does it I do not know}\r
1260 @headitem Left @tab Op @tab Right @tab Result @tab Description\r
1261 @item scalar @tab @code{+} @tab scalar \r
1262 @sxindex +@r{, plus operator}\r
1263 @tab scalar @tab Scalar sum.\r
1264 @item vector @tab @code{+} @tab vector\r
1265 @tab  vector @tab Vector sum.\r
1266 @item point  @tab @code{+} @tab vector\r
1267 @tab  point  @tab Point-vector affine sum.\r
1268 @item vector @tab @code{+} @tab point\r
1269 @tab  "         @tab " \r
1270 @item scalar    @tab @code{-} @tab scalar\r
1271 @sxindex -@r{, minus operator}\r
1272 @tab  scalar    @tab Scalar difference.\r
1273 @item vector    @tab @code{-} @tab vector\r
1274 @tab  vector    @tab Vector difference.\r
1275 @item point     @tab @code{-} @tab point\r
1276 @tab  vector    @tab Point-point affine difference.\r
1277 @item point     @tab @code{-} @tab vector\r
1278 @tab  point     @tab Point-vector affine difference.\r
1279 @item scalar    @tab @code{*} or \r
1280                      @code{.} @tab scalar\r
1281 @sxindex *@r{, multiplication operator}\r
1282 @sxindex .@r{, dot operator}\r
1283 @tab  scalar    @tab Scalar product.\r
1284 @item scalar    @tab @code{*} or \r
1285                      @code{.} @tab vector\r
1286 @tab  vector    @tab Scalar-vector product.\r
1287 @item vector    @tab @code{*} or \r
1288                      @code{.} @tab scalar\r
1289 @tab  "         @tab " \r
1290 @item vector    @tab @code{*} @tab vector\r
1291 @tab  vector    @tab Vector cross-product.\r
1292 @item vector    @tab @code{.} @tab vector\r
1293 @tab  scalar    @tab Vector dot product.\r
1294 @item scalar    @tab @code{^} @tab scalar\r
1295 @sxindex ^@r{, exponentiation operator}\r
1296 @tab  scalar    @tab Raise scalar to scalar power.\r
1297 @item transform @tab @code{^} @tab integer\r
1298 @tab  transform @tab Raise transform to integer power.\r
1299 @cindex transform\r
1300 @item transform @tab @code{*} or \r
1301                      @code{.} @tab point\r
1302 @tab  point     @tab Affine point transform (right-to-left).\r
1303 @item transform @tab @code{*} or \r
1304                      @code{.} @tab vector\r
1305 @tab  vector    @tab Affine vector transform (right-to-left).\r
1306 @item transform @tab @code{*} or \r
1307                      @code{.} @tab transform\r
1308 @tab  transform @tab Transform composition (right-to-left).\r
1309 @item point     @tab @code{then} @tab transform\r
1310 @sxindex then\r
1311 @tab  point     @tab Affine point transform (left-to-right).\r
1312 @item vector    @tab @code{then} @tab transform\r
1313 @tab  vector    @tab Affine vector transform (left-to-right).\r
1314 @item transform @tab @code{then} @tab transform\r
1315 @tab  transform @tab Transform composition (left-to-right).\r
1316 @item scalar    @tab @code{/} @tab scalar\r
1317 @sxindex /@r{, division operator}\r
1318 @tab  scalar    @tab Scalar division.\r
1319 @item vector    @tab @code{/} @tab scalar\r
1320 @tab  vector    @tab Vector component-wise division by scalar.\r
1321 @item point     @tab @code{'} @tab @code{x}, @code{y}, or @code{z}\r
1322 @cindex tick operator (@code{'})\r
1323 @sxindex 'x@r{,} 'y@r{, and }'z\r
1324 @tab  scalar    @tab Point component extraction.\r
1325 @item vector    @tab @code{'} @tab @code{x}, @code{y}, or @code{z}\r
1326 @tab  scalar    @tab Vector component extraction.\r
1327 @end multitable\r
1328 @sp 1\r
1329 @noindent\r
1330 Operator precedence \r
1331 @cindex precedence, operator\r
1332 @cindex operator precedence\r
1333 is shown in this table.\r
1334 @multitable {@code{then}} {highest (most tightly binding)}\r
1335 @headitem Op        @tab Precedence\r
1336 @item @code{'}      @tab highest (most tightly binding)\r
1337 @item @code{^}      @tab \r
1338 @item @code{-}      @tab (unary negation)\r
1339 @item @code{*}\r
1340       @code{.}\r
1341       @code{/}      @tab \r
1342 @item @code{+}\r
1343       @code{-}      @tab\r
1344 @item @code{then}   @tab lowest (least tightly binding)\r
1345 @end multitable\r
1346 @sp 1\r
1347 @noindent\r
1348 All operations are left-associative \r
1349 @cindex operator associativity\r
1350 @cindex associativity, operator\r
1351 except for @samp{^}.\r
1352 Parentheses @samp{( )} \r
1353 @cindex parentheses\r
1354 @sxindex ( )@r{, grouping}\r
1355 are used for grouping to override precedence in the usual way.\r
1357 As you can see, the dot operator @samp{.} \r
1358 @sxindex .@r{, dot operator}\r
1359 is usually a synonym for run-of-the-mill multiplication, @samp{*}.\r
1360 The meanings differ only for vector operands.  The @code{then}\r
1361 operator\r
1362 @sxindex then\r
1363 merely reverses the operand\r
1364 order with respect to normal multiplication @samp{*}.  The intent\r
1365 here is to make compositions read more naturally. The code\r
1366 @example\r
1367 (1,2,3) then scale(2) then rotate(30) then translate([1,3,0]) \r
1368 @end example\r
1369 @noindent\r
1370 expresses a series of successive modifications to the point,\r
1371 whereas the equivalent form\r
1372 @sxindex *@r{, multiplication operator}\r
1373 @example\r
1374 translate([1,3,0]) * rotate(30) * scale(2) * (1,2,3)\r
1375 @end example\r
1376 @noindent\r
1377 will be intuitive only to mathematicians (and perhaps Arabic\r
1378 language readers). \r
1380 @node Unary forms,  , Two-operand (binary) forms, Arithmetic\r
1381 @comment  node-name,  next,  previous,  up\r
1382 @subsubsection Unary forms\r
1383 Unary or one-operand forms\r
1384 @cindex unary form\r
1385 @cindex one-operand form\r
1386 are summarized in the following table, where @code{X}\r
1387 stands for the operand.\r
1388 @multitable{@code{inverse(X)}}{transform}{transform}{Long description meant to wrap eventually.}\r
1389 @headitem Op         @tab Operand \r
1390  @tab Result @tab Description\r
1391 @item @code{-X}      @tab scalar\r
1392 @sxindex -@r{, unary minus operator}\r
1393  @tab scalar @tab Unary scalar negation.\r
1394 @item @code{-X}      @tab vector\r
1395  @tab vector @tab Unary vector negation.\r
1396 @item @code{|X|}     @tab vector\r
1397  @sxindex |@math{X}|@r{, magnitude operator}\r
1398  @tab scalar @tab Vector length.\r
1399 @item @code{unit(X)} @tab vector\r
1400  @sxindex unit\r
1401  @tab vector @tab Unit vector with same direction.\r
1402 @item @code{sqrt(X)} @tab scalar\r
1403  @sxindex sqrt\r
1404  @tab scalar @tab Scalar square root.\r
1405 @item @code{sin(X)} @tab scalar\r
1406  @sxindex sin\r
1407  @tab scalar @tab Trigonometric sine (@code{X} in degrees).\r
1408 @item @code{cos(X)} @tab scalar\r
1409  @sxindex cos\r
1410  @tab scalar @tab Trigonometric cosine (@code{X} in degrees).\r
1411 @item @code{atan2(X,Y)} @tab scalar\r
1412  @sxindex atan2\r
1413  @tab scalar @tab Polar angle in degrees of vector @math{[X,Y]}.\r
1414 @item @code{inverse(X)} @tab transform\r
1415  @sxindex inverse\r
1416  @tab transform @tab Inverse transform.\r
1417 @end multitable\r
1418 @sp 1\r
1419 @noindent\r
1420 Errors are reported when @code{|X|}, @code{unit}, @code{sqrt},\r
1421 @code{atan2}, and @code{inverse} fail due to bad parameters.\r
1423 @node Options,  , Arithmetic, Language basics\r
1424 @comment  node-name,  next,  previous,  up\r
1425 @subsection Options\r
1426 @cindex options\r
1427 @strong{Syntax:}\r
1428 @example\r
1429 [@var{key1}=@var{val1},@var{key2}=@var{val2},@dots{}]\r
1430 @end example\r
1431 @noindent\r
1432 Options are used to specify details of the appearance of drawables.\r
1433 As shown above, they are given as comma-separated key-value\r
1434 pairs. \r
1436 @menu\r
1437 * PSTricks options::            Options inherited from @code{PSTricks}.\r
1438 * TikZ/PGF options::            Options inherited from @code{TikZ/PGF}.\r
1439 * Dots in TikZ/PGF::            Sketch uses @code{TikZ/PGF} circles for dots.\r
1440 * TikZ/PGF user-defined styles::  Support for @code{TikZ/PGF} named, user-defined styles.\r
1441 * Transparency::                See-through polygons.\r
1442 * Internal options::            Options used by @code{sketch}.\r
1443 @end menu\r
1445 @node PSTricks options, TikZ/PGF options, Options, Options\r
1446 @comment  node-name,  next,  previous,  up\r
1447 @subsubsection @code{PSTricks} options\r
1448 When @code{language pstricks} is selected (the default), permissible\r
1449 key-value pairs include all those for similar @code{PSTricks} objects.\r
1450 For example, a polygon might have the options\r
1451 @verbatim\r
1452   [linewidth=1pt,linecolor=blue,fillcolor=cyan]\r
1453 @end verbatim\r
1454 @noindent\r
1455 @code{Sketch} merely passes these on to @code{PSTricks} without\r
1456 checking or modification.  Option lists are always optional.  A\r
1457 missing options list is equivalent to an empty one @samp{[]}.\r
1459 When a @code{polygon} has options for both its face and its edges, and\r
1460 the polygon is split by the hidden surface algorithm, @code{sketch}\r
1461 must copy the edge options to @code{psline}s for the edge segments and\r
1462 the face options to @code{pspolygon}s.  Options known to @code{sketch}\r
1463 for purposes of this splitting operation include @code{arrows},\r
1464 @code{dash}, @code{dotsep}, @code{fillcolor}, @code{fillstyle},\r
1465 @code{linecolor}, @code{linestyle}, @code{linewidth}, @code{opacity}, \r
1466 @code{showpoints}, @code{strokeopacity}, and @code{transpalpha}.\r
1468 @node TikZ/PGF options, Dots in TikZ/PGF, PSTricks options, Options\r
1469 @comment  node-name,  next,  previous,  up\r
1470 @subsubsection @code{TikZ/PGF} options\r
1471 @code{TikZ/PGF} options are handled much as for @code{PSTricks}.\r
1472 Though @code{TikZ/PGF} often allows colors and styles to be given\r
1473 without corresponding keys, for example,\r
1474 @verbatim\r
1475   \draw[red,ultra thick](0,0)--(1,1);\r
1476 @end verbatim\r
1477 @noindent\r
1478 this is not permitted in @code{sketch}.  To draw a red, ultra-thick\r
1479 line in @code{sketch}, the form is\r
1480 @verbatim\r
1481   line[draw=red,style=ultra thick](0,0)(1,1)\r
1482 @end verbatim\r
1484 Just as for @code{PSTricks}, when a @code{polygon} has options for\r
1485 both its face and its edges, and the polygon is split by the hidden\r
1486 surface algorithm, @code{sketch} must copy the edge options to\r
1487 @code{psline}s for the edge segments and the face options to\r
1488 @code{pspolygon}s.  @code{TikZ/PGF} options known to @code{sketch} for\r
1489 purposes of this splitting operation include @code{arrows},\r
1490 @code{cap}, @code{color}, @code{dash pattern}, @code{dash phase},\r
1491 @code{double distance}, @code{draw}, @code{draw opacity}, @code{fill},\r
1492 @code{fill opacity}, @code{join}, @code{line width}, @code{miter\r
1493 limit}, @code{pattern}, @code{pattern color}, and @code{style}.\r
1495 The @code{style} option can contain both face and edge information, so\r
1496 @code{sketch} must check the style value.  Values known to\r
1497 @code{sketch} include @code{dashed}, @code{densely dashed},\r
1498 @code{densely dotted}, @code{dotted}, @code{double}, @code{loosely\r
1499 dashed}, @code{loosely dotted}, @code{nearly opaque}, @code{nearly\r
1500 transparent}, @code{semithick}, @code{semitransparent}, @code{solid},\r
1501 @code{thick}, @code{thin}, @code{transparent}, \r
1502 @code{ultra nearly transparent}, @code{ultra thick}, @code{ultra thin}, \r
1503 @code{very nearly transparent}, @code{very thick}, and @code{very thin}.\r
1505 @node  Dots in TikZ/PGF, TikZ/PGF user-defined styles, TikZ/PGF options, Options\r
1506 @comment  node-name,  next,  previous,  up\r
1507 @subsubsection Dots in @code{TikZ/PGF}\r
1508 @code{TikZ/PGF} does not have a @code{dots} command as does PSTricks.\r
1509 Instead, @code{Sketch} emits dots as @code{filldraw} circles.  The\r
1510 diameter may be set using the option @code{dotsize} borrowed from\r
1511 PSTricks.  The @code{dotsize} option will be removed from the option\r
1512 list in the output @code{filldraw} command.  Other options work in the\r
1513 expected way.  For example, @code{fill} sets fill color and\r
1514 @code{color} sets line color of the circles.\r
1516 @node  TikZ/PGF user-defined styles, Transparency, Dots in TikZ/PGF, Options\r
1517 @comment  node-name,  next,  previous,  up\r
1518 @subsubsection @code{TikZ/PGF} user-defined styles\r
1519 @code{TikZ/PGF} allows named styles defined by the user, for\r
1520 example\r
1521 @verbatim\r
1522   \tikzstyle{mypolygonstyle} = [fill=blue!20,fill opacity=0.8]  \r
1523   \tikzstyle{mylinestyle} = [red!20,dashed]\r
1524 @end verbatim\r
1525 @noindent\r
1526 Since @code{sketch} has no information on the contents of such styles,\r
1527 it omits them entirely from lines, polygons, and their edges during\r
1528 option splitting.  For example,\r
1529 @verbatim\r
1530   polygon[style=mypolygonstyle,style=thick](0,0,1)(1,0,0)(0,1,0)\r
1531   line[style=mylinestyle](-1,-1,-1)(2,2,2)\r
1532 @end verbatim\r
1533 @noindent\r
1534 produces the @code{TikZ} output\r
1535 @verbatim\r
1536   \draw(-1,-1)--(.333,.333);\r
1537   \filldraw[thick,fill=white](0,0)--(1,0)--(0,1)--cycle;\r
1538   \draw(.333,.333)--(2,2);\r
1539 @end verbatim\r
1540 @noindent\r
1541 Note that the user-defined styles are not present.  Sketch also issues\r
1542 warnings:\r
1543 @verbatim\r
1544   warning, unknown polygon option style=mypolygonstyle will be ignored\r
1545   warning, unknown line option style=mylinestyle will be ignored\r
1546 @end verbatim\r
1548 The remedy is to state explicitly whether a user-defined style should\r
1549 be attched to polygons or lines in the @code{TikZ} output using\r
1550 @emph{pseudo-options} @code{fill style} and @code{line style},\r
1551 @cindex pseudo-options\r
1552 @sxindex fill style\r
1553 @sxindex line style\r
1554 @verbatim\r
1555   polygon[fill style=mypolygonstyle,style=thick](0,0,1)(1,0,0)(0,1,0)\r
1556   line[line style=mylinestyle](-1,-1,-1)(2,2,2)\r
1557 @end verbatim\r
1558 @noindent\r
1559 Now, the output is\r
1560 @verbatim\r
1561   \draw[mylinestyle](-1,-1)--(.333,.333);\r
1562   \filldraw[mypolygonstyle,thick](0,0)--(1,0)--(0,1)--cycle;\r
1563   \draw[mylinestyle](.333,.333)--(2,2);\r
1564 @end verbatim\r
1566 A useful technique is to include user-defined style definitions in\r
1567 @code{sketch} code as @code{special}s with option @code{[lay=under]}\r
1568 to ensure that the styles are emitted first in the output, before\r
1569 any uses of the style names.\r
1570 @footnote{This clever trick is due to Kjell Magne Fauske.}  For\r
1571 example,\r
1572 @verbatim\r
1573   special|\tikzstyle{mypolygonstyle} = [fill=blue!20,fill opacity=0.8]|[lay=under]\r
1574   special|\tikzstyle{mylinestyle} = [red!20,dashed]|[lay=under]\r
1575 @end verbatim\r
1576 @noindent\r
1577 The author is responsible for using the key, @code{line style}\r
1578 or @code{fill style}, that matches the content of the style\r
1579 definition.\r
1581 @node  Transparency, Internal options, TikZ/PGF user-defined styles, Options\r
1582 @comment  node-name,  next,  previous,  up\r
1583 @subsubsection Transparency\r
1584 @cindex transparency\r
1585 Both @code{PSTricks} and @code{TikZ/PGF} support polygon options that\r
1586 have the effect of making the polygon appear transparent.  For\r
1587 @code{PSTricks}, keyword @code{transpalpha} was used during initial\r
1588 development of transparency features, and @code{opacity} was adopted \r
1589 later. @code{Sketch} honors both. @code{TikZ/PGF} uses @code{opacity} only.\r
1590 @opindex transpalpha\r
1591 @opindex opacity\r
1592 @opindex fill opacity\r
1593 When transparent polygons are in the foreground, objects behind them\r
1594 (drawn earlier) are visible with color subdued and tinted.  The hidden\r
1595 surface algorithm of @code{sketch} works well with such transparent\r
1596 polygons.\r
1598 Note that @verb{|cull=false|}\r
1599 @opindex cull\r
1600 must be used for rear-facing polygons to be visible when positioned\r
1601 behind other transparent surfaces.\r
1603 @node Internal options,  , Transparency, Options\r
1604 @comment  node-name,  next,  previous,  up\r
1605 @subsubsection Internal options\r
1606 There are also @emph{internal} options\r
1607 @cindex options, internal\r
1608 @cindex internal options\r
1609 used only by @code{sketch} and not\r
1610 passed on to @code{PSTricks}.  These are summarized in the following\r
1611 table.\r
1612 @sxindex cull\r
1613 @sxindex lay\r
1614 @sxindex split\r
1615 @multitable {@code{split}}{@code{over}, @code{in}, @code{under}}{A column that ought to wrap.  Will it wrap?  I do not know.}\r
1616 @headitem Key @tab Possible values @tab Description\r
1617 @item @code{cull}\r
1618 @tab  @code{true}, @code{false}\r
1619 @tab  Turn culling of backfaces on and off respectively for this object.\r
1620 The default value is @code{true}.\r
1621 @item @code{lay}\r
1622 @tab  @code{over}, @code{in}, @code{under}\r
1623 @tab  Force this object to be @code{under} or\r
1624 @code{over} all other objects in the depth sort\r
1625 @cindex depth sort\r
1626 order created by the hidden surface algorithm.  The default value\r
1627 @code{over} guarantees that output due to the @code{special} will be\r
1628 visible.\r
1629 @item @code{split}\r
1630 @tab  @code{true}, @code{false}\r
1631 @tab  Turn splitting of sweep-generated body polygons \r
1632 @cindex body polygon\r
1633 @cindex polygon, body\r
1634 on and off respectively. @xref{Sweeps}.  The default value @code{true}\r
1635 causes ``warped'' polygons to be split into triangles, which avoids\r
1636 mistakes by the hidden surface algorithm.\r
1637 @end multitable\r
1639 @subsection Point lists\r
1640 @sxindex point list\r
1641 @strong{Syntax:}\r
1642 @example\r
1643 (@var{x1},@var{y1},@var{z1})(@var{x2},@var{y2},@var{z2})@dots{}\r
1644 @end example\r
1645 @noindent\r
1646 A sequence of one or more points makes a point list, a feature\r
1647 common to all drawables.  Each of the point components is a scalar\r
1648 arithmetic expression.  Any point may have the @math{z}-component\r
1649 omitted; it will default to @math{z=0}.\r
1651 @menu\r
1652 * Drawables::                   Things that are drawn.\r
1653 * Definitions::                 Things with names.\r
1654 @end menu\r
1656 @node Drawables, Definitions, Language basics, Input language\r
1657 @comment  node-name,  next,  previous,  up\r
1658 @section Drawables\r
1659 @cindex drawable\r
1660 Drawables are simply @code{sketch} objects that might appear in the\r
1661 drawing.  They include dots, polylines, curves, polygons, and more\r
1662 complex objects that are built up from simpler ones in various ways.\r
1663 Finally, @dfn{special} objects are those composed of @LaTeX{} or\r
1664 @code{PSTricks} code, perhaps including coordinates and angles\r
1665 computed by @code{sketch}.\r
1667 @menu\r
1668 * Dots::                        Draw dots.\r
1669 * Lines::                       Draw polylines.\r
1670 * Curves::                      Draw curves.\r
1671 * Polygons::                    Draw polygons.\r
1672 * Specials::                    Embed raw @LaTeX{} and @code{PSTricks}.\r
1673 * Sweeps::                      Draw sweeps of dots and polylines.\r
1674 * Blocks::                      Group other drawables.\r
1675 * Repeats::                     Draw transformed copies of objects.\r
1676 * Puts::                        Draw one object transformed.\r
1677 @end menu\r
1679 @node Dots, Lines, Drawables, Drawables\r
1680 @comment  node-name,  next,  previous,  up\r
1681 @subsection Dots\r
1682 @sxindex dots\r
1683 @strong{Syntax:}\r
1684 @example\r
1685 dots[@var{options}] @var{point_list}\r
1686 @end example\r
1687 @noindent\r
1688 This command is the three-dimensional equivalent of the\r
1689 @code{PSTricks} command @code{\psdots}.\r
1691 @node Lines, Curves, Dots, Drawables\r
1692 @comment  node-name,  next,  previous,  up\r
1693 @subsection Lines\r
1694 @sxindex line\r
1695 @strong{Syntax:}\r
1696 @example\r
1697 line[@var{options}] @var{point_list}\r
1698 @end example\r
1699 @noindent\r
1700 This command is the three-dimensional equivalent of the \r
1701 @code{PSTricks} command @code{\psline}.\r
1703 @node Curves, Polygons, Lines, Drawables\r
1704 @comment  node-name,  next,  previous,  up\r
1705 @subsection Curves\r
1706 @sxindex curve\r
1707 @strong{Syntax:}\r
1708 @example\r
1709 curve[@var{options}] @var{point_list}\r
1710 @end example\r
1711 @noindent\r
1712 This command is the three-dimensional equivalent of the \r
1713 @code{PSTricks} command @code{\pscurve}. @b{It is not\r
1714 implemented in the current version of @code{sketch}}.\r
1716 @node Polygons, Specials, Curves, Drawables\r
1717 @comment  node-name,  next,  previous,  up\r
1718 @subsection Polygons\r
1719 @sxindex polygon\r
1720 @strong{Syntax:}\r
1721 @example\r
1722 polygon[@var{options}] @var{point_list}\r
1723 @end example\r
1724 @noindent\r
1725 @noindent\r
1726 This command is the three-dimensional equivalent of the\r
1727 @code{PSTricks} command @code{\pspolygon}.  The @code{sketch} hidden\r
1728 surface algorithm assumes that polygons are convex and planar.  \r
1729 @cindex polygon, planar\r
1730 @cindex planarity of polygons\r
1731 In practice, drawings may well turn out correctly even if these\r
1732 assumptions are violated.\r
1734 @node Specials, Sweeps, Polygons, Drawables\r
1735 @comment  node-name,  next,  previous,  up\r
1736 @subsection Specials\r
1737 @sxindex special\r
1738 @strong{Syntax:}\r
1739 @example\r
1740 special $@var{raw_text}$[lay=@var{lay_value}] @var{point_list}\r
1741 @end example\r
1742 @noindent\r
1743 Here @code{$} \r
1744 @cindex quoting, special\r
1745 can be any character and is used to delimit the start\r
1746 and end of @var{raw_text}.  The command embeds @var{raw_text} in the\r
1747 @code{sketch} output after performing substitutions as follows.\r
1748 @cindex special argument substitution\r
1749 @cindex argument, special\r
1750 @itemize\r
1751 @item \r
1752 @code{#@var{i}} where @var{i} is a positive integer is replaced by \r
1753 the @var{i}'th point in @var{point_list}.\r
1754 @item\r
1755 @code{#@{@var{i}@}} is also replaced as above.\r
1756 @item\r
1757 @code{#@var{i}-@var{j}} where @var{i} and @var{j} are positive\r
1758 integers is replaced by a string @code{@{@var{angle}@}} where\r
1759 @var{angle} is the polar angle of a vector from the @var{i}'th point\r
1760 in @var{point_list} to the @var{j}'th.\r
1761 @item\r
1762 @code{#@{@var{i}-@var{j}@}} is also replaced as above.\r
1763 @item \r
1764 @code{##} is replaced with @code{#}.\r
1765 @end itemize\r
1766 @noindent\r
1767 The forms with braces @samp{@{ @}} are useful when the argument is\r
1768 immediately followed by a digit that is part of the @TeX{} code.\r
1770 The only useful option of @code{special} is @code{lay}.\r
1771 @sxindex lay\r
1772 @xref{Internal options}.\r
1774 @node Sweeps, Blocks, Specials, Drawables\r
1775 @comment  node-name,  next,  previous,  up\r
1776 @subsection Sweeps\r
1777 @sxindex sweep\r
1778 @strong{Syntax:}\r
1779 @example\r
1780 sweep @{ @var{n}, @var{T_1}, @var{T_2}, @dots{}, @var{T_@math{r}} @}[@var{options}] @var{swept_object}\r
1781 sweep @{ @var{n}<>, @var{T_1}, @var{T_2}, @dots{}, @var{T_@math{r}} @}[@var{options}] @var{swept_object}\r
1782 @end example\r
1783 @noindent\r
1784 The sweep connects @var{n} (or perhaps @math{@var{n}+1}) copies of\r
1785 @var{swept_object} \r
1786 @cindex swept object\r
1787 in order to create a new object of higher\r
1788 dimension.  The @var{T_@math{i}} (for @math{i} between @math{1} and\r
1789 @math{r}) are transforms.  \r
1790 @cindex transform\r
1791 The @math{k}'th copy of @var{swept_object} is produced by applying the\r
1792 following transform to the original.\r
1793 @example\r
1794 @math{@var{T_1}^k} then @math{@var{T_2}^k} then @dots{} then @math{@var{T_r}^k}\r
1795 @end example\r
1796 @noindent\r
1797 Here @math{@var{T}^k} means ``transform @var{T} applied @math{k}\r
1798 times.''  The original object is the zero'th copy, with @math{k=0} and\r
1799 effectively no transform applied (@math{T^0=I}, the identity\r
1800 transform).\r
1802 The method of connecting the copies depends on the type of\r
1803 @var{swept_object} and on whether the closure tag\r
1804 @sxindex <>@r{, closure tag}\r
1805 @cindex closure tag, @code{<>}\r
1806 @samp{<>} is present\r
1807 or not.\r
1809 An example of a sweep where @math{r=2} is the Mobius figure at\r
1810 @ref{More to learn}.\r
1812 @menu\r
1813 * Swept points::                Swept points make lines or polygons.\r
1814 * Swept lines::                 Swept lines make open or closed surfaces.\r
1815 * Swept polygons::              Swept polygons make closed surfaces.\r
1816 * Swept blocks::                Swept block @equiv{} block of sweeps.\r
1817 * Sweep face splitting::        Fixing warped faces with triangles.\r
1818 @end menu\r
1820 @node Swept points, Swept lines, Sweeps, Sweeps\r
1821 @comment  node-name,  next,  previous,  up\r
1822 @subsubsection Swept points\r
1823 @cindex swept point\r
1824 @cindex point sweep\r
1825 If @var{swept_object} is a point list and there is no closure tag,\r
1826 @sxindex <>@r{, closure tag}\r
1827 @cindex closure tag, @code{<>}\r
1828 then @code{sweep} connects @math{@var{n}+1} successive copies of each\r
1829 point (including the original) with straight line segments to form a\r
1830 polyline.  If there are @math{m} points in the original point list,\r
1831 @cindex point list\r
1832 then @math{m} polylines with @var{n} segments each are formed by the\r
1833 sweep.  In this manner, @code{sweep} forms a set of one-dimensional\r
1834 objects (polylines) from zero-dimensional ones (points).\r
1836 When there @emph{is} a closure tag, \r
1837 @sxindex <>@r{, closure tag}\r
1838 @cindex closure tag, @code{<>}\r
1839 @code{sweep} connects @var{n}\r
1840 successive copies of each point (including the original) with straight\r
1841 line segments and finally connects the last copy back to the original\r
1842 to form a polygon with @var{n} sides.  If there are @math{m} points in\r
1843 the original point list, then @math{m} polygons with @var{n} sides\r
1844 each are formed by the sweep.  In this manner, @code{sweep} forms a\r
1845 set of two-dimensional objects (polygons) from zero-dimensional ones\r
1846 (points).\r
1848 Options \r
1849 @cindex options, sweep\r
1850 of the @code{sweep} are copied directly to the resulting\r
1851 polyline(s).\r
1853 @node Swept lines, Swept polygons, Swept points, Sweeps\r
1854 @comment  node-name,  next,  previous,  up\r
1855 @subsubsection Swept lines\r
1856 @cindex swept line\r
1857 @cindex line sweep\r
1858 If @var{swept_object} is a polyline and there is no closure tag, \r
1859 @sxindex <>@r{, closure tag}\r
1860 @cindex closure tag, @code{<>}\r
1861 then\r
1862 @code{sweep} connects @math{@var{n}+1} successive copies of the\r
1863 polyline (including the original) with four-sided polygons, each pair\r
1864 of copies giving rise to a ``polygon strip.''  If there are @math{m}\r
1865 points in the original polyline, then @math{(m-1)@var{n}} polygons are\r
1866 formed by the sweep.  We call these @dfn{body polygons}.\r
1867 @cindex body polygon\r
1868 @cindex polygon, body\r
1869 In this manner, @code{sweep} forms a\r
1870 two-dimensional surface from from a one-dimensional polyline.\r
1872 The order of vertices \r
1873 @cindex polygon vertex order\r
1874 @cindex order, polygon vertex\r
1875 produced by @code{sweep} is important.  If a\r
1876 polygon's vertices do not appear in counter-clockwise order in the\r
1877 final image, the polygon will be culled \r
1878 @cindex culling\r
1879 (unless @code{cull=false} is\r
1880 set).  If the points in the @math{k}'th copy of the polyline are\r
1881 @math{P_1}, @math{P_2}, @dots{}, @math{P_m}, and the points in the\r
1882 next copy, the @math{(k+1)}st, are @math{P_1'}, @math{P_2'}, @dots{},\r
1883 @math{P_m'}, then the vertex order of the generated polygons is\r
1884 @display\r
1885 Body polygon 1: @math{P_2} @math{P_1} @math{P_1'} @math{P_2'} \r
1886 Body polygon 2: @math{P_3} @math{P_2} @math{P_2'} @math{P_3'} \r
1887 @dots{}\r
1888 Body polygon @math{m-1}: @math{P_m} @math{P_{m-1}} @math{P_{m-1}'} @math{P_m'} \r
1889 @end display\r
1891 Options of unclosed line sweeps \r
1892 @cindex options, sweep\r
1893 are copied to each output polygon.\r
1894 Options of the swept line are ignored.\r
1895 @cindex options, swept object\r
1897 When there @emph{is} a closure tag, \r
1898 @sxindex <>@r{, closure tag}\r
1899 @cindex closure tag, @code{<>}\r
1900 then @code{sweep} connects @var{n}\r
1901 successive copies of the polyline (including the original) with\r
1902 four-sided body polygons just as the case with no closure tag.  It then\r
1903 connects the last copy back to the original to form a ribbon-shaped\r
1904 surface that closes on itself with two holes remaining.\r
1906 Finally, the sweep adds two more polygons to seal the holes and form a\r
1907 closed surface that, depending on the sweep transforms, may\r
1908 represent the boundary of a solid.  In this manner, @code{sweep} forms\r
1909 the boundary of a three-dimensional object from a one-dimensional\r
1910 polyline.  We call these hole-filling polygons @dfn{ends}.\r
1911 @cindex end polygon\r
1912 @cindex polygon, end\r
1914 The order of vertices of end polygons \r
1915 @cindex polygon vertex order\r
1916 @cindex order, polygon vertex\r
1917 is important for correct culling\r
1918 as described above.  If @math{P_1^1}, @math{P_1^2}, @dots{},\r
1919 @math{P_1^n} are the @var{n} copies of the first polyline point and\r
1920 @math{P_m^1}, @math{P_m^2}, @dots{} ,@math{P_m^n} are the @var{n}\r
1921 copies of the last polyline point, then the end polygon vertex order\r
1922 is\r
1923 @display\r
1924 End polygon 1: @math{P_1^n}, @math{P_1^{n-1}}, @dots{} ,@math{P_1^1}\r
1925 End polygon 2: @math{P_m^1}, @math{P_m^2}, @dots{} ,@math{P_m^n}\r
1926 @end display\r
1928 If there are no options on the swept line, \r
1929 @cindex options, swept object\r
1930 then the @samp{sweep}\r
1931 options \r
1932 @cindex options, sweep\r
1933 are copied to each output polygon.  If the swept line does\r
1934 have options, these are copied to corresponding body polygons; the\r
1935 sweep options are copied to the end polygons.  In this manner, body\r
1936 and ends may be drawn with different characteristics such as\r
1937 @code{fillcolor}.\r
1939 @node Swept polygons, Swept blocks, Swept lines, Sweeps\r
1940 @comment  node-name,  next,  previous,  up\r
1941 @subsubsection Swept polygons\r
1942 @cindex polygon sweep\r
1943 If @var{swept_object} is a polygon, the @code{sweep} connects\r
1944 @math{@var{n}+1} successive copies of the closed polyline border of\r
1945 the polygon to form body polygons exactly as though the border were a\r
1946 swept polyline as described in @ref{Swept lines}.\r
1947 @cindex body polygon\r
1948 @cindex polygon, body\r
1949 If there are @math{m} points in the\r
1950 original polygon, then @math{m@var{n}} body polygons are formed by\r
1951 this sweep.  The body polygons form an @dfn{extrusion} of the boundary of the\r
1952 original polygon with two holes at the open ends.  \r
1954 Finally, the sweep adds two copies of the original polygon to cover\r
1955 the holes.  We call these hole-filling polygons @dfn{ends}.\r
1956 @cindex end polygon\r
1957 @cindex polygon, end\r
1958 In this manner, @code{sweep} forms the boundary of a three-dimensional\r
1959 object from a two-dimensional polygon.\r
1961 The order of vertices \r
1962 @cindex polygon vertex order\r
1963 @cindex order, polygon vertex\r
1964 of end polygons is important for correct culling as described above.\r
1965 An exact copy of the original polygon with vertex order intact forms\r
1966 the first end polygon.  The other end polygon results from\r
1967 transforming and the reversing the order of vertices in the original.\r
1968 The transform places the original polygon at the uncovered hole;\r
1969 it is\r
1970 @example\r
1971 @math{@var{T_1}^n} then @math{@var{T_2}^n} then @dots{} then @math{@var{T_r}^n}.\r
1972 @end example\r
1973 @noindent\r
1974 If there are no options on the swept polygon, then the @samp{sweep}\r
1975 options are copied to each output polygon.  If the swept polygon does\r
1976 have options, these are copied to the ends; the sweep options are\r
1977 copied to the body polygons.  In this manner, body and ends may be\r
1978 drawn with different characteristics such as @code{fillcolor}.\r
1980 @node Swept blocks, Sweep face splitting, Swept polygons, Sweeps\r
1981 @comment  node-name,  next,  previous,  up\r
1982 @subsubsection Swept blocks\r
1983 @cindex swept bock\r
1984 @cindex block sweep\r
1985 The swept object @var{swept_object} may also be any collection of\r
1986 polylines and polygons.  This may be a block \r
1987 @cindex block\r
1988 @sxindex @{ @}@r{, block drawable}\r
1989 composed of @code{line} \r
1990 @sxindex line\r
1991 and/or @code{polygon} \r
1992 @sxindex polygon\r
1993 commands in braces\r
1994 @samp{@{ @}}, or it may be the result of a @code{repeat}, another\r
1995 @code{sweep}, etc.  The sweep acts independently on each object in the\r
1996 block exactly as if it were a single swept object described above in\r
1997 @ref{Swept lines} and @ref{Swept polygons}.\r
1999 @node Sweep face splitting,  , Swept blocks, Sweeps\r
2000 @comment  node-name,  next,  previous,  up\r
2001 @subsubsection Sweep face splitting\r
2002 Before sending each four-sided body polygon of a @code{sweep}\r
2003 to the output, @code{sketch} tests to see if it is roughly planar.\r
2004 @cindex polygon, planar\r
2005 @cindex planarity of polygons\r
2006 Since planarity is necessary for proper functioning of the hidden\r
2007 surface algorithm, ``warped'' polygons are automatically split into\r
2008 two triangles.  \r
2010 Hole-filling polygons produced by closure-tagged \r
2011 @sxindex <>@r{, closure tag}\r
2012 @cindex closure tag, @code{<>}\r
2013 line sweeps are not\r
2014 split.  Nor are original polygons in polygon sweeps.  It is the user's\r
2015 responsibility to ensure these are planar.\r
2017 @node Blocks, Repeats, Sweeps, Drawables\r
2018 @comment  node-name,  next,  previous,  up\r
2019 @subsection Blocks\r
2020 @cindex block\r
2021 @sxindex @{ @}@r{, block drawable}\r
2022 Any sequence of drawables may be grouped in a @dfn{block} merely by\r
2023 enclosing them in braces @samp{@{ @}}.  A block is itself drawable.  A\r
2024 key use of blocks is to extend the effect of a single @code{def},\r
2025 @ref{Definitions}, @code{put} @ref{Puts}, @code{sweep} @ref{Sweeps},\r
2026 or @code{repeat} @ref{Repeats} to include several objects rather than\r
2027 one.\r
2029 Definitions (@xref{Definitions}.) inside a block have @dfn{lexical\r
2030 scope} \r
2031 @cindex lexical scope\r
2032 @cindex scope, identifier\r
2033 extending from the place of definition to the end of the block.\r
2035 @node Repeats, Puts, Blocks, Drawables\r
2036 @comment  node-name,  next,  previous,  up\r
2037 @subsection Repeats\r
2038 @sxindex repeat\r
2039 @cindex repeated object\r
2040 @strong{Syntax:}\r
2041 @example\r
2042 repeat @{ @var{n}, @var{T_1}, @var{T_2}, @dots{}, @var{T_r} @} @var{repeated_object}\r
2043 @end example\r
2044 @noindent\r
2045 The repeat makes @var{n} transformed copies of @var{repeated_object}\r
2046 (including the original).  The @var{T_@math{i}} are transforms.\r
2047 @cindex transform\r
2048 The @math{k}'th copy of the @var{repeated_object} (for\r
2049 @math{k=0,1,...,n-1}) is produced in the\r
2050 same manner as for @code{sweep}s described in @ref{Sweeps}.  This is\r
2051 repeated here (no pun intended) for convenience.  To make the\r
2052 @math{k}'th copy, the following transform is applied to the\r
2053 original object.\r
2054 @example\r
2055 @math{@var{T_1}^k} then @math{@var{T_2}^k} then @dots{} then @math{@var{T_r}^k}\r
2056 @end example\r
2057 @noindent\r
2058 Here @math{@var{T}^k} means ``transform @var{T} applied @math{k}\r
2059 times.'' \r
2061 @node Puts,  , Repeats, Drawables\r
2062 @comment  node-name,  next,  previous,  up\r
2063 @subsection Puts\r
2064 @sxindex put\r
2065 @strong{Syntax:}\r
2066 @example\r
2067 put @{ @var{T} @} @var{put_object}\r
2068 @end example\r
2069 @noindent\r
2070 Put merely applies transform @var{T} to the drawable @var{put_object}.\r
2072 @node Definitions, Global environment, Drawables, Input language\r
2073 @comment  node-name,  next,  previous,  up\r
2074 @section Definitions\r
2075 @cindex definition\r
2076 Definitions give names to @code{sketch} objects.  Definitions alone\r
2077 are benign.  A @code{sketch} input file consisting entirely of\r
2078 definitions will generate no drawing.  Only when definitions are\r
2079 @dfn{referenced} do they potentially lead to ink on the drawing.\r
2081 The intent of definitions is to make @code{sketch} code more concise\r
2082 and readable.  There is no input file employing definitions\r
2083 that could not be re-written without them.\r
2085 Definable objects include any result of an affine arithmetic\r
2086 expression (scalar, point, vector, or transform), any drawable\r
2087 object (dots, line, curve, polygon, block, sweep, put, repeat, or\r
2088 special), and option strings.  In addition, @dfn{tag definitions},\r
2089 @cindex definition, tag\r
2090 @cindex tag definition\r
2091 which have no associated object at all, allow the meaning of other\r
2092 definitions to be selected from a set of alternatives. Since tags may\r
2093 be defined (and undefined) in the command line of @code{sketch}, they\r
2094 can be an aid in the script-driven preparation of documents.\r
2096 @menu\r
2097 * Forms of definitions::        Different defs for different purposes.\r
2098 * Forms of references::         How references denote types.\r
2099 @end menu\r
2101 @node Forms of definitions, Forms of references, Definitions, Definitions\r
2102 @comment  node-name,  next,  previous,  up\r
2103 @subsection Forms of definitions\r
2104 Definitions have three possible forms, @dfn{simple}, \r
2105 @cindex simple definition\r
2106 @cindex definition, simple\r
2107 @dfn{with alternatives}, \r
2108 @cindex definition with alternatives\r
2109 @cindex alternatives, definition\r
2110 and @dfn{tag} \r
2111 @cindex tag definition\r
2112 @cindex definition, tag\r
2113 as shown here in order.\r
2115 @noindent\r
2116 @strong{Syntax:}\r
2117 @example\r
2118 def @var{id} @var{object}  % simple def\r
2119 def @var{id} <@var{tag_1}> @var{object_1}  % def with alternatives\r
2120        <@var{tag_2}> @var{object_2}\r
2121        @dots{}\r
2122        <> @var{default_object}\r
2123 def @var{id} <>  % tag def\r
2124 @end example\r
2125 @noindent\r
2126 The simple definition merely associates @var{object} with the\r
2127 identifier @var{id}.  \r
2129 The definition with alternatives associates\r
2130 @var{object_i} with @var{id}, where @var{tag_i} is the\r
2131 first defined tag in the list of alternative tag references.\r
2132 @cindex tag reference\r
2133 @cindex reference, tag\r
2134 @sxindex <foo>@r{, tag reference}\r
2135 If no tag in the list is defined, then @var{default_object} is\r
2136 associated with identifier @var{id}.\r
2138 The final form defines @var{id} as a tag.  Another way to define a tag\r
2139 is with the @option{-D} command line option. @xref{Command line}.\r
2141 @node Forms of references,  , Forms of definitions, Definitions\r
2142 @subsection Forms of references\r
2143 References to defined names are enclosed in bracketing delimiters.\r
2144 The delimiter characters imply the type of the associated value as\r
2145 shown in the table below.  A type error is raised if the type of a\r
2146 reference does not match the type of the defined value.  The intent of\r
2147 this mechanism is, again, to make @code{sketch} input files more\r
2148 readable.\r
2149 @multitable {transform}{@code{[@var{id}]} or @code{[@var{id1}, ..., @var{idN}]}}\r
2150 @headitem Type  @tab Reference\r
2151 @item scalar    @tab @code{@var{id}}\r
2152 @cindex scalar reference\r
2153 @cindex reference, scalar\r
2154 @item point     @tab @code{(@var{id})}\r
2155 @cindex point reference\r
2156 @cindex reference, point\r
2157 @sxindex (foo)@r{, point reference}\r
2158 @item vector    @tab @code{[@var{id}]}\r
2159 @cindex vector reference\r
2160 @cindex reference, vector\r
2161 @sxindex [foo]@r{, vector reference}\r
2162 @item transform @tab @code{[[@var{id}]]}\r
2163 @cindex transform reference\r
2164 @cindex reference, transform\r
2165 @sxindex [[foo]]@r{, transform reference}\r
2166 @item drawable  @tab @code{@{@var{id}@}}\r
2167 @cindex drawable reference\r
2168 @cindex reference, drawable\r
2169 @sxindex @{foo@}@r{, drawable reference}\r
2170 @item options   @tab @code{[@var{id}]} or @code{[@var{id1},...,@var{idN}]}\r
2171 @cindex options reference\r
2172 @cindex reference, options\r
2173 @sxindex [foo]@r{, options reference}\r
2174 @cindex options multiple reference\r
2175 @cindex reference, multiple options\r
2176 @sxindex [foo,...,bar]@r{, multiple options reference}\r
2177 @item tag       @tab @code{<@var{id}>}\r
2178 @cindex tag reference\r
2179 @cindex reference, tag\r
2180 @sxindex <foo>@r{, tag reference}\r
2181 @end multitable\r
2182 @sp 1\r
2183 @noindent\r
2184 Note that square brackets @samp{[ ]} are used both for vector and for\r
2185 options references.  Details of @code{sketch} syntax make it\r
2186 impossible for these two reference types to be confused.  The\r
2187 special multiple reference @code{[@var{id1},@var{id2},...,@var{idN}]}\r
2188 acts as if the respective lists of options were concatenated.\r
2190 @node Global environment,  , Definitions, Input language\r
2191 @comment  node-name,  next,  previous,  up\r
2192 @section Global environment\r
2193 An optional global environment block provides a few ways to affect the\r
2194 entire scene.  The block must appear as the last text in the\r
2195 @code{sketch} input file.  It may include definitions, but note\r
2196 that previous definitions at the top level (not nested inside\r
2197 blocks) are also available.\r
2199 @noindent\r
2200 @strong{Syntax:}\r
2201 @sxindex global\r
2202 @example\r
2203 global @{ @var{environment_settings} @}\r
2204 @end example\r
2205 @noindent\r
2206 The contents of @var{environment_settings} are discussed in the\r
2207 sections that follow.\r
2209 @menu\r
2210 * Global options::              Attributes of the entire drawing.\r
2211 * Camera::                      A final camera transformation of the scene.\r
2212 * Picture box::                 Setting the bounding box and 2d clipping.\r
2213 * Frame::                       Adding a box around the drawing.\r
2214 * Language::                    Setting the output language.\r
2215 @end menu\r
2217 @node Global options, Camera, Global environment, Global environment\r
2218 @comment  node-name,  next,  previous,  up\r
2219 @subsection Global options\r
2220 @cindex options, global\r
2221 @cindex global options\r
2222 @sxindex set\r
2223 @strong{Syntax:}\r
2224 @example\r
2225 set [ @var{options} ]\r
2226 @end example\r
2227 @noindent\r
2228 The contents of @var{options}, except for @code{sketch} internal\r
2229 options, are copied as-is to a @verb{|\psset|} that appears before\r
2230 anything else in the output file.  This is a good place to set\r
2231 @code{unit}, a default @code{linewidth}, etc.\r
2233 Internal options \r
2234 @cindex options, internal\r
2235 @cindex internal options\r
2236 work on all objects where they make sense.\r
2237 This includes \r
2238 @sxindex cull\r
2239 @sxindex split\r
2240 @sxindex lay\r
2241 @code{cull} and @code{split} (but not @code{lay}).\r
2242 @xref{Internal options}. \r
2244 @node Camera, Picture box, Global options, Global environment\r
2245 @comment  node-name,  next,  previous,  up\r
2246 @subsection Camera\r
2247 @cindex camera\r
2248 @strong{Syntax:}\r
2249 @sxindex camera\r
2250 @example\r
2251 camera @var{transform_expression}\r
2252 @end example\r
2253 The @var{transform_expression} is applied after all other\r
2254 transformations of the scene.  This is currently only useful for\r
2255 transforming the bounding box.  @xref{Picture box}.  It will play a\r
2256 role in any future implementation of clipping.\r
2258 @node Picture box, Frame, Camera, Global environment\r
2259 @comment  node-name,  next,  previous,  up\r
2260 @subsection Picture box\r
2261 @cindex picture box\r
2262 @strong{Syntax:}\r
2263 @sxindex picturebox\r
2264 @example\r
2265 picturebox[@var{baseline}]\r
2266 picturebox[@var{baseline}] (@var{p1})(@var{p2})\r
2267 @end example\r
2268 @noindent\r
2269 The first form of @code{picturebox} causes a scalar @var{baseline}\r
2270 fraction to be emitted in the @code{pspicture}\r
2271 @cindex @code{pspicture}\r
2272 @cindex baseline fraction\r
2273 environment of the output.  See\r
2274 @code{PSTricks} documentation for @code{pspicture}.\r
2276 In the second form, the @var{baseline} fraction is optional, and the\r
2277 two points that follow define the diagonal of a three-dimensional\r
2278 bounding box\r
2279 @cindex bounding box\r
2280 for the completed scene.  The parallel projection \r
2281 @cindex parallel projection\r
2282 @cindex projection, parallel\r
2283 of the bounding box\r
2284 determines the corners of the drawing's @code{pspicture*} environment,\r
2285 which is used in place of @code{pspicture}.  This causes PostScript to\r
2286 clip\r
2287 @cindex clipping\r
2288 the final drawing to the bounding box in 2d.  If there is a\r
2289 @code{camera} specified, the camera tranformation is applied to the\r
2290 bounding box, and the @code{pspicture} is set just large\r
2291 enough to include the transformed box.\r
2293 When no bounding box is given, @code{sketch} computes one\r
2294 automatically.\r
2296 @node Frame, Language, Picture box, Global environment\r
2297 @comment  node-name,  next,  previous,  up\r
2298 @subsection Frame\r
2299 @cindex frame box\r
2300 @strong{Syntax:}\r
2301 @sxindex frame\r
2302 @example\r
2303 frame [@var{options}]\r
2304 @end example\r
2305 @noindent\r
2306 Causes a @verb{|\psframebox|} \r
2307 @cindex @code{psframebox}\r
2308 to surround the @code{pspicture}\r
2309 environment in the output.  If @var{options} are present, they are\r
2310 copied as-is.  Normally one would want to set \r
2311 @opindex linewidth\r
2312 @code{linewidth},\r
2313 @opindex linestyle\r
2314 @code{linestyle}, \r
2315 @opindex linecolor\r
2316 @code{linecolor}, etc. \r
2317 If omitted, then \r
2318 @opindex framesep\r
2319 @code{framesep=0pt} is\r
2320 added so that the frame tightly hugs the @code{pspicture}.\r
2322 @node Language,  , Frame, Global environment\r
2323 @comment  node-name,  next,  previous,  up\r
2324 @subsection Language\r
2325 @cindex language, output\r
2326 @cindex output language\r
2327 @sxindex language\r
2328 @example\r
2329 language tikz\r
2330 language tikz, context\r
2331 language pstricks\r
2332 language pstricks, latex\r
2333 @end example\r
2334 @noindent\r
2335 Sets the output language generated by @code{sketch}.  \r
2336 @sxindex pstricks\r
2337 @sxindex tikz\r
2338 The set of options understood by sketch also changes.  For example,\r
2339 the @code{PSTricks} option @code{linewidth} will not be properly\r
2340 handled if @code{language} is set to @code{tikz}.  Similarly, the\r
2341 @code{TikZ} option @code{line style} (note the space) will not be\r
2342 properly handled if @code{language} is set to @code{pstricks}.  If no\r
2343 language is specified, the default @code{pstricks} is used.\r
2345 An optional comma followed by \r
2346 @code{latex} \r
2347 @sxindex latex\r
2348 or \r
2349 @code{context} \r
2350 @sxindex context\r
2351 specifies the macro package that the output should assume.  This\r
2352 affects the @code{picture} environment commands emitted and the\r
2353 document template used with the @option{-T} option. @xref{Command\r
2354 line}.  Note that at the time this manual was generated,\r
2355 @code{PSTricks} was not supported by @LaTeX{} or by @code{ConTeXt}.\r
2357 @node Building a drawing, Command line, Input language, Top\r
2358 @comment  node-name,  next,  previous,  up\r
2359 @chapter Building a drawing\r
2360 Successful drawings with @code{sketch} and with any scene description\r
2361 language\r
2362 @cindex scene description language\r
2363 require that the user develop an accurate mental picture of her code\r
2364 and its meaning.  This image is best built in small pieces.\r
2365 Therefore, @code{sketch} inputs are best created in small increments\r
2366 with frequent pauses to compile and view the results.  Careful\r
2367 comments in the input often help as a scene grows in complexity.\r
2369 @menu\r
2370 * Overview::                    Building a substantial drawing.\r
2371 * A technical drawing::         An example with fine placement.\r
2372 * A hierarchical model::        An example with sweeps and puts.\r
2373 * Caveats::                     Where trouble can occur.\r
2374 @end menu\r
2376 @node Overview, A technical drawing, Building a drawing, Building a drawing\r
2377 @comment  node-name,  next,  previous,  up\r
2378 @section Overview\r
2379 As an overview, let's develop a diagram that shows how a perspective\r
2380 projection transform\r
2381 @cindex perspective projection\r
2382 @cindex transform\r
2383 @cindex projection, perspective\r
2384 works.  We'll start with the traditional reference object\r
2385 used in computer graphics textbooks, a house-shaped prism.  Begin\r
2386 by defining the points of the house.  Rather than defining the faces\r
2387 of the house as polygons and transforming those, we are going to\r
2388 transform the points themselves with @code{sketch} arithmetic so that\r
2389 we have names for the transformed points later.\r
2390 @sxindex def\r
2391 @verbatim\r
2392   % right side (outside to right)\r
2393   def R1 (1,1,1) def R2 (1,-1,1) def R3 (1,-1,-1) def R4 (1,1,-1)\r
2394   def R5 (1,1.5,0)\r
2396   % left side (outside to right--backward)\r
2397   def W  [2,0,0]\r
2398   def L1 (R1)-[W] def L2 (R2)-[W] def L3 (R3)-[W] def L4 (R4)-[W]\r
2399   def L5 (R5)-[W]\r
2400 @end verbatim\r
2401 @noindent\r
2402 To add a door to the house, we use a polygon slightly in\r
2403 front of the foremost face of the house.\r
2404 @verbatim\r
2405   % door\r
2406   def e .01\r
2407   def D1 (0,-1,1+e) def D2 (.5,-1,1+e) def D3 (.5,0,1+e) def D4 (0,0,1+e)\r
2408 @end verbatim\r
2409 @noindent\r
2410 Now let's create a new set of points that are a to-be-determined\r
2411 transform of the originals.\r
2412 @verbatim\r
2413   def hp scale(1) % house positioner\r
2414   def pR1 [[hp]]*(R1) def pR2 [[hp]]*(R2) def pR3 [[hp]]*(R3)\r
2415   def pR4 [[hp]]*(R4) def pR5 [[hp]]*(R5)\r
2416   def pL1 [[hp]]*(L1) def pL2 [[hp]]*(L2) def pL3 [[hp]]*(L3)\r
2417   def pL4 [[hp]]*(L4) def pL5 [[hp]]*(L5)\r
2418   def pD1 [[hp]]*(D1) def pD2 [[hp]]*(D2) def pD3 [[hp]]*(D3)\r
2419   def pD4 [[hp]]*(D4) \r
2420 @end verbatim\r
2421 @noindent\r
2422 Note the use of a @dfn{transform definition} \r
2423 @cindex transform definition\r
2424 @cindex definition, transform\r
2425 @sxindex [[foo]]@r{, transform reference}\r
2426 and\r
2427 @dfn{transform references}.\r
2428 @cindex transform reference\r
2429 @cindex reference, transform\r
2430 @sxindex [[foo]]@r{, transform reference}\r
2431 Now define the seven polygonal faces of the house and the door using\r
2432 the transformed points as vertices.  Be careful with vertex order!\r
2433 @cindex polygon vertex order\r
2434 @cindex order, polygon vertex\r
2435 @opindex fillcolor\r
2436 @sxindex def\r
2437 @sxindex polygon\r
2438 @sxindex @{ @}@r{, block drawable}\r
2439 @verbatim\r
2440   def rgt polygon (pR1)(pR2)(pR3)(pR4)(pR5)\r
2441   def lft polygon (pL5)(pL4)(pL3)(pL2)(pL1)\r
2442   def frt polygon (pR2)(pR1)(pL1)(pL2)\r
2443   def bck polygon (pR4)(pR3)(pL3)(pL4)\r
2444   def tfr polygon (pR1)(pR5)(pL5)(pL1)\r
2445   def tbk polygon (pR5)(pR4)(pL4)(pL5)\r
2446   def bot polygon (pR2)(pL2)(pL3)(pR3)\r
2447   def door polygon[fillcolor=brown] (pD1)(pD2)(pD3)(pD4)\r
2448   def house { {rgt}{lft}{frt}{bck}{tfr}{tbk}{bot}{door} }\r
2449 @end verbatim\r
2450 Time for a sanity check.  Add the line\r
2451 @sxindex @{foo@}@r{, drawable reference}\r
2452 @cindex reference, drawable\r
2453 @verbatim\r
2454   {house}\r
2455 @end verbatim\r
2456 @noindent\r
2457 and this is what we get.\r
2459 @center @image{ex130}\r
2461 @noindent\r
2462 This is correct, but does not reveal very much.  Common errors are\r
2463 misplaced vertices and polygons missing entirely due to incorrect\r
2464 vertex order.  \r
2465 @cindex polygon vertex order\r
2466 @cindex order, polygon vertex\r
2467 To rule these out, let's inspect all sides of the\r
2468 house. This is not hard. Merely replace the reference\r
2469 @verb{|{house}|} with a @code{repeat}. @xref{Repeats}.\r
2470 @sxindex @{foo@}@r{, drawable reference}\r
2471 @cindex reference, drawable\r
2472 @sxindex repeat\r
2473 @sxindex rotate\r
2474 @sxindex translate\r
2475 @verbatim\r
2476   repeat { 13, rotate(30, [1,2,3]), translate([3,0,0]) } {house}\r
2477 @end verbatim\r
2478 @center @image{ex140}\r
2480 @noindent\r
2481 Again things look correct.  Note that the hidden surface algorithm\r
2482 handles intersecting polygons correctly where some copies of the house\r
2483 overlap. \r
2485 Let's lay out the geometry of perspective projection of the house onto\r
2486 a plane with rays passing through the origin.  Begin by positioning the\r
2487 house twelve units back on the negative @math{z}-axis and adding a set\r
2488 of coordinate axes.  To move the house we need only change the ``house\r
2489 positioning'' transform defined earlier.\r
2490 @sxindex def\r
2491 @sxindex rotate\r
2492 @sxindex translate\r
2493 @opindex arrows\r
2494 @opindex linewidth\r
2495 @opindex linecolor\r
2496 @opindex linestyle\r
2497 @sxindex special\r
2498 @sxindex line\r
2499 @verbatim\r
2500   def hp rotate(-40, [0,1,0]) then translate([0,0,-12])\r
2501   def axes {\r
2502     def sz 1\r
2503     line [arrows=<->] (sz,0,0)(O)(0,sz,0)\r
2504     line [arrows=->]  (O)(0,0,sz)\r
2505     line [linewidth=.2pt,linecolor=blue,linestyle=dashed] (O)(0,0,-10)\r
2506     special |\uput[r]#1{$x$}\uput[u]#2{$y$}\uput[l]#3{$z$}|\r
2507       (sz,0,0)(0,sz,0)(0,0,sz)\r
2508   }\r
2509 @end verbatim\r
2511 Time for another test.  Let's build a real view transform,\r
2512 creating a @dfn{virtual camera}\r
2513 @cindex virtual camera\r
2514 to look at the scene we are constructing.  Replace the @code{repeat}\r
2515 with\r
2516 @verbatim\r
2517   def eye (10,4,10)\r
2518   def look_at (0,0,-5)\r
2519   put { view((eye), (look_at)) } { {house}{axes} }\r
2520 @end verbatim\r
2521 The @dfn{view transform} repositions the scene so that the point\r
2522 @code{eye} is at the origin and the direction from @code{eye} to\r
2523 @code{look_at} is the negative @math{z}-axis.  This requires a\r
2524 rotation and a translation that are all packed into the constructor\r
2525 @code{view}.\r
2527 @center @image{ex150}\r
2529 @noindent\r
2530 This is starting to look good!  Add the projection plane half way\r
2531 between the origin and the house at @math{z=-5}.  We'll try\r
2532 the angle argument feature of @code{special} to position a label.\r
2533 @verbatim\r
2534   def p 5 % projection distance (plane at z=-p)\r
2535   def projection_plane {\r
2536     def sz 1.5\r
2537     polygon (-sz,-sz,-p)(sz,-sz,-p)(sz,sz,-p)(-sz,sz,-p)\r
2538     special |\rput[b]#1-2#3{\footnotesize\sf projection plane}| \r
2539       (-sz,-sz,-p)(sz,-sz,-p)(0,-sz+.1,-p)\r
2540   }\r
2541 @end verbatim\r
2542 @noindent\r
2543 Add @verb{|{projection_plane}|} to the list of objects in the\r
2544 @code{put} above.\r
2546 @center @image{ex160}\r
2548 @indent\r
2549 The way we constructed the points of the house now makes it easy to\r
2550 draw rays of projection.  We'll cast one ray from every visible vertex\r
2551 of the house and define options so the appearance of\r
2552 all rays can be changed at the same time.\r
2553 @verbatim\r
2554   def projection_rays {\r
2555     def rayopt [linewidth=.3pt,linecolor=lightgray]\r
2556     line [rayopt](O)(pR1) line [rayopt](O)(pR2) line[rayopt](O)(pR3)\r
2557     line [rayopt](O)(pR4) line [rayopt](O)(pR5)\r
2558     line [rayopt](O)(pL1) line [rayopt](O)(pL2) line[rayopt](O)(pL5)\r
2559     line [rayopt](O)(pD1) line [rayopt](O)(pD2) \r
2560     line [rayopt](O)(pD3) line [rayopt](O)(pD4) \r
2561   }\r
2562 @end verbatim\r
2563 @noindent\r
2564 The result is shown here.  \r
2566 @center @image{ex170}\r
2568 @noindent\r
2569 The rays pierce the projection plane at the corresponding points on\r
2570 the perspective image we are trying to draw.  Albrecht D@"urer and his\r
2571 Renaissance contemporaries had the same idea in the early 1500's.\r
2573 @center @image{duerer,,1.5in}\r
2575 All that's left is to find a way to connect the points of the house\r
2576 on the projection plane.  We could pull out a good computer graphics\r
2577 text, find the necessary matrix, and enter it ourselves as a\r
2578 transform literal.  @xref{Transform literals}. That work is\r
2579 already done, however.  We can use the @code{project(p)} constructor.\r
2581 There are still some details that require care.  Projection will\r
2582 flatten whatever is transformed onto the plane @math{z=-p}.  Therefore\r
2583 any part of the house could disappear behind the projection plane (the\r
2584 hidden surface algorithm orders objects at the same depth\r
2585 arbitrarily).  The door may also disappear behind the front of the\r
2586 house.  To make sure everything remains visible, we'll place the house\r
2587 a tiny bit in front of the projection plane and a second copy of the\r
2588 door in front of the house.\r
2589 @verbatim\r
2590   def projection {\r
2591     % e is a small number defined above\r
2592     put { project(p) then translate([0,0,1*e]) } {house}\r
2593     put { project(p) then translate([0,0,2*e]) } {door}\r
2594   }\r
2595 @end verbatim\r
2597 @center @image{ex180}\r
2599 If you have studied and understand all this, you are well on the way\r
2600 to success with @code{sketch}.  Not shown are the 20 or so iterations\r
2601 that were required to find a reasonable viewing angle and house\r
2602 position, etc.  Nonetheless, this drawing was completed in about an\r
2603 hour.  While a GUI tool may have been a little faster, it is unlikely\r
2604 that a new drawing, itself a perspective projection of the scene,\r
2605 could be generated with two more minutes' work!  Just change the view\r
2606 transform to\r
2607 @verbatim\r
2608   put { view((eye), (look_at)) then perspective(9) } { ...\r
2609 @end verbatim\r
2610 @noindent \r
2611 and produce this.\r
2613 @center @image{ex190}\r
2615 @node  A technical drawing, A hierarchical model, Overview, Building a drawing\r
2616 @comment  node-name,  next,  previous,  up\r
2617 @section A technical drawing\r
2618 Let's look at a drawing that represents the kind of problem\r
2619 @code{sketch} was meant to solve---a pair of textbook figures\r
2620 regarding a polygonal approximation of a truncated cone.  Here are the\r
2621 pictures we will produce.\r
2623 @center @image{ex250}@ @ @ @ @ @image{ex260}\r
2625 The cone shape is just a swept line with no closure tag and culling\r
2626 turned off.  Begin by setting up some useful constants.\r
2627 @sxindex def\r
2628 @sxindex rotate\r
2629 @verbatim\r
2630   def O (0,0,0) def I [1,0,0] def J [0,1,0] def K [0,0,1]\r
2631   def p0 (1,2) def p1 (1.5,0) def N 8\r
2632   def seg_rot rotate(360 / N, [J])\r
2633 @end verbatim\r
2634 @noindent\r
2635 The points @code{p0} and @code{p1} are the end points of the line to\r
2636 be swept.  The definition @code{seg_rot} is the sweep transformation.\r
2637 With these, the cone itself is simple.\r
2638 @sxindex sweep\r
2639 @opindex cull\r
2640 @sxindex line\r
2641 @cindex swept line\r
2642 @cindex line sweep\r
2643 @verbatim\r
2644   sweep[cull=false] { N, [[seg_rot]] } line(p0)(p1)\r
2645 @end verbatim\r
2647 The axes are next and include an interesing trick that shows the\r
2648 hidden parts as dotted lines.  The secret is draw the axes\r
2649 twice---solid lines with the normal\r
2650 @cindex hidden surface algorithm\r
2651 hidden surface algorithm in effect, and then dotted with the\r
2652 option\r
2653 @opindex lay\r
2654 @code{lay=over} so that no polygons can hide them.\r
2655 @sxindex def\r
2656 @sxindex line\r
2657 @opindex arrows\r
2658 @opindex linewidth\r
2659 @opindex lay\r
2660 @opindex linestyle\r
2661 @sxindex special\r
2662 @verbatim\r
2663   def ax (dx,0,0) % tips of the axes\r
2664   def ay (0,dy,0)\r
2665   def az (0,0,dz)\r
2666   line[arrows=<->,linewidth=.4pt](ax)(O)(ay)\r
2667   line[arrows=->,linewidth=.4pt](O)(az)\r
2668   % repeat dotted as an overlay to hint at the hidden lines\r
2669   line[lay=over,linestyle=dotted,linewidth=.4pt](ax)(O)(ay)\r
2670   line[lay=over,linestyle=dotted,linewidth=.4pt](O)(az)\r
2671   special|\footnotesize\r
2672           \uput[d]#1{$x$}\uput[u]#2{$y$}\uput[l]#3{$z$}|\r
2673     (ax)(ay)(az)\r
2674 @end verbatim\r
2675 @noindent\r
2676 The labels are applied with @code{PSTricks} special objects \r
2677 @cindex special objects\r
2678 as usual.\r
2680 For the height dimension mark, the power of affine \r
2681 @cindex affine arithmetic\r
2682 arithetic is very helpful.\r
2683 @sxindex def\r
2684 @sxindex unit\r
2685 @sxindex scale\r
2686 @sxindex line\r
2687 @sxindex special\r
2688 @verbatim\r
2689   def hdim_ref unit((p1) - (O)) then [[seg_rot]]^2\r
2690   def c0 (p0) then scale([J])\r
2691   def h00 (c0) + 1.1 * [hdim_ref]\r
2692   def h01 (c0) + 1.9 * [hdim_ref]\r
2693   def h02 (c0) + 1.8 * [hdim_ref]\r
2694   line(h00)(h01)\r
2695   def h10 (O) + 1.6 * [hdim_ref]\r
2696   def h11 (O) + 1.9 * [hdim_ref]\r
2697   def h12 (O) + 1.8 * [hdim_ref]\r
2698   line(h10)(h11)\r
2699   line[arrows=<->](h02)(h12)\r
2700   def hm2 ((h02) - (O) + (h12) - (O)) / 2 + (O)\r
2701   special|\footnotesize\rput*#1{$h$}|(hm2)\r
2702 @end verbatim\r
2703 The general idea employed here is to compute a unit ``reference\r
2704 vector'' parallel to the @math{xz}-plane in the desired direction of\r
2705 the dimension from the origin.  The transformation\r
2706 @code{[[seg_rot]]^2} rotates two segments about the @math{y}-axis.\r
2707 When applied to @code{(p1) - (O)}, the resulting vector points to the\r
2708 right as shown.  In this manner, we can pick any vertex as the\r
2709 location of the height dimension lines by varying the exponent of\r
2710 @code{[[seg_rot]]}.  This is only one of many possible strategies.\r
2712 The computation of @code{hm2} is a useful idiom for finding the\r
2713 @cindex centroid\r
2714 centroid of a set of points.\r
2716 The two radius marks are done similarly, so we present the code\r
2717 without comment.\r
2718 @sxindex def\r
2719 @sxindex line\r
2720 @sxindex special\r
2721 @sxindex scale\r
2722 @opindex arrows\r
2723 @verbatim\r
2724   % radius measurement marks\r
2725   def gap [0,.2,0]  % used to create small vertical gaps\r
2727   % first r1\r
2728   def up1 [0,3.1,0] % tick rises above dimension a little\r
2729   def r1 ((p1) then [[seg_rot]]^-2) + [up1]\r
2730   def r1c (r1) then scale([J])\r
2731   def r1t (r1) + [gap]\r
2732   def r1b ((r1t) then scale([1,0,1])) + [gap]\r
2733   line[arrows=<->](r1c)(r1)  % dimension line\r
2734   line(r1b)(r1t)             % tick\r
2735   def r1m ((r1) - (O) + (r1c) - (O)) / 2 + (O) % label position\r
2736   special |\footnotesize\rput*#1{$r_1$}|(r1m)  % label\r
2738   % same drill for r0, but must project down first\r
2739   def up0 [0,2.7,0]\r
2740   def r0 ((p0) then scale([1,0,1]) then [[seg_rot]]^-2) + [up0]\r
2741   def r0c (r0) then scale([J])\r
2742   def r0t (r0) + [gap]\r
2743   def r0b ((p0) then [[seg_rot]]^-2) + [gap]\r
2744   line[arrows=<->](r0c)(r0)\r
2745   line(r0b)(r0t)\r
2746   def r0m ((r0) - (O) + (r0c) - (O)) / 2 + (O)\r
2747   special |\footnotesize\rput*#1{$r_0$}|(r0m)\r
2748 @end verbatim\r
2750 The second drawing uses the same techniques.  Only the method for\r
2751 drawing the elliptical arc is new.  Here is the code.\r
2752 @sxindex def\r
2753 @sxindex special\r
2754 @opindex lay\r
2755 @verbatim\r
2756   def mid ((p00)-(O)+(p10)-(O)+(p11)-(O)+(p01)-(O))/4+(O)\r
2757   special|\rput#1{\pscustom{\r
2758     \scale{1 1.3}\r
2759     \psarc[arrowlength=.5]{->}{.25}{-60}{240}}}|\r
2760     [lay=over](mid)\r
2761 @end verbatim\r
2762 @noindent\r
2763 We could have swept a point to make the arc with @code{sketch}, but\r
2764 using a @code{PSTricks} custom graphic was simpler.  Again we computed\r
2765 the \r
2766 @cindex centroid\r
2767 centroid of the quadrilateral by averaging points.  Note that scaling\r
2768 in Postscript distorts the arrowhead, but in this case the distortion\r
2769 actually looks better in the projection of the slanted face.  A\r
2770 @code{sketch} arrowhead would not have been distorted.\r
2772 The complete code for this example, which draws either figure\r
2773 depending on the definition of the tag @code{<labeled>}, is included\r
2774 in the @code{sketch} distribution in the file @file{truncatedcone.sk}.\r
2776 @node A hierarchical model, Caveats, A technical drawing, Building a drawing\r
2777 @comment  node-name,  next,  previous,  up\r
2778 @section A hierarchical model\r
2779 @cindex hierarchical model\r
2780 While @code{sketch} was never meant to be a geometric modeling\r
2781 language, it comes fairly close.  The following example puts all we\r
2782 have seen to work in a very simple model of the human hand.  Start by\r
2783 sweeping a line to make a truncated cone, which will be copied over\r
2784 and over again to make the segments of fingers.\r
2785 @sxindex def\r
2786 @sxindex sweep\r
2787 @sxindex rotate\r
2788 @sxindex line\r
2789 @verbatim\r
2790   def O (0,0,0) % origin\r
2791   def I [1,0,0] def J [0,1,0] def K [0,0,1] % canonical unit vectors\r
2792   def segment {\r
2793     def n_faces 8\r
2794     sweep { n_faces<>, rotate(360 / n_faces, [J]) } \r
2795       line(proximal_rad, 0)(distal_rad, distal_len)\r
2796   }\r
2797 @end verbatim\r
2798 @noindent\r
2799 In hand anatomy, @emph{distal} is ``at the tip'' and @emph{proximal}\r
2800 is ``in the area of the palm.''  We have omitted all the scalar\r
2801 constants.  You can find them in @file{hand.sk}, which is provided\r
2802 in the @code{sketch} distribution. \r
2804 We also need a prototypical sphere to use for the joints themselves.\r
2805 @sxindex def\r
2806 @sxindex sweep\r
2807 @sxindex rotate\r
2808 @verbatim\r
2809   def joint_sphere {\r
2810     def n_joint_faces 8\r
2811     sweep [fillcolor=red] { n_joint_faces, rotate(360 / n_joint_faces, [J]) }\r
2812       sweep { n_joint_faces, rotate(180 / n_joint_faces) } \r
2813         (0, -joint_rad)\r
2814   }\r
2815 @end verbatim\r
2817 We'll now design the index finger (number@w{ }1 in our notational\r
2818 convention; finger@w{ }0 is the thumb).  The distal rotation for the\r
2819 finger applies only to the tip, so we define the following.\r
2820 @sxindex def\r
2821 @sxindex put\r
2822 @sxindex translate\r
2823 @sxindex rotate\r
2824 @sxindex scale\r
2825 @verbatim\r
2826   def distal_1 {\r
2827     put { translate(joint_gap * joint_rad * [J]) \r
2828           then rotate(distal_1_rot, [I]) \r
2829           then translate((distal_len + joint_gap * joint_rad) * [J]) }\r
2830       {segment}\r
2831     put { rotate(distal_1_rot / 2, [I])\r
2832           then translate((distal_len + joint_gap * joint_rad) * [J]) } \r
2833       {joint_sphere}\r
2834     put { scale( [J] + proximal_distal_ratio * ([I]+[K]) ) }\r
2835       {segment}\r
2836   }  \r
2837 @end verbatim\r
2838 @noindent\r
2839 The identifiers here are for size and location constants. The\r
2840 exception is @code{distal_rot_1}.  This rotation parameter models the\r
2841 flexing of the finger tip.  The first @code{put} makes a copy of the\r
2842 finger segment that is translated upward \r
2843 @cindex translation transform\r
2844 @cindex transform, translation\r
2845 just far enough to make room\r
2846 for the spherical joint.  Then it applies the distal rotation.\r
2847 @cindex rotation transform\r
2848 @cindex transform, rotation\r
2849 Finally it translates the whole assembly upward again to make room for\r
2850 the middle phlanges (the next bone toward the palm).  The second\r
2851 @code{put} positions the sphere.  There is a rotation to place the\r
2852 grid on the sphere surface at an nice angle, then a translation to the\r
2853 base of the distal phlanges, which is also center of its rotation.\r
2854 Finally, the last @code{put} positions the middle segment itself.\r
2856 The middle joint is the next one down, with rotation angle\r
2857 @code{middle_rot_1}.  When this angle changes, we need all the objects\r
2858 in @code{distal_1} to rotate as a unit.  \r
2859 @cindex rotation transform\r
2860 @cindex transform, rotation\r
2861 This is the reasoning behind\r
2862 the next definition.\r
2863 @verbatim\r
2864   def finger_1 {\r
2865     put { translate(joint_gap * joint_rad * [J])\r
2866           then rotate(middle_1_rot, [I])\r
2867           then translate((middle_ratio * distal_len + \r
2868                           joint_gap * joint_rad) * [J]) }\r
2869       {distal_1}\r
2870     put { scale(proximal_distal_ratio)\r
2871           then rotate(middle_1_rot / 2, [I])\r
2872           then translate((middle_ratio * distal_len + \r
2873                           joint_gap * joint_rad) * [J]) } \r
2874       {joint_sphere}\r
2875     put { scale( middle_ratio * [J] + \r
2876                  proximal_distal_ratio^2 * ([I]+[K]) ) }\r
2877       {segment}\r
2878   }\r
2879 @end verbatim\r
2880 @noindent\r
2881 This looks very similar to the previous definition, and it is.  The\r
2882 important difference is that rather than positioning and rotating a\r
2883 single segment, we position and rotate the entire ``assembly'' defined\r
2884 as @code{distal_1}.  \r
2885 @cindex rotation transform\r
2886 @cindex transform, rotation\r
2887 The rest is just arithmetic to compute sizes and\r
2888 positions that look nice.  The last @code{put} places an appropriately\r
2889 shaped segment that is the @emph{proximal phlanges}, the bone that\r
2890 joins the palm of the hand.  This completes the finger itself.\r
2892 All the other fingers are described identically to this one.  We\r
2893 account for the fact that real fingers are different sizes in the next\r
2894 step, which is to build the entire hand.\r
2896 The @code{hand} definition that follows includes a section for each\r
2897 finger.  We'll continue with finger@w{ }1 and omit all the others.\r
2898 (Of note is that the thumb needs slightly special treatment---an extra\r
2899 rotation to account for its opposing angle. This is clear in the full\r
2900 source code.) Not surprisingly, the @code{hand} definition looks very\r
2901 much like the previous two.  It should be no surprise that when the\r
2902 rotation parameter @code{meta_1_rot} changes, the entire finger\r
2903 rotates!\r
2904 @cindex rotation transform\r
2905 @cindex transform, rotation\r
2906 There is an additional rotation that allows the fingers to spread\r
2907 laterally.  We say these joints of the proximal phlanges have two\r
2908 @emph{degrees of freedom}. The joints higher on the finger have only\r
2909 one. Finally, each finger is scaled by a factor to lend it proportion.\r
2910 @verbatim\r
2911   def hand {\r
2912     % finger 1 [all other fingers omitted]\r
2913     def scale_1 .85\r
2914     put { scale(scale_1) \r
2915           then translate((joint_gap * joint_rad) * [J])\r
2916           then rotate(meta_1_rot, [I])\r
2917           then rotate(-spread_rot, [K])\r
2918           then translate((proximal_1_loc) - (O)) } \r
2919       {finger_1}\r
2920     put { scale(scale_1 * proximal_distal_ratio^2)\r
2921           then rotate(meta_1_rot / 2, [I])\r
2922           then rotate(-spread_rot, [K])\r
2923           then translate((proximal_1_loc) - (O)) } \r
2924       {joint_sphere}\r
2926     % palm\r
2927     sweep { 1, rotate(6, (0,15,0), [I]) }\r
2928       put { rotate(-3, (0,15,0), [I]) } {\r
2929         polygon(proximal_1_loc)(proximal_2_loc)\r
2930                (proximal_3_loc)(proximal_4_loc)\r
2931                (h5)(h6)(h6a)(h9)(h10)\r
2932         polygon(h6a)(h7)(h8)(h9)\r
2933    }  }\r
2934 @end verbatim\r
2935 @noindent\r
2936 The last section of the definition creates the polytope for the palm\r
2937 of the hand by @code{sweep}ing \r
2938 @cindex swept polygon\r
2939 @cindex polygon sweep\r
2940 a 10-sided polygon through a very short\r
2941 arc (9@w{ }degrees).  This provides a wedge-shaped profile when viewed\r
2942 from the side. The thick end of the wedge is the wrist.  Because the\r
2943 polygon is concave, it is split into into two convex shapes with nine\r
2944 and four vertices.\r
2946 We can now have fun positioning the hand by adjusting the various\r
2947 rotation angles.  The complete source includes definitions with\r
2948 alternatives that include the following views and more.\r
2950 @center @image{ex210}@image{ex220}@image{ex230}@image{ex240}\r
2952 @node Caveats,  , A hierarchical model, Building a drawing\r
2953 @comment  node-name,  next,  previous,  up\r
2954 @section Caveats\r
2955 @code{Sketch} is a fairly powerful tool for drawing, but, just as with\r
2956 @TeX{}, the power to create beautiful results comes along with the\r
2957 power to make mistakes.  The following are some points where care is\r
2958 necessary and where the current version of @code{sketch} is limited or\r
2959 has known bugs.\r
2961 @menu\r
2962 * Limits on error detection::   What sketch doesn't do.\r
2963 * Clipping::                    No clipping at present.\r
2964 * Hidden surface removal::      Imperfections to fix.\r
2965 @end menu\r
2967 @node Limits on error detection, Clipping, Caveats, Caveats\r
2968 @comment  node-name,  next,  previous,  up\r
2969 @subsection Limits on @code{sketch} error detection\r
2971 @code{Sketch} catches many kinds of errors, but not all. For example,\r
2972 options that sketch does not recognize, even incorrect ones, are\r
2973 quietly copied to @code{PSTricks} commands in the output.  It is also\r
2974 unfortunately easy to produce @code{sketch} inputs that lead to no\r
2975 picture at all (improper vertex ordering causes everything to be\r
2976 culled), to pictures that are too big or too small for @code{PSTricks}\r
2977 to draw (due to limits of @TeX{} math), and pictures that look nothing\r
2978 like what was intended.  A picture with one of these problems can be\r
2979 difficult to ``debug.''  We offer the following suggestions.\r
2980 @itemize\r
2981 @item \r
2982 Follow the suggested incremental development method described in\r
2983 @ref{Overview}. \r
2984 @item\r
2985 Always maintain one or two back-versions of a drawing so that it is\r
2986 easy to fall back to a known-good increment.\r
2987 @item\r
2988 When using @code{perspective}, ensure all finally transformed objects\r
2989 satisfy @math{z<0} and, in fact, do not come very close to the origin\r
2990 at all.\r
2991 @item\r
2992 Temporarily use @code{cull=false} to see where vertex ordering\r
2993 problems lie.\r
2994 @item\r
2995 Use temporary changes of color of one or more objects to ensure that\r
2996 your understanding of the scene geometry is correct.\r
2997 @item\r
2998 If @code{PSTricks} complains about something, inspect the output\r
2999 directly for clues.\r
3000 @end itemize\r
3002 @node Clipping, Hidden surface removal, Limits on error detection, Caveats\r
3003 @comment  node-name,  next,  previous,  up\r
3004 @subsection Clipping\r
3005 The current version of @code{sketch} has no clipping \r
3006 @cindex clipping\r
3007 operations.  The entire scene is always drawn.  This means that when a\r
3008 perspective transform is employed, it is the user's responsibility to\r
3009 make sure the entire scene remains in front of the viewer, the region\r
3010 @math{z<0}.\r
3012 @node Hidden surface removal,  , Clipping, Caveats\r
3013 @comment  node-name,  next,  previous,  up\r
3014 @subsection Hidden surface removal and polygon splitting\r
3015 @code{Sketch} uses the @dfn{depth sort algorithm} \r
3016 @cindex depth sort\r
3017 @cindex hidden surface algorithm\r
3018 for hidden surface removal.  This is a very old technique due to\r
3019 Newell.@footnote{Newell, M.E., R.G.@: Newell, and T.L.@: Sancha, A\r
3020 solution to the hidden surface problem. @i{Proceedings of the ACM\r
3021 annual conference - Volume 1}, page 443--450, ACM Press, 1972.}  It is\r
3022 generally regarded as too slow for real time graphics, but it is\r
3023 ideal for our purpose where speed is not very important.@footnote{We\r
3024 have run @code{sketch} on the famous Stanford Bunny, which consists\r
3025 of nearly @math{70,000} triangles.  Run time was about 6 seconds.\r
3026 Most of this was spent writing the output file rather than in the\r
3027 hidden surface algorithm.  @LaTeX{} took much longer to process the\r
3028 resulting @code{PSTricks} code.  The obvious conclusion is that the\r
3029 speed of the depth sort algorithm is not a worry.}\r
3031 The depth sort algorithm merely sorts objects on a key of increasing\r
3032 @math{z}-coordinate, equivalent to decreasing depth.  Objects are then\r
3033 drawn in the sorted sequence so that those at the rear of the scene\r
3034 are overwritten by those closer to the viewer. Since this is also\r
3035 how oil painters practice their art, depth sort is sometimes called\r
3036 ``the painter's algorithm.''\r
3038 In some cases it is impossible to strictly order polygons according to\r
3039 depth.  Moreover, even if a correct depth ordering exists, the\r
3040 computation needed to find it may be too complex and slow.  In these\r
3041 cases, @code{sketch} splits \r
3042 @cindex splitting, line and surface\r
3043 one or more polygons into pieces.  The\r
3044 expectation is that the new, smaller polygons will be simpler to\r
3045 order.  @code{Sketch} uses a @acronym{BSP,binary space partition} \r
3046 @cindex binary space partition\r
3047 @cindex BSP, binary space partition\r
3048 to handle the splitting operation.\r
3050 @menu\r
3051 * Statistics::                  Performance numbers on depth sort.\r
3052 * Bugs and anomalies::          Imperfections in this implementation.\r
3053 @end menu\r
3055 @node Statistics, Bugs and anomalies, Hidden surface removal, Hidden surface removal\r
3056 @comment  node-name,  next,  previous,  up\r
3057 @subsubsection Statistics\r
3058 For the curious, @code{sketch} writes one line of depth sort\r
3059 statistics.  Here is an example for a large collection of triangles.\r
3060 @verbatim\r
3061   remark, node=34824 probe=581.9 swap=5 split=2 (in=4 out=6) ols=24851/0\r
3062 @end verbatim\r
3063 @noindent\r
3064 It means that @math{34,824} objects were depth sorted after culling.\r
3065 For each, an average of @math{581.9} others had to be checked to\r
3066 ensure that the initial, approximate ordering was correct.  Among all\r
3067 these checks, only @math{5} resulted in swaps to reorder the initial\r
3068 sort.  In two cases, a correct ordering could not be determined, so\r
3069 binary space partitions\r
3070 @cindex binary space partition\r
3071 were constructed for splitting.  A total of @math{4}\r
3072 objects (triangles in this case) were inserted in the partitions, and\r
3073 @math{6} polygons were produced.  Finally, @math{24,851} ``last\r
3074 resort'' polygon overlap checks were performed after simpler, faster\r
3075 checks failed to yield conclusive results.  The final @math{/0} is for\r
3076 line-polygon overlap checks.  For comparison, the statistics for the\r
3077 last figure in @ref{Overview} follow.\r
3078 @verbatim\r
3079   remark, node=27 probe=14.6 swap=36 split=15 (in=30 out=45) ols=0/69\r
3080 @end verbatim\r
3081 @noindent\r
3082 Note that there was proportionally much more swapping and splitting\r
3083 activity in this highly connected scene.\r
3085 @node Bugs and anomalies,  , Statistics, Hidden surface removal\r
3086 @comment  node-name,  next,  previous,  up\r
3087 @subsubsection Bugs and anomalies\r
3088 Polygon and line splitting can both cause anomalies in the output.  \r
3089 @code{PSTricks} dash patterns, specified with @code{linestyle=dashed},\r
3090 @opindex linestyle\r
3091 can be disrupted by splitting.  This occurs when the depth sort\r
3092 @cindex depth sort\r
3093 gives up too early and splits a line where it is not really\r
3094 necessary. \r
3095 A workaround is to use gray or finely dotted\r
3096 lines instead.  If your drawing is small, you can also edit the\r
3097 @code{sketch} output by hand to merge the pieces of the offending\r
3098 line.\r
3100 Another anomaly is tiny (or in degenerate cases not-so-tiny) notches\r
3101 in the lines that border split polygons.  These derive from the way\r
3102 each polygon is painted: first, all pixels within the boundary are\r
3103 @dfn{filled} with color (perhaps white), then the same boundary is\r
3104 @dfn{stroked} (a Postscript term) with a line.  The result is that\r
3105 half the line lies inside the boundary and half outside, while the\r
3106 Painter's algorithm assumes the polygon lies entirely within its\r
3107 boundary.  The notches are due to one polygon fill operation\r
3108 overwriting the already-drawn inside of the border of another\r
3109 polygon.@footnote{I know how to fix this problem, but I don't like my\r
3110 solution, and I'm interested in yours.}  One workaround is to make\r
3111 border lines very thin.  In fact @code{linewidth=0pt} is guaranteed to\r
3112 eliminate this problem, though this results in the thinnest line your\r
3113 output device can draw, which is usually too thin.  You might get\r
3114 lucky by merely reordering things in the input file, which is likely\r
3115 to move the splits to different places.  The only sure-fire solution\r
3116 is pretty terrible: custom fit @code{special} overlay lines (with\r
3117 @code{\psline}) to cover the notches.\r
3119 Polygon splitting also breaks @code{PSTricks} hatch patterns.  The\r
3120 only known workaround is to substitute a solid fill for the hatch.\r
3122 @node Command line, Installing sketch, Building a drawing, Top\r
3123 @comment  node-name,  next,  previous,  up\r
3124 @chapter Command line\r
3125 @cindex command line, @code{sketch}\r
3126 @strong{Synopsis:}\r
3127 @example\r
3128 sketch [-h][-V x.y][-v][-b][-d][t doctmp][-T[u|e][p[P|T][L|C]]][-o output.tex]\r
3129   [-D @var{tag} @dots{}] input1.sk [-U @var{tag} @dots{}] input2.sk @dots{}\r
3130 @end example\r
3132 @noindent\r
3133 @strong{Description}\r
3134 Processes the @code{sketch} input files in order to produce\r
3135 @code{PSTricks} output code suitable for inclusion in a @TeX{} or\r
3136 @LaTeX{} document.\r
3138 @noindent\r
3139 @strong{Options:}\r
3140 @cindex options, command line\r
3141 @cindex command line options\r
3142 @table @code\r
3143 @item -h\r
3144 Print a short catalog of options.\r
3145 @item -V\r
3146 Set the @code{PSTricks} version assumed for output purposes to\r
3147 @code{x.y}, for example 1.19.  Usually needed only if your\r
3148 @code{PSTricks} is old compared to your @code{sketch}.  Use\r
3149 @code{-v} to see what @code{sketch} assumes by default.\r
3150 @item -v\r
3151 Print version information to standard output, including the version\r
3152 of @code{PSTricks} assumed for output (can be changed with @code{-V} above).\r
3153 @item -b\r
3154 Use a BSP \r
3155 @cindex binary space partition\r
3156 @cindex BSP, binary space partition\r
3157 (@xref{Hidden surface removal}.) for\r
3158 @emph{all} hidden surface removal rather than the default, which is\r
3159 the depth sort algorithm with BSPs used only for cycle resolution.\r
3160 This may produce correct output in certain degenerate cases where the\r
3161 depth sort cannot, but it also leads to many gratuitous splits, hence\r
3162 more anomalies @ref{Bugs and anomalies} and big output files.\r
3163 @item -d\r
3164 Run @code{sketch}'s parser in debugging mode.  This is primarily for\r
3165 development.\r
3166 @item -t\r
3167 Use contents of file @file{doctmp} as a document template \r
3168 @cindex document template\r
3169 @cindex template, document\r
3170 in which to enclose @code{PSTricks} output code.  The code is inserted\r
3171 in place of the first instance of the escape string\r
3172 @verb{|%%SKETCH_OUTPUT%%|}.  \r
3173 @item -T\r
3174 Causes @code{PSTricks} output to be enclosed in default US document\r
3175 template text.  Option @option{-Tu} is a synonym.  Option @option{-Te}\r
3176 causes the Euro standard document template to be used.  A @option{p}\r
3177 appended to any of these options causes the respective default\r
3178 @code{PSTricks} document template to be printed to standard output. An\r
3179 appended @option{P} is a synonym.  An appended @option{T} causes the\r
3180 the @code{TikZ/PGF} template to be printed.  An appended @option{L}\r
3181 prints the @LaTeX{} version of the document template, a synonym for\r
3182 the default.  A @option{C} prints the @code{ConTeXt} template.\r
3183 @item -o\r
3184 Use @file{output.tex} as the output file.  The default is standard output.\r
3185 @item -D\r
3186 Define a tag \r
3187 @cindex tag definition\r
3188 @cindex definition, tag\r
3189 for purposes of selecting definition alternatives.\r
3190 @xref{Definitions}.  The definition applies for all input files that\r
3191 follow unless the tag is undefined with @option{-U}.\r
3192 @item input@math{i}.sk\r
3193 Input files, read in the sequence they are given.\r
3194 @item -U\r
3195 Un-define a tag for purposes of selecting definition alternatives.\r
3196 @end table\r
3198 @node Installing sketch, Index of syntax, Command line, Top\r
3199 @comment  node-name,  next,  previous,  up\r
3200 @chapter Building and installing @code{sketch}\r
3201 @code{Sketch} is so small that compiling by brute force is probably\r
3202 best.  The following command ought to do the trick on any\r
3203 systems where @code{gcc} is installed.  Make sure to first change\r
3204 current directories to the place where you have unpacked the sources.\r
3205 @example\r
3206 gcc *.c -o sketch.exe -lm\r
3207 @end example\r
3208 @noindent\r
3209 The @samp{.exe} at the end is necessary for Windows systems.  Drop it\r
3210 if your system is some version of Unix.  Other C compilers ought\r
3211 to work as just as well.  For example,\r
3212 @example\r
3213 cl *.c -o sketch.exe\r
3214 @end example\r
3215 @noindent\r
3216 is the correct command for many versions of MS Visual C.  In the\r
3217 latest versions, Microsoft has deprecated the @code{-o} option and, by\r
3218 default, does not define the @code{__STDC__} macro.  This causes\r
3219 problems with some versions of @code{flex}, @code{bison}, @code{lex},\r
3220 and @code{yacc}, which are used to create the @code{sketch} scanner\r
3221 and parser.  It's nearly always possible to find a set of options that\r
3222 compiles with no errors or warnings, and this means @code{sketch} is\r
3223 @emph{very} likely to work correctly.  For example, the Visual C++\r
3224 2005 Express Edition compiler (available free of charge from the\r
3225 Microsoft web site), @code{flex} version 2.5.4, and @code{bison}\r
3226 version 2.1 build error-free with\r
3227 @example\r
3228 cl -DYY_NEVER_INTERACTIVE=1 -Za -Ox -Fesketch.exe *.c\r
3229 @end example\r
3231 For purists, there is also a @code{makefile} compatible with GNU\r
3232 @code{make} and @code{gcc}. The command\r
3233 @example\r
3234 make\r
3235 @end example\r
3236 @noindent\r
3237 will build the executable, including the rebuilding of the scanner and\r
3238 parser with @code{flex} and @code{bison} if you have changed\r
3239 @file{sketch.l} or @code{sketch.y} respectively.  \r
3241 To build this document in all its myriad forms (assuming you have the\r
3242 necessary conversion programs on your system), use\r
3243 @example\r
3244 make docs\r
3245 @end example\r
3246 @noindent\r
3247 The possibilities are listed in this following table.\r
3248 @multitable {@code{manual/index.html}}{texi2dvi,dvips}{@b{Pictures}}{wide column that needs to be as big as it needs to be,}\r
3249 @headitem Format @tab Converter @tab Pictures @tab Description\r
3250 @item manual.info \r
3251   @tab makeinfo       @tab @file{.txt} @tab @acronym{GNU} Info.\r
3252 @item manual.dvi\r
3253   @tab texi2dvi       @tab @file{.eps} @tab @TeX{} typeset output.\r
3254 @item manual.ps   \r
3255   @tab texi2dvi,dvips @tab @file{.eps} @tab Postscript.\r
3256 @item manual.pdf\r
3257   @tab texi2dvi       @tab @file{.pdf} @tab Adobe PDF.\r
3258 @item manual.html \r
3259   @tab makeinfo       @tab @file{.png} @tab A single web page.\r
3260 @item manual/index.html\r
3261   @tab makeinfo       @tab @file{.png} @tab Linked web pages, one per node.\r
3262 @end multitable\r
3263 An additional open source program @code{epstool} is needed to refine the\r
3264 Encapsulated Postscript bounding boxes of @code{sketch}-generated\r
3265 figures.  \r
3267 @node Index of syntax, Index, Installing sketch, Top\r
3268 @comment  node-name,  next,  previous,  up\r
3269 @unnumbered Index of syntax\r
3271 @printindex sx\r
3273 @node Index,  , Index of syntax, Top\r
3274 @comment  node-name,  next,  previous,  up\r
3275 @unnumbered Index of concepts\r
3277 @printindex cp\r
3279 @bye\r