GAViewer Documentation
GAViewer Documentation
84
Daniel Fontijne University of Amsterdam March 19, 2010
Contents
1 Introduction 2 The user interface 2.1 The view window . . . . . . . . . . . . . 2.1.1 Viewpoint rotation . . . . . . . . 2.1.2 Viewpoint translation . . . . . . 2.1.3 Object selection . . . . . . . . . . 2.1.4 Object selection . . . . . . . . . . 2.1.5 Object translation / modication 2.1.6 View window control summary 2.2 The console . . . . . . . . . . . . . . . . 2.3 Object controls window . . . . . . . . . 2.4 Scalar controls window . . . . . . . . . . 2.5 The menu bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 9 9 9 9 10 10 10 11 11 11 12 12 15 15 16 16 17 18 18 18 18 19 19 19 19 19 20 20 20 20 21 21 21 21 21
3 .geo and .gpl les 3.1 title . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 fgcolor, bgcolor, olcolor, cvcolor . . . . . . . . . . . . . . 3.3 e3ga, ca3d, p3ga, ca4d, c3ga, ca5d . . . . . . . . . . . . . 3.4 label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5 fontsize . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6 tsmode . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.7 tsfont . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.8 tsreset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.9 tsinterpret . . . . . . . . . . . . . . . . . . . . . . . . . . 3.10 factor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.11 eyepos, campos . . . . . . . . . . . . . . . . . . . . . . . 3.12 eyetrl, camtrl . . . . . . . . . . . . . . . . . . . . . . . . . 3.13 eyeori, camori . . . . . . . . . . . . . . . . . . . . . . . . 3.14 eyerot, camrot . . . . . . . . . . . . . . . . . . . . . . . . 3.15 hide, show . . . . . . . . . . . . . . . . . . . . . . . . . . 3.16 remove . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.17 fade, fade and remove, fade and hide, show and fade 3.18 sleep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.19 wait . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.20 exit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.21 clearconsole . . . . . . . . . . . . . . . . . . . . . . . . . 3.22 console . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
4 3.23 3.24 3.25 3.26 3.27 3.28 3.29 3.30 3.31 3.32 3.33 resize . . . . . . . . . . . . . . . . . . viewwindowsize . . . . . . . . . . . consoleheight . . . . . . . . . . . . . consolefontsize . . . . . . . . . . . . fullscreen . . . . . . . . . . . . . . . . bookmark . . . . . . . . . . . . . . . open, switchto, import . . . . . . . . clip . . . . . . . . . . . . . . . . . . . delete . . . . . . . . . . . . . . . . . . polygon, simplex . . . . . . . . . . . mesh . . . . . . . . . . . . . . . . . . 3.33.1 meshvertex . . . . . . . . . . 3.33.2 meshnormal . . . . . . . . . . 3.33.3 meshface . . . . . . . . . . . . 3.33.4 Full usage example for mesh 3.34 play (.gpl les only) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CONTENTS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 22 22 22 22 22 23 23 23 23 24 24 25 25 25 25 27 27 28 28 29 30 31 31 31 31 32 32 33 33 34 37 38 38 38 39 40 41 42 42 43 43 43 44 44 45 46 47 47
4 The Programming Language and the Console 4.1 Comma, semicolon and space . . . . . . . . . . . . . . . 4.2 ans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Operators, assignment, precendence . . . . . . . . . . . 4.4 Variables, types and casting . . . . . . . . . . . . . . . . 4.5 Builtin Constants . . . . . . . . . . . . . . . . . . . . . . 4.5.1 Renaming builtin constants . . . . . . . . . . . . 4.6 Adding your own constants . . . . . . . . . . . . . . . . 4.7 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.8 Calling functions . . . . . . . . . . . . . . . . . . . . . . 4.9 Built-in functions . . . . . . . . . . . . . . . . . . . . . . 4.9.1 Products . . . . . . . . . . . . . . . . . . . . . . . 4.9.2 Basic GA functions . . . . . . . . . . . . . . . . . 4.9.3 Boolean . . . . . . . . . . . . . . . . . . . . . . . 4.9.4 Drawing . . . . . . . . . . . . . . . . . . . . . . . 4.9.5 Controls . . . . . . . . . . . . . . . . . . . . . . . 4.9.6 Goniometric functions, sqrt, abs, log, exp, pow. . 4.9.7 Projective model functions . . . . . . . . . . . . 4.9.8 Conformal model functions . . . . . . . . . . . . 4.9.9 System functions . . . . . . . . . . . . . . . . . . 4.9.10 Networking . . . . . . . . . . . . . . . . . . . . . 4.10 Dynamic statements . . . . . . . . . . . . . . . . . . . . 4.10.1 Named Dynamic Statements . . . . . . . . . . . 4.10.2 Animations . . . . . . . . . . . . . . . . . . . . . 4.11 Control constructs . . . . . . . . . . . . . . . . . . . . . . 4.11.1 if else . . . . . . . . . . . . . . . . . . . . . . . . . 4.11.2 for . . . . . . . . . . . . . . . . . . . . . . . . . . 4.11.3 while . . . . . . . . . . . . . . . . . . . . . . . . . 4.11.4 switch . . . . . . . . . . . . . . . . . . . . . . . . 4.12 Writing functions and batches . . . . . . . . . . . . . . . 4.12.1 Batches . . . . . . . . . . . . . . . . . . . . . . . . 4.13 Autocolor. . . . . . . . . . . . . . . . . . . . . . . . . . . 4.13.1 Writing your own autocolor() function. . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CONTENTS
5 Typesetting labels. 5.1 txt and eqn modes. . . . . . . . . . . 5.1.1 txt mode details: . . . . . . . 5.1.2 eqn mode details: . . . . . . . 5.2 Fonts . . . . . . . . . . . . . . . . . . 5.3 Scaling of fonts . . . . . . . . . . . . 5.4 Forced whitespace, forced newlines 5.5 Alignment . . . . . . . . . . . . . . . 5.6 Sub- and superscript . . . . . . . . . 5.7 Parentheses . . . . . . . . . . . . . . 5.8 Tabulars . . . . . . . . . . . . . . . . 5.9 (Square) roots . . . . . . . . . . . . . 5.10 Fractions . . . . . . . . . . . . . . . . 5.11 Hats . . . . . . . . . . . . . . . . . . . 5.12 Colors . . . . . . . . . . . . . . . . . . 5.12.1 Custom colors . . . . . . . . . 5.13 Custom commands . . . . . . . . . . 5.14 Special symbols . . . . . . . . . . . .
5 49 50 50 51 51 53 53 54 54 55 56 57 57 58 58 59 59 60
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
CONTENTS
Chapter 1
Introduction
GAViewer is a multi-purpose program for performing geometric algebra computations and visualizing geometric algebra. Some possible uses are: Visualizing geometric algebra output from other programs. Interactively performing GA computations and visualizing the outcome. Presenting lectures, slideshows, doing tutorials, demonstrations, with (interactive) geometric algebra animations. Rendering (hi-res) images of GA objects for use in papers. Debugging other programs that use geometric algebra. We do not consider GAViewer appropriate for implementing serious applications. The internal (interpreted) programming language is too slow and limited for such purposes. GAViewer has outgrown its original purpose. We initially created GAViewer as a small program for visualizing GABLE/Matlab output because we werent satised with the Matlab graphics. Then we wanted to have a typesetting system for labels and support for slideshows. After some time the desire rose to add a console for interactive computations inside the viewer. After a console was added, we wanted to have functions and batches. Then dynamic statements were added. The latest additions include animations based an dynamic statements and scalar controls. In the following chapters, the various features of GAViewer are described in the following order: The user interface. Visualizing geometric algebra output from other programs using .geo les. The programming language. Typesetting labels. Using .geo les for slideshows and presentations.
CHAPTER 1. INTRODUCTION
Chapter 2
10
console
scalar controls
status bar
pause button
11
12
The checkboxes in the middle of the window can be used to make some visual distictions between objects. E.g., you could stipple imaginary objects, or turn off the shading to indicate atness. Certain objects can be drawn in multiple ways. For instance, select the blue bivector c. It has a draw method pull down menu from which you can choose various ways of drawing a bivector. At the very bottom of the object controls window is a text eld that shows: The interpretation of the object. Some numerical properties that are used to draw the object. The coordinates of the object (with limited precision). When the object controls window is hidden (menu ViewControls), you can still see a condensed version of this information in the status bar.
13
Select object: pops up a dialog that allows you to select any object. Hide: allows interaction with hidden objects. Unhide all: shows all hidden objects. Select hidden object: pops up a dialog that allows you to select a hidden object. Show hidden object: pops up a dialog that allows to toggle the hide/show state of hidden objects. Canvas: selects the color of the canvas (white, (light) grey or black). Console font size: selects the font size used on the console. Controls: toggles whether the object controls window is visible. Scalar Controls: toggles whether the scalar controls window is visible. Console: toggles whether the console is visible. Labels always on top: when on, labels will always be drawn on top of other objects. Fullscreen: toggles fullscreen/windowed user interface. In fullscreen mode, only the view window will be visible. Dynamic: contains dynamic statement and animation related items. View Dynamic statements: pops up a dialog where you can view/modify the current dynamic statements (see section 4.10). Start / resume animation: starts the atime variable (see section 4.10.2). Pause animation: pauses the atime variable. Stop animation: stops the atime variable. Playback speed: controls how fast animations play. Utils Search for next bookmark: goes to the next bookmark in the current .geo le, if any. Output current camera orientation (bivector): prints the current camera (viewpoint) orientation (camori) to the console, in bivector form. Output current camera orientation (rotor): same as above, but in rotor form. Output current camera translation: prints camera the translation (campos) to the console. Screenshot: pops up a dialog that allows you to renders a screenshot of the view window in arbitrary resolution. The le is stored in the .png le format. Help About: displays some info about GAViewer.
14
Chapter 3
3.1 title
Sets the title bar of the viewer window. Usage example: title "this is my demo" Sets the title bar of the window to GAViewer: this is my demo
15
16
3.4. LABEL
stipple: draws the object stippled.
17
orientation: draws something related to the orientation of the object, if possible. wireframe: draws the object in wireframe, if possible. magnitude: draws the magnitude (called weight in the GAViewer UI) of the object, if possible. shade: shades the object, if possible. versor: force versor interpretation of the multivector (e.g. to interpret a blade like a versor). blade: force blade interpretation of the multivector (e.g. to interpret 0 as a blade). grade0 ... grade8: force gradeX interpretation of multivector (e.g. to interpret 0 as a vector). dm1 ... dm7: use draw method 1 to 7, if supported by the object. Some object can be drawn in multiple ways. The default draw method is 1. Usage examples: c3ga "the arbitrary origin" [no] e3ga stippled_vector [e1+e2+e3] stipple e3ga z [4.0*e3e1] magnitude orientation dm2
3.4 label
Adds a label to the scene. The syntax is: label "name" "point" "text" flag1 flag2 ... flagn Draws a label (in current colors and font siz, and other typesetting parameters) at position point. point can be any previously specied multivector object which has a point interpretation, or a 3D multivector coordinates like [1.0*e1 + 2.0*e3]. The ags can be some of the following: 2d: label coordinates are in 2D window coordinates. 3d: label coordinates are in 3D world coordinates (default). cx: x-axis origin is in center of window (only in combination with 2D). cy: y-axis origin is in center of window (only in combination with 2D). px: positive x axis is towards the right (only in combination with 2D). nx: positive x axis is towards the left (only in combination with 2D). py: positive y axis is towards the bottom (only in combination with 2D).
18
Usage examples: label simple [1.0*e1] "a simple label" label attached_to_z z "this label follows z" dynamic label fullscreen_image [0] "c:\images\dog.png" 2d image fullscreen px py
3.5 fontsize
Sets the size of the font for the labels in pixels. Usage example: fontsize 30.0
3.6 tsmode
Sets the initial parsing mode of the typesetting system for labels. See chapter 5 for more details on typesetting. The mode can be any of: text, equation, verbatim, uppercase or lowercase. In fact, only the rst character of the string is used to determine the mode. Verbatim mode bypasses the whole typesetting system and displays labels using the regular ASCII characters directly. Usage example: tsmode equation
3.7 tsfont
Sets the initial font of the typesetting system for labels See chapter 5 for more details on typesetting. The font can be any of: regular, bold, italic, greek, uppercase or lowercase. In fact, only the rst character of the string is used to determine the font. Usage example: tsfont italic
3.8 tsreset
Resets the typesetting system to its initial mode. See chapter 5 for more details on typesetting. Usage example: tsreset
3.9. TSINTERPRET
19
3.9 tsinterpret
Sends text to the typesetting system. See chapter 5 for more details on typesetting. It is then parsed and interpreted, but not displayed. This is useful for adding custom commands and colors to the typesetting system. Usage example: tsinterpret "some string" Sends some string to the typesetting system. The typesettings system mode (as set with tsmode) is always forced to text during a tsinterpret!
3.10 factor
Species a custom factor for factorization. These are used during the interpretation of some multivectors. (currently only the e3ga bivector and trivector) Syntax: factor model idx [vectorCoordinates] model species for which model this factor is intended (c3ga, ca5d), (p3ga, ca4d), (e3ga, ca3d). idx species the index of the factor [1 ... d] (d = dimension of the model). Usage examples: factor e3ga 1 [1.0*e1] factor e3ga 2 [1.0*e2] factor e3ga 3 [1.0*e3]
20
3.16 remove
Removes the specied object. Usage example: remove x
3.17 fade, fade and remove, fade and hide, show and fade
The keywords allow you to fade in and out objects. Before the fade, the object can be shown (show and fade). After the fade is over, the object can be hidden (fade and hide) or removed (fade and remove). The syntax is: fade "object name" fade_duration fade_target fade_start The rst argument is the name of the object. The second argument is the duration of the fade in seconds. The third argument is the target alpha of the fade. The fourth, optional argument is the alpha at the start of the fade. Using fade will not actually modify the alpha of the any of the colors of the object, but rather multiplies those alpha values before they are sent to OpenGL. Usage examples: fade x 2.0 1.0 fade_and_remove y 1.0 0.0 1.0
3.18. SLEEP
21
3.18 sleep
Pauses the reading of the input le for a specied number of seconds. User interface will be fully functional during this sleep. Usage examples: sleep 10.0 Sleeps for 10.0 seconds. The maximum resolution for the sleep time is about 1/30th of a second.
3.19 wait
Pauses the reading of the input le until the waiting button is pressed. Usage example: wait
3.20 exit
Terminates the GAViewer immediately. Usage example: exit
3.21 clearconsole
Clears the console and removes scalar controls. Usage example: clearconsole
3.22 console
console allows you to execute a command in a .geo as if it was typed on the console. Usage example: console a = e1 e2
3.23 resize
Changes the size and optionally the position of the GAViewer window. Syntax: resize w h resize x y w h The rst format (with 2 arguments) changes the width and height of the window to w and h. The second format (with 4 arguments) also sets the position to x and y.
22
3.24 viewwindowsize
Changes the size of the view window. This will resize the main window and keep the height of the console and the width of the controls constant. Usage example: viewwindowsize 1024 768
3.25 consoleheight
Changes the height of the console. This will resize the console and the view window to achieve the desired height. Usage example: consoleheight 10 lines consoleheight 200 pixels You must specify eiter pixels or lines.
3.26 consolefontsize
Changes the size (in pixels) of the font used on the console. Usage example: consolefontsize 14
3.27 fullscreen
Sets the viewer to fullscreen mode or windowed mode. Only the view window is visible in full screen mode. Usage examples: fullscreen fullscreen on fullscreen off The rst two lines turn fullscreen mode on, the second line turns it off. In fullscreen mode, a small red W may be visible in the lower right corner when GAViewer would normally ash the waiting button.
3.28 bookmark
Indicates a bookmark in the le. When the user selects menu bar item utilssearch for next bookmark, input will be parsed quickly until such a bookmark is found. This is useful for skipping through a (slow) demo quickly. Usage example: bookmark "optional name that is not used yet"
23
3.30 clip
Sets the distance of the clipping planes to the origin. Currently not functional. Usage examples: clip 10.0
3.31 delete
Species whether to delete this .geo le or not when a new le is opened or GAViewer is terminated. This used to be useful when GAViewer was only used to visualize Matlab output, where .geo les were usually just a temporary communication channel. Syntax: delete [yes|no|ask] "question to ask" If the rst argument is ask the user is asked whether to delete or not. The question to ask can be supplied as the optional second argument. If you use by the name of the le. Usage examples: delete yes delete ask "delete %s?"
24
The rst argument is the name of the object. The second the number of vertices, followed by a name of a point for every vertex. After that, a number of ags can be added. The maximum number of vertices is 3 for a simplex. Polygons must be convex, or the resulting graphics will be unpredicatble. The p 1 ... p n are names of objects that have some kind of point interpretation. E.g., they can be vectors in the 3D model, or points in the conformal model. Possible ags: dynamic: the vertices of the polygon will lookup their position from the original point objects everytime the polygon gets redrawn. outline: draws an outline around the polygon. dm1 ... dm7: use draw method 1 to 7 (dm1: lled, dm2: line strip, dm3: line loop, dm4: 1D simplex is drawn as true vector). Usage example: polygon "P1 -> Q2" 2 P1 Q2 dm2
3.33 mesh
This keyword allows for the creation of a mesh object. A mesh consists of a number of vertices (with optional surface normals) and polygons. The vertices, surface normals and polygons are specied after the mesh. The syntax of mesh is: mesh "mesh name" normal_flag normal ag can be compute normals at: compute the surface normals such that the object will have a at shaded appearance. compute normals gouraud: compute the surface normals such that the object will have a smooth (Gouraud) shaded appearance. specify normals: specify normals in the le. The mesh must be followed by its vertices, normals and faces, described below. Usage example (a full example is given after the meshvertex, meshnormal and meshface have been described: mesh teapot compute_normals_gouraud
3.33.1 meshvertex
The syntax of meshvertex is: meshvertex "mesh name" index point The mesh name refers to the mesh name given in an earlier mesh keyword. index is the positive index of the vertex in the list of vertices. point can be the name of an existing object with a point interpretation, or the 3D coordinates of the point between square brackets. Usage example: meshvertex teapot 0 [1.0e1 + 1.0*e3]
25
3.33.2 meshnormal
meshnormal allows you to specify the surface normal at a vertex. The syntax of meshnormal is: meshnormal "mesh name" index vector The mesh name refers to the mesh name given earlier in a mesh keyword. index is the positive index of the vertex in the list of vertices. point can be the name of an existing object with a vector interpretation, or the 3D coordinates of the vector (not a bivector.... :) between square brackets. Usage example: meshnormal teapot 0 [1.0e1 + 1.0*e3]
3.33.3 meshface
meshface species a face of a mesh. It can have an arbitrary (current max 16) number of vertices. Vertices should be listed in counter clockwise order, when viewed from the front side. The syntax is: meshface "mesh name" vertex_idx1 vertex_idx2 ... vertex_idxN Usage example: meshface teapot 295 327 328
26
play filename.geo arg1 arg2 ... argN The arguments are optional and will replace $1, $2 ... $N. A playlist for a presentation could look like this: play ppt/ppt.geo ppt_01_title.png play play play play ppt/ppt.geo ppt/ppt.geo ppt/ppt.geo ppt/ppt.geo ppt_02_overview_1.png ppt_02_overview_2.png ppt_02_overview_3.png ppt_02_overview_4.png
#block 1 play ppt/ppt.geo ppt_03_block1.png play play play play ... demos/crossproduct.geo demos/outerproduct.geo demos/trivector.geo demos/basiselements.geo
Chapter 4
4.2 ans
When you type e1 on the console: >> e1 ans = 1.00*e1 youll see that the value of the statement e1 gets assigned to ans. When you enter a statement on the console thats (implicitly) terminated with a comma, every variable that was assigned a value is displayed on the console and in the view window. If no assignments were made, the result of the statement is assigned to the ans variable. When you enter a statement that is terminated by a semicolon, ans is deleted.
29
All these operators are internally translated to function calls by GAViewer (sections 4.9.1 and 4.9.3). The . operator is translated to hip (Hestenes inner product) by default, but it can be set by the inner product() function. The default is hip, but mhip, rcont and lcont are also possibilities 1 . This example shows the effect of changing the inner product from Hestenes inner product to left contraction: >> e1 e2 . e1 // here the default Hestenes inner product ans = -1.00*e2 >> inner_product(lcont) >> e1 e2 . e1 // now the left contraction is used ans = 0 >>
30 CHAPTER 4. THE PROGRAMMING LANGUAGE AND THE CONSOLE If some identier, like alpha is currently a function, you can force it to become a variable by using the variable statement. The other way around can be done by declaring the function again. Consider: >> a = alpha(e1, 0.5) a = 1.00*e1 >> variable alpha; // declare alpha -> variable >> alpha = 1 alpha = 1.00 >> >> function alpha(x, y); // declare alpha -> function >> alpha = 1 // this is no longer allowed line 1:7: expecting (, found = ans = 1.00 >> a = alpha(e1, 0.5) a = 1.00*e1
31
4.7 Arrays
Array indices can be used to generate new variable identiers. GAViewer does not have any real support for arrays. For example, you can not pass arrays to functions or return them from functions. The C-like syntax for accessing an array element in GAViewer is A[idx1][idx2] ... [idxN].
32 CHAPTER 4. THE PROGRAMMING LANGUAGE AND THE CONSOLE Preferably, all arguments have the right type (e3ga, p3ga, c3ga). This would be a perfect match. If no perfect match can be found, the next best match is searched: all functions with the right name and right number arguments are collected. The best matching function is the one for which the coercing distance is smallest. This distance is dened as follows: coercing to a higher dimensional model is preferred over coercing to a lower dimensional model, since no information is lost.
4.9.1 Products
While many products are accessible through operators, they can also be explicitly called through the following functions: function(arguments) return value gp(a, b) geometric product of a and b igp(a, b) inverse geometric product of a and b op(a, b) outer product of a and b (a / b) hip(a, b) Hestenes inner product of a and b mhip(a, b) modied Hestenes inner product of a and b lcont(a, b) left contraction of a and b rcont(a, b) right contraction of a and b scp(a, b) scalar product of a and b meet(a, b) meet of a and b join(a, b) join of a and b Since version 0.41, two products are available in a Euclidean Metric avour also, which can be useful for low level work (for example, the meet and join use these products internally): function(arguments) return value gpem(a, b) geometric product (Euclidean Metric) of a and b lcem(a, b) left contraction (Euclidean Metric) of a and b
33
4.9.3 Boolean
A number of functions for doing boolean arithmetic are available. 0.0 is false. Any value that is not false is considered to be true. The function scalar()
34 CHAPTER 4. THE PROGRAMMING LANGUAGE AND THE CONSOLE returns the grade 0 part of a multivector. function(arguments) return value equal(a, b) true if (a - b) equals 0 ne(a, b) true if (a - b) does not equal 0 less(a, b) true if scalar(a) < scalar(b) greater(a, b) true if scalar(a) > scalar(b) le(a, b) (less or equal) true if scalar(a) scalar(b) ge(a, b) (greater or equal) true if scalar(a) scalar(b) and(a, b) true if a is true and b is true or(a, b) true if a is true or b is true not(a) true if a is false Bitwise boolean arithmetic can be done with the functions in the following table. Arguments are converted to 32 bit unsigned integers before performing the bitwise operation. function(arguments) return value bit not(a) returns the bitwise not of scalar(a) bit and(a, b) returns the bitwise and of scalar(a) and scalar(b) bit or(a, b) returns the bitwise or of scalar(a) and scalar(b) bit xor(a, b) returns the bitwise xor of scalar(a) and scalar(b) bit shift(a, b) returns bitwise shift left of scalar(a) by scalar(b) The second argument of bit shift() can be negative for right shift. The only reason to include these bitwise boolean functions was to allow user to write there own autocolor() 4.13 function, where some tests on bitelds need to be done. The bitwise boolean functions are not of much use for geometric algebra.
4.9.4 Drawing
Various drawing properties of multivectors can be set with the functions described below. The functions are always used as in the example: >> a = cyan(e1) a = 1.00*e1 >> This draws the vector a in cyan. Compare this to the following example, which will not work as expected: >> green(a) ans = 1.00*e1 One might expect green(a) to turn the multivector a green. Bit what actually happens is that the value of a gets assigned to ans, and then ans gets drawn. Since ans is equal to a, it may or may not be drawn on top of a. On the next statement you enter, the value of ans will be overwritten or removed, and youll see that the actual color of a has not changed. So the functions that modify drawing properties only set certain ags and values on the intermediate variables and have no effect unless such intermediate variables are assigned to something. Drawing functions can be nested like this:
35
The color and opacity (often called alpha in computer graphics) of variables can be set using these functions: function(arguments) effect: red(a) a turns red green(a) a turns green blue(a) a turns blue white(a) a turns white magenta(a) a turns magenta yellow(a) a turns yellow cyan(a) a turns cyan black(a) a turns black grey(a) a turns grey gray(a) a turns gray color(a, R, G, B) the color of a becomes the RGB value [R, G, B] color(a, R, G, B, A) the color/opacity of a becomes the RGBA value [R, G, B, A] alpha(a, value) the alpha (opacity) of a becomes alpha Red, green, blue and alpha values should be in the range [0.0 1.0]. A alpha of 0.0 is entirely transparent (the object will be invisible), while a value of 1.0 will be entirely opaque. Values outisde the [0.0 1.0] range will be clamped by OpenGL. Multivectors can be drawn stippled, wireframed, with or without weight or orientation, and some multivector interpretations allow for an outline to be drawn. All of this can be set with these functions: function(arguments) effect: stipple(a) draws a stippled no stipple(a) draws a not stippled wireframe(a) draws a in wireframe no wireframe(a) draws a without wireframe outline(a) outlines a no outline(a) does not outline a weight(a) draws the weight of a no weight(a) does not draw the weight of a ori(a) draws the orientation of a no ori(a) does not draw the orientation of a To force hiding/showing a multivector, use the show() and hide() functions, but rememeber to assign! >> a = e1 // Draws a a = 1.00*e1 >> a = hide(a), // Hides a, despite the comma. a = 1.00*e1 >> a = show(a); // Shows a, despite the semicolon. a = 1.00*e1
36 CHAPTER 4. THE PROGRAMMING LANGUAGE AND THE CONSOLE >> hide(a) // Does not hide a. // Instead, assigns the value of a to ans, // and hides ans. Some multivector interpretations can be drawn in multiple ways. For instance, if you type: >> line = ori(ni no e1) youll see a popup menu labeled draw method in the controls on the right hand side of tha GAViewer UI. Use it to select various ways to draw the orientation of the line. From the console, you can also set the draw method, using the dm functions: >> line = dm2(ori(ni no e1)) The index (2 in the example) can range from 1 to 7. If it is out of range for the specic multivector interpretation, the default is used. You can retrieve the drawing properties of variables using the following functions: function(arguments) return value: get color(a) a vector with rgb color of a get alpha(a) a scalar with alpha of a get stipple(a) a boolean scalar with ag stipple of a get wireframe(a) a boolean scalar with ag wireframe of a get outline(a) a boolean scalar with ag outline of a get weight(a) a boolean scalar with ag weight of a get ori(a) a boolean scalar with ag ori of a get hide(a) a boolean scalar with ag hide of a A label can be drawn at the position of an object using the label() function. Not every object has a positional aspect to it, in which case the label will be drawn in the origin. The rst argument to label() is the variable that you want to label. The optional second argument is that text of the label (by default, the name of the variable is used as the label text). Some examples: >> a = e1 a = 1.00*e1 >> label(a); >> label(b = 2 a) // this is short for b = 2a, label(b); b = 2.00*e1 >> label(c = e2, "this is c") c = 1.00*e2 The following two functions dont really affect how a variable is drawn, but more how a variable is interpreted. versor(a): forces a versor interpretation of a. blade(a): forces blade interpretation of a. versor() can be useful when a versor coincidentally becomes single-grade. Consider: >> a = versor(e1 e2) a = 1.00*e1e2
37
draws a bivector. blade() is useful when oating point noise on some grade parts becomes so large that GAViewer mistakes a blade for a versor. Suppose you have a bivector a = e1 e2 but due to some manipulations, oating point nouse causes the scalar part to be 0.01 instead of 0: >> a = e1 e2 + 0.01 a = 0.01 + 1.00*e1e2 a gets interpreted and drawn as a rotor in this case. Now, to force a to be interpreted as a blade, use: >> a = blade(e1 e2 + 0.01) a = 0.01 + 1.00*e1e2
4.9.5 Controls
Scalar controls can be created by using the functions described in the list below. To get an idea of what scalar controls are useful for, enter the following code on the console: >> ctrl_range(a = 2.0, 0.5, 10.0); >> dynamic{v = a e1,} v = 2.00*e1 Now move the slider that appeared in the lower right window (section 4.10 for a discussion of dynanic). ctrl bool(name = value): creates a boolean control with name name, set to value. ctrl range(name = value, min value, max value): creates a slider control with name name, set to value, limited to min value and max value. ctrl range(name = value, min value, max value, step): creates a slider control with name name, set to value, limited to min value and max value values, that can only be changed step at a time. ctrl select(name = value, option1 = value1, ..., optionN = valueN): creates a selection menu with name name, set to value. A maximum op 7 options can be specied, value must be one of the options ctrl remove(name): removes any control with name name All these functions also have a variant where you can specify a callback batch function to be called when the user changes the widget. These functions have names ending in with callback. An example:
38 CHAPTER 4. THE PROGRAMMING LANGUAGE AND THE CONSOLE batch myCallback() { switch(choice) { case 1: x = c3ga_point(e1), break; case 2: x = c3ga_point(e2), break; } } ctrl_select_with_callback(choice=1, choice1 = 1, choice2 = 2, "myCallback");
39
c3ga point(c1, c2, c3): returns the conformal point constructed from the e3ga vector [c1 e1 + c2 e2 + c3 e3]. c3ga point(e3ga a): returns the conformal point constructed from the e3ga vector a. c3ga point(p3ga b): returns the conformal point constructed from the p3ga point a. translation versor(a): returns a conformal versor that translates over the e3ga vector a. tv(a): synonym of translation versor(a). translation versor(c1, c2, c3): returns a conformal versor that translates over vector [c1 e1 + c2 e2 + c3 e3] tv(c1, c2, c3): synonym of translation versor(c1, c2, c3).
4.9.10 Networking
Since version 0.4, other programs can communicate with GAViewer over a TCP connection. To enable this, use the command: >> add_net_port(6860); Server socket setup correctly at port 6860 After this command, GAViewer will listen on TCP port 6860 to clients trying to connect. You can try the connection out by using telnet. In a Unix terminal, or on a Windows command prompt use something like telnet localhost 6860 to connect. GAViewer will immediately send the values of all known variables:
"autocolor" = 1.000000000000000e+000;$"camori" = 1.000000000000000e+000;$"camp " = 1.100000000000000e+001*e3;$ In the telnet application, you can type commands that you would otherwise type on the GAViewer console, but they must be terminated with a dollar sign. For example: a = e1 + e2,$ GAViewer will reply: "a" = 1.000000000000000e+000*e1 + 1.000000000000000e+000*e2,$ because the value of variable a changed. Every time a variable changes value, GAViewer will send such a message to all connected clients. Here are the commands related to networking add net port(port): start listening on TCP port. remove net port(port): stop listening on TCP port; disconnect all current clients. net status(): prints out a summary of the network status. net close(): shuts down all network connections and ports. You can start up GAViewer as follows: gaviewer -net This enables TCP port 6860 immediately. Optionally you can specify the port, for example gaviewer -net 5000 This enables TCP port 5000 immediately. Networking is disabled by default, because anyone on the internet can connect to your GAViewer this way (unless you block this using a rewall) and I cannot guarantee that GAViewer cannot be exploited (through buffer overows, for example) to give someone access to your computer. However, it is unlikely that someone will go through the effort of nding such an exploit as long as GAViewer is a niche application.
41
42 CHAPTER 4. THE PROGRAMMING LANGUAGE AND THE CONSOLE dynamic can only be called in the global scope, not inside functions or batches called by functions. Setting the inner product using inner product() (section 4.3) will not cause dynamic statements using the . operator to be re-evaluated. The function cld() removes all dynamic statements Terminating statements with colon or semincolon only effects the visibility of variables on the rst time the dynamic statement is evaluated. hide() and show() do affect visibility on every re-evaluations.
4.10.2 Animations
One way to achieve animation in GAViewer is by writing dynamic statements that depend on the atime variable. For example, enter the following dynamic statement on the console: >> dynamic{print(atime);} atime = 0 Now select DynamicStart/Resume Animation: >> >> >> >> >> atime atime atime atime atime = = = = = 0 0.01 0.07 0.13 0.19
As you can see, atime will be set to the time elapsed since the animation was started. atime will be set at most 30 times per second, but it may be slower, depending on the time required to redraw the view window and to re-evaluate dynamics. To stop the animation, select DynamicStop Animation. To pause, select DynamicStop Animation. By writing more complicated dynamic statements involving atime, more interesting animations can be produced. You can also start and stop animations from the console.
43
start animation() starts the animation of dynamics depending on atime. It is guaranteed that when an animation starts, atime will be 0. You can check atime == 0 and do some kind of initialization if you need to. stop animation(): stops animation. pause animation(): pauses animation. resume animation(): resumes animation (synonym of start animation()). For example: >> cld(); // remove all current dynamics >> dynamic{a = sin(atime) e1, if (atime > 10) stop_animation();} a = -0.86*e1 >> start_animation(); This animation will run for about 10 seconds because it stops itself when atime is larger than 10.
4.11.1 if else
An if else looks like this if (condition) statement [else statement] As indicated by the square brackets, the else part is optional. For example: >> if (a == 1) {b = 1;} else {b = 2;} For simple if else statements you can leave out the curly brackets. So the example from above can be rewritten without change in semantics to the following: >> if (a == 1) b = 1; else b = 2;
4.11.2 for
A for statement allows one to write a loop. It looks like: for ([init] ; [cond] ; [update]) statement It works as follows: to begin with, the init statement is executed. Then before every execution of the statement, it is checked whether cond is true. If so, statement is executed, otherwise the loop terminates. After the statement has been executed, update is executed. The square brackets around init, cond and update indicate that they are all optional. If cond is not specied, it is assumed to be true. An example of a for loop is:
44 CHAPTER 4. THE PROGRAMMING LANGUAGE AND THE CONSOLE >> for (i = 0; i < 5; i = i + 1) {print(i);} i = 0 i = 1.00 i = 2.00 i = 3.00 i = 4.00 A for loop can be terminated prematurely by issuing a break statement. A for loop can be forced to terminate the execution of the current loop body by using a continue statement. The following for loop would loop forever, if it wasnt for the break statement. The print() of i for i == 1 is skipped, as you can see in the output. >> for (;;) { if (i == 1) continue; print(i); if (i == 3) break; } i = 0 i = 2.00 i = 3.00
4.11.3 while
The while language construct also allows you to perform loops, but in a slightly different format. A while loop looks like while (cond) statement It loops as long as cond is true, executing the statement on every loop. An example of a while loop is: >> while (i < 5) {print(i); i = i + 1} It is very easy to write innite for or while loops, for example, by forgetting to increment i. In such a case, GAViewer will hang forever. Try for example: >> while (1) {} As with the for loop, continue and break can be used to control the loop.
4.11.4 switch
A switch statement allows you to compare the value of an expression against the value of a bunch of other expressions, and to undertake some action depending on the outcome of that. It looks like this: switch(expression) { case expr1: [statements] case exprn: [statements] default: [statements] }
45
All the statements are optional. They may include break statements to leave the switch. A more or less typical switch would look like: switch(i) { case 1: cprint("i is 1"); break; case 2: case 3: cprint("i is 2 or i is 3"); break; case j + 2: cprint("i is (j + 2)"); break; default: cprint("the default action was called"); } Note that, as opposed to C, arbitrary expressions (such as j + 2) are allowed for cases.
46 CHAPTER 4. THE PROGRAMMING LANGUAGE AND THE CONSOLE More than 8 arguments currently crashes the GAViewer. An arbitrary number of arguments should be allowed for in the future. The type specier (e3ga, p3ga, c3ga) is optional. If no type is specied, actual arguments always match perfectly. A return type specier can not be given. A multivector is always returned, without any restrictions on the model/type. Inside a function, you can type arbitrary statements. A return expr statement cause the function to terminate and return the value of expr. It is also allowed to dene new functions inside functions. For example: function f(a) { function neg(b) { return -b; } return 2 * neg(a); } You can declare the existence of a certain function without dening it like this: function f(a); So a function declaration is like a function denition, except you leave out the function body and replace it with a semicolon. All variables inside a function are local by default. This means that you can not see variables from the global scope, nor can you set variables in the global scope. The :: operator can be used reach variables in the global scope from inside a function: function setGlobalVar(a) { ::globalVar = a; }
4.12.1 Batches
Batches are functions that execute in the same scope as the caller. This means that youll have to be really careful when calling batches and make sure that variable names used in the batch are not used for some other purpose in the calling scope. For instance, if formal argument names of a batch are already present in the scope of the caller, they will be overwritten. Batches are most useful for writing interactive demos and tutorials. Often you want to execute a bunch of statements that are too tedious for the user of your tutorial to type by hand. Then you can collect these statements into a batch, store them in a .g le and have the user load that. There is a special suspend statement to allow for interaction inside batches. Consider: batch demo1() { a = show(e1); cprint("a is now equal to e1."); cprint("Drag the left mouse button to rotate your view."); cprint("Type arbitrary commands on the console."); cprint("Press enter to continue.");
4.13. AUTOCOLOR.
// set a special prompt prompt("demo1 suspended... >> "); // suspend the current batch suspend; // set the prompt back to normal prompt(); cprint("Welcome back to demo1"); a = show(e2); cprint("a is now equal to e2"); cprint("This is the end of demo1"); } Using suspend is not allowed outside the global scope.
47
4.13 Autocolor.
You may have noticed that not all variables are drawn in the same color. Grade 1 variables are red, grade 2 variables are blue, etc. This color is set by a built-in function called autocolorfunc(). Every time variable in the global scope that is assigned a value, it is send is through autocolorfunc() to give it a distinctive look before. The default builtin autocolorfunc() changes the color of the variable depending on it grade (but only if the color has not been set explicitly by one of the drawings function (section 4.9.4)). It also turns on stippling for imaginary conformal model objects (such as the circles of intersection of two spheres that do not intersect). You can turn the auto-color feature of by setting the global variable autocolor to false. If autocolor is false, all variables get the same default foreground color.
48 CHAPTER 4. THE PROGRAMMING LANGUAGE AND THE CONSOLE How do I know whether some drawing property of a variable was already set explicitly by the user. Of course, you dont want to override what the user has explicitly set. So call get draw ags(a). This will return a biteld that contains information about which drawing properties were set by the user.
Chapter 5
Typesetting labels.
GAViewer features a simple typesetting language which resembles Latex. It was implemented by the author as an introduction to parsing and interpreting languages, and of course because of its functionality. Here is a list of some of the features the the typesetting system provides: text and equation modes, sub- and superscripts, four scalable fonts (regular, italic, bold, greek), some special GA-symbols, tabulars, left, right, center, and justifyable alignment, hats, scalable parenthesis, (square) roots, fractions, custom commands (macros), and (custom) colors. The implementation of the typesetting system was kept simple, which makes it unsuitable for typesetting large amounts of text. The input is parsed, checked for syntax errors, and converted to a parse tree. After the parse pass have been completed, the parse tree is interpreted an turned into drawing commands. Then the parse tree can be released, and the drawing commands sent to OpenGL (or some other graphics API). Because parsing, interpreting and drawing do not occur in one pass, large amounts of memory will be required in large amounts of text are supplied as input. As a side note, lex and yacc are used for parsing the input. The font for the typesetting is a 1024 1024 pixel GL ALPHA texture. It is included directly in the source code, in fontdata.cpp. The font is antialiased 49
50
and contains all ASCII symbols of four font: regular, italic, bold, greek. It also contains several special GA-only symbols. Figure 5.1 shows an example of a complex typeset label. This gure is representative for the complexity the typesetting system was designed. The system can handle multiple lines and such, but dont use it to typeset entire pages like you can do with Latex.
5.2. FONTS
51
words. A backslash followed by letters is interpreted as a command. A backslash followed by numbers is interpreted as a custom command argument (section 5.13). Two backslashes next to each other is short for the newline command. A backslash followed by any other character is interpreted as an escape sequence for that character. To produce an actual backslash in the output, use the backslash command. The frac, sqrt, har and par commands are not valid in txt mode.
5.2 Fonts
Four fonts are available, as illustrated in gure 5.3. The input used to generate the gure speaks for itself:
52 Greek symbol o
\regular{Regular font.}\newline \bold{Bold font.}\newline \italic{Italic font.}\newline \greek{Greek font.} If you nd regular, bold, italic, greek, too long to type, you may consider using the equivalent abbreviations fr, fb, , fg, which stand for font followed by the rst letter of the name of the font. Of couse, fonts can be embedded in each other as with the txt and eqn modes. So the following lines also result in the output shown in gure 5.3: \regular{Regular font.\newline \bold{Bold font.\newline \italic{Italic font.\newline \greek{Greek font.}}}} The default font in math mode is italic for letters (variables) and regular for all other symbols. The greek alphabet is mapped to the ASCII alfabet as shown in gure 5.4. Their are two ways to produce greek characters. The rst way is to switch to the greek font, the second is to use the command supplied for each character, e.g., alpha to produce the symbol :
53
\greek{a} \alpha The greek symbol commands work in both txt and eqn modes.
Figure 5.6: Forcing whitespace at both sides of the semicolon using the ws command.
54
Newline are automatically inserted when text is too wide to t on the current line. To force a newline to be inserted, you can use the newline command, as was already shown in the four fonts example above (section 5.2). Two backslashes is a short synonym for a newline.
5.5 Alignment
Four alignment modes are offered to place text on a line as required, and to ll out the line if required. The rst mode is left. This places all text as far to the left as possible. right modes places all text as far to the right as possible. center modes places all text in the center of the line. justify mode spaces all text such that it nicely ts the maximum width of the line. The ouput in gure 5.7 was generated from the following input: \left{Left mode}\newline \right{Right mode} \newline\center{Center mode} \newline\justify{Justify mode}
5.7. PARENTHESES
55
Figure 5.9: The three types of parentheses, and an example of how parentheses scale with their contents.
\eqn{x{y} + M_{12} - e_{1}{2}} If you try to append multiple subscripts or multiple superscripts to a single word, the system will complain and ignore everthing but the rst sub- or superscript.
5.7 Parentheses
Three types of parentheses can be placed around pieces of text in eqn mode: square parentheses [], round parentheses () and curly parentheses {}. The brackets automatically scale with the size of the input. Here are some examples of their use, the output is in gure 5.9: \center{ \eqn{\par{()}{\txt{Round parentheses}}}\newline \eqn{\par{[]}{\txt{Square parentheses}}}\newline \eqn{\par{\{\}}{\txt{Curly parentheses}}}\newline \eqn{\par{\{\}}{\frac{\txt{Curly parentheses with some}} {\scale{2.0}{\txt{big text}}}}}} As you can see, the rst argument to the par command is the parentheses you would like. These can be any mix of types, e.g.: [], (] or even something weird like }{. The second arguments species the contents of the parentheses. Note that you always have to be in eqn mode (for no apparent reason...), but you can cheat you way around this by including txt commands inside the parentheses command.
56
5.8 Tabulars
Tabulars can be used for all kinds of purposes where you want to arrange text in row and columns. Examples of their use are tables and matrices. We will give an example of both. The tabular command rst argument specify the number of columns, the alignment of content inside the columns, and optional vertical lines between them. All following arguments specify rows. Inside a row, each column is seperated by an ampersand: &. The alignment of a column can be Here is an example of a table with 4 columns and 4 rows (output in gure 5.10): \tabular{|r||c|c|c|} {\hline} { &\bold{1998}&\bold{1999}&\bold{2000}} {\hline} {\hline} {\bold{x}&1.0&1.2&1.4} {\bold{y}&+&-&++} {\bold{z}&bad&worse&horrible} {\hline} The width of a column is determined by the width of the widest item in the column. The alignment can be l, r, c or j (left, right, center, or justify), and behaves as described in section 5.5. A vertical bar in the rst argument produces a vertical line. A row containing only an hline command produces a horizontal line. Empty or unspecied entries in row are lled with blanks; surplus columns in row are ignored with a warning issued. Now for an example of a matrix: \eqn{\bold{M} = \par{[]}{ \tabular{cccc} {\fr{R_{11}}\ws{0.2}&\fr{R_{12}}\ws{0.2}&\fr{R_{13}}\ws{0.2}&0} {\fr{R_{21}}&\fr{R_{22}}&\fr{R_{23}}&0} {\fr{R_{31}}&\fr{R_{32}}&\fr{R_{33}}&0}
57
{\fr{t_{1}}&\fr{t_{2}}&\fr{t_{3}}&1} }} This produces gure 5.11. Note the use of the ws command to force some extra whitespace between columns.
5.10 Fractions
To construct complicated fractions where the numerator and the denominator are separated by a horizontal line, use the frac command. It takes two arguments (the contents of the numerator and the denominator). The size of the
58
font is implicitly scaled by 0.9 in a fraction, but this can be corrected by using the scale command (section 5.3). The output in gure 5.13 was generated from the following input: \eqn{\frac{1}{x+y}\ws{2.0} \frac{a{2} - b{2}}{a + b} = a - b}
5.11 Hats
You can add hats, bars and tildes on top of text by using the hat, widehat, bar, widebar, tilde or widetilde commands. The wide variants scale with the size of the content, as is illustrated by the following examples, and its output in gure 5.14. \eqn{ \hat{A}\ws{1.0}\tilde{\frac{x}{y}}\ws{1.0} \widehat{A + B + C}\ws{1.0}\widebar{A + B + C}} All types of hats look rather bad when (OpenGL) antialiasing is turned off.
5.12 Colors
Text can be typeset in arbitrary colors. A xed number of colors is known to the system, and custom colors can be dened using a special command described below. The default colors are: red, green, blue, magenta, yellow, cyan, black, white, grey and gray (these last two are synonyms). The draw text in one of these colors (the default is black by the way), do something like the following (output in gure 5.15): Black text, \red{red text}, \blue{blue text} \newline and a green \green{frog}.
59
60
easier and less error-prone to change a single custom command denition, than to replace every occurance of the bold command. Here is an example of dening and using a custom command: \newcommand{\mv}{\bold{\1}} \eqn{\mv{C} = \mv{a} \op \mv{b}} The output is in gure 5.16a. The rst argument to the newcommand command is the name of the the new command (mv in this case). The second argument is what the command should be expanded to. Inside the second argument, a backslash followed by an positive number i will be replaced ith argument of the new command. The mv command takes only one argument, but next we give an example of multiple arguments (output in gure 5.16b). \newcommand{\wc}{\eqn{\sqrt{\frac{\1}{\2}}{\3}}} \wc{1}{2}{3} Note that the eqn command is included inside the custom command, to force equation mode every time the command is used (otherwise the frac command may not work). This is like ensuremath in Latex. Commands with no arguments are also possible by simply not using any backslash positive numbers inside the custom command string. If a command is already dened, issuing a newcommand command for it will override its current value. Redening an existing predened command (such as txt or par is possible but not recommended.
Bibliography
[1] D. Fontijne, T. Bouma, L. Dorst Gaigen: A Geometric Algebra Implementation Generator. Available at http://carol.science.uva.nl/fontijne/gaigen
61