OVERVIEW: CenterStage is a Geomview external module that allows you to create geomview objects easily and interactively. It can create parametric surfaces and curves, polyhedra, vectors, and objects that build on other objects, such as tubes around curves, and offset surfaces and curves. Objects can be grouped into compound, hierarchical objects. You can control an object's coloration and appearance in a variety of ways, and there are several different surface and curve domain styles (solid, grid, bands, lines, dots, checkerboard, etc). CenterStage also provides a means of tying sliders, check-boxes and type-in areas to parameters for the objects it creates, and will update them automatically when these values are changed. Moreover, StageManager can be used to control these values, so you can make a movie of a surface deforming as its parameters change for example. CenterStage is intended as an easy means of producing geometric objects for use within Geomview. STARTING CENTERSTAGE: Once geomview is running, select CenterStage from the modules panel. This will load CenterStage. CenterStage has a fairly long startup sequence, so it tells you what it is doing via the message bar at the bottom of its window. When the menu bar becomes active, CenterStage is ready to go. To exit from CenterStage, press the QUIT button. CREATING OBJECTS: The main purpose of CenterStage is to be able to create objects for Geomview to display. To create an object, you first select the NEW item from the OBJECT menu. You will be asked to select the type of object to create and to give the object a name. The basic object types are SURFACE, CURVE, and POLYHEDRON, plus some specialized objects like AXES, and ARROWS. Once you have selected the type, click the OK button to create it. The name of your object should appear in the objects list at the right, and the object's type will be shown in blue at the far right of the menu bar. For your convenience, a template for the type of object that you have selected will be displayed in the type-in area. The template gives you a place to start creating your object. For example, if you have selected a surface, you will get a template for the domain and the function definition. You can edit these to suit your requirements. The template usually does not include all possible types of data you can specify for the object; to obtain a template for one of the optional directives, select the item from the TEMPLATES submenu in the OBJECT menu. Once you have defined the object to your liking, press the UPDATE button to have it computed and displayed in Geomview. CenterStage is designed for flexibility, not speed, so this may take a few moments. It is usually best to keep your domain sizes small to begin with until you are sure it is the way you want it to be, then increase the size for the final version of the object. For more information about a specific object type, see the documentation for that object class. If you make edits to your object, CenterStage will show a small diamond next to the object type at the right of the menu bar. This indicates that you need to update your object. If this diamond is showing, then the object being displayed by geomview may not correspond to the data that appears in the CenterStage window. Press UPDATE to be sure the object showing in geomview is up to date. CENTERSTAGE MENUS: The FILE menu controls the file you are editing. Each file can contain any number of objects (these are listed in the OBJECTS list at the right). Be default, CenterStage object files have the type ".cs". The items in the FILE menu are: NEW Clears the contents of definition area and deletes all the objects in the list. Resets the settings to their default. This is like starting CenterStage from scratch. OPEN Opens an existing CenterStage file (.cs) and loads the objects that it contains. SAVE Save the currently defined objects and menu settings to the same file they were read from. You should do this periodically to be sure that your edits are saved. SAVE AS Saves the objects and menu settings under a new name. A new file is created and it becomes the current files. The original file is not altered. REVERT Rereads the objects and menus settings from the file, thus eliminating all edits that occurred since the last save. IMPORT This item lets you load an object (or collection of objects) into the current file from some other file. This differs from the OPEN menu in that OPEN forgets about the current file and starts using the new file, whereas IMPORT incorporates the contents of the new file into the current one, making the current file larger. EXPORT This item saves the current object (and only the current object, unless the object is a group, in which case all the objects contained in the group as well) to a file. This differs from the SAVE AS menu in that SAVE AS saves ALL the objects to the named file and makes that file the current one, whereas EXPORT saves a single object to a file but does not change the current file. Thus EXPORT and IMPORT provide a mechanism for copying objects from one file to another. SAVE OOGL This item will cause CenterStage to write an OOGL file that contains the data for the current object. This file can be read directly into Geomview without requiring CenterStage to recompute it. Note, however, that CenterStage can not read an OOGL file, only a file that was created with SAVE, SAVE AS or EXPORT. LIBRARY This item brings up a panel that lets you specify arbitrary TCL files that should be included when this file is loaded. For example, if you have defined your own class of objects, you may want to include the .tcl file that defines the object so that your new class will always be available when the file is loaded. QUIT Exits CenterStage. The EDIT menu provides standard editing features, and lists their keyboard equivalents. These commands operate on regions of text selected with the left mouse button, or by holding down the SHIFT key and using the arrow keys. The standard X-windows selection mechanism also works for copying text from one window to another. The EDIT menu also includes a PREFERENCES item. Currently, there is only one preference, and that controls whether CenterStage uses the old 'let' statement (that does not understand mathematics very well) or the new one that allows you to write more mathematical statements. This preference is mainly for backward compatibility with files created by older versions of CenterStage. The OBJECT menu lets you create and manipulate objects. It has the following items: NEW This item lets you create a new object. You will be asked to select an object type (surface, curve, etc.) and to give the object a name. If the new object requires a link to an existing object, you will be requested to make the link at this point. The new object is created at the same level of the hierarchy as the currently selected object. ADD Similar to NEW, this menu item creates a new object, but if the currently selected object is a group, the new object is added to the group. RENAME This item lets you rename the selected object. DUPLICATE This lets you create a duplicate of the selected object. You will be asked for a new name for the duplicate. DELETE This item lets you delete the current object and remove it from the objects list. There is no way to undo this operation, so be careful! TEMPLATE This menu contains items for each type of information that you can specify for the given object. You can get a template for the directives that were not included in the original template for the object. For example, if you want to add a slider bar, you can select the template for Slider to see how to specify one. Items in parentheses should be replaced by corresponding values. Some templates do not show all possible optional values or flags. See the documentation for the object type you are using for more complete details on the directives that can be supplied. LINK TO Many objects build on other objects in some way; for example, the TUBE object requires a CURVE object and builds a tube around the curve. When such an object is created, you must supply a link to an object of the appropriate type; however, if you want to change the object, you can use this menu item to select a new one to link to. Those objects that do not build on some other object can also be linked to objects; in this case, when the referenced object is updated, it will force the current object also to be updated. MOVE TO GROUP This menu item lets you move the current object into an existing group. You will be asked to select the group from a list of the currently available groups. You can move objects from one group to another using this menu item. REMOVE FROM GROUP This menu item makes the currently selected object a top-level object (i.e., it is removed from any group it is in). UPDATE This menu lets you update the current object in different ways. The DEFINITION option causes the current object to process the type-in area, but not recompute the object at this time. You may want to use this if you have added, for example, a ColorFunction and want to be able to select it in the COLOR menu without having to update the object unnecessarily. The COLORS item recomputes the object's colors (without recomputing its data), and the APPEARANCE item updates the object's appearance characteristics without recomputing the object's data. The OBJECT item updates the entire object (just like pressing the UPDATE button). These items are most useful when the AUTOMATIC checkbox is unchecked. If AUTOMATIC is checked, then the object is updated automatically whenever you select a new item in the COLORS and APPEARANCE menu. If you want to make several changes without having to wait for an update after each one, you should uncheck the AUTOMATIC checkbox. SHOW This menu controls when Geomview shows the current object. Normally, only the selected object will be displayed in Geomview. If you want the current object to always be shown, even when it is not selected, chose the ALWAYS item. If you never want Geomview to show this object, select NEVER; this is useful for objects that are merely needed to define other objects. For example, if you have a curve object that is used as a reference for a tube object, you may not want the curve to be displayed, so you should select the NEVER item for the curve. NORMALIZE By default, Geomview scales and centers any object it displays so that it will fit into a unit sphere at the origin. This makes sure you can see the entire object, but it also means that if you have several objects, their position and size may not be correctly represented. You can use this menu to help overcome the problem. NONE means Geomview will not normalize the object, so if you have several objects with normalization NONE, they will be properly positioned. KEEP means it will normalize the object when it first appears, but then will not renormalize it if the object changes. If you have a dynamically changing object, this may be the best setting for you. EACH is the default Geomview action: any time the object changes it is re-normalized. ALL means that Geomview will renormalize the object only if it gets bigger. The NORMALIZE/AGAIN item means Geomview should normalize the object, but then KEEP the current normalization. Another way around the normalization problem is to place all the objects into a group object, as Geomview only normalizes the group as a whole, not the individual objects within the group. The COLOR menu lets you specify how the object should be colored. There are several standard colorations that you can apply, or you can define your own using the ColorFunction directive. BY PARAMETER For a parametric surface or curve, this will color the object by spreading the colors from the lowest to the highest value of one of the parameters: all the points with the same parameter value will be colored the same color. BY COORDINATE Here, all the points on the object that have the same value for the coordinate you choose will be colored the same color. BY FUNCTION This lets you choose from among the color functions that you have defined (or that are defined automatically by the system). You can create a new coloring function via the ColorFunction directive (see the template for ColorFunction). You give the function a name and a means of computing the function's value, witch is either an index into the color table or an RGB color value (depending on whether the result is a single number or a triple of numbers). You can use color functions to produce virtually any coloration of the object. SOLID This specifies that the object should be a solid color. The menu lets you specify the color to use, or NONE, which means no color is applied to the object (Geomview's lights also may cause the object to be colored). If you want a solid color that does not appear on the list, you can use the OTHER... item to specify RGB values for the color. You can also edit the color table to provide aditional named colors. NORMALIZE This check-box determines whether CenterStage will scale all the color values so that they use the full spread of colors. The color table uses indices from 0 to 1 to determine which color to use, so if your color function gives values outside this range, or doesn't use the full range, the object would be colored strangely. If NORMALIZE is checked, however, CenterStage will scale whatever range of color values you specify so that they will always be between 0 and 1 (unless there is only one value to start with). This means you don't have to be careful about making sure your function always returns a number from 0 to 1. Similarly, for RGB values, CenterStage will scale all the coordinates so that the range of red, green and blue values used over the entire surface is between 0 and 1. If NORMALIZE is not checked, then the exact values you specify will be used, even if they are outside of 0 to 1. WRAP COLORS If checked, this menu item means that the color table will have the same color at 0 and 1 (so that the color table can be used to color a periodic function more easily). Otherwise the two ends of the color table will be different colors. INHERIT COLORS If checked, this means that the object will inherit its color table from its parent object (if it is part of a group) or from the default color table. EDIT COLORS This item brings up the color-table editor. Currently it is pretty crude, but it lets you specify named colors and their RGB values, plus a count of how many entries in the color table should be used to go from this color to the next one. Higher counts menas more gradations are possible. Currently there is no way to edit the default color table, but you can copy and past the complete color list from one object to another. The APPEARANCE menu lets you specify Geomview appearance characteristics, such as shading and line thickness. SHADING This menu lets you choose the way Geomview will shade the object. CONSTANT means no lighting effects will be used, and each face will be a single color. FLAT means each face is a single color, but the lighting will be used to determine the color. SMOOTH means that each vertex of a face can have its own color and that the color of the rest of the face will be determined by linearly interpolating the vertex colors (this can make even coarsely parameterized surfaces look remarkably smooth). CSMOOTH means the same as SMOOTH but with no lighting effects. TRANSPARENCY This menu lets you specify how transparent an object should be. Transparency is only available via hardware support (on some SGIs). FACES This check-box lets you control whether the object's faces are shown. EDGES This check-box lets you control whether the object's edges are shown. NORMALS This check-box lets you specify whether the object's normal vectors are shown (the vectors that are used for lighting computations). INHERIT This menu lets you specify which appearance characteristics are inherited from the object's parent object (if it is part of a group). If a characteristic is NOT inherited, then its setting above will override the group's appearance characteristic. If it IS inherited, then the group's value will be used. The DOMAIN menu is available for parametric curves and surfaces. This menu lets you specify the style of the domain. For surfaces, you can specify that it is a solid patch, a grid, a checkerboard, etc., and for curves, you can make the domain be a solid line, a dashed line or a dotted line. See the documentation for the curve and surface classes for more information. The VECTOR menu is available for CurveVectors and SurfaceVectors objects. It lets you select the type of vectors that will be showing. You can select more than one type of vector at a time. For example, you can choose the tangent, normal and binormal vectors to get the Frenet frame. If UNIT is selected, then all the vectors will be normalized to unit length. See the documentation for these object classes for more information. CONTROLLING OBJECT VISIBILITY: Since CenterStage lets you define many objects at once, you may not want them all to be displayed simultaneously. By default, CenterStage only displays the object that is currently selected, so as you select different objects, previous objects will be removed from Geomview. You can change this behavior via the OBJECT/SHOW menu. If you select ALWAYS, the object will always be displayed, even if it is not selected. If you choose NEVER, the object will not be displayed, even if you do select it. This is useful if the object is merely being used as the basis for some other object; for example, if you are building a tube around a curve, you may not want the curve itself to be displayed. By default, objects in Geomview are centered and scaled so that they fit within a unit sphere. If you have several objects created by CenterStage, this normalization that Geomview performs may cause their relative sizes and positions to be inaccurate. For example, if you create a curve and a tube around the curve and display them both, the tube may not appear to be properly centered around the curve since Geomview scales the two differently. To overcome this problem, you can request that Geomview not normalize the objects. This is controlled via the OBJECT/NORMALIZE menu item (do not confuse this with the COLOR/NORMALIZE menu, which specifies whether the color values are scaled to between 0 and 1). If you set OBJECT/NORMALIZE to NONE, then geomview will display the objects properly; however, you may need to scale the scene by hand in order to see the complete objects. Another alternative is to create a group object rather than a collection of individual objects. Since Geomview only scales top-level objects (not individual parts of an object), this will guarantee that the parts of the group are in proper relation to each other. Geomview will scale the entire group so that you can see it, so this gives you the best of both worlds. You may wish to specify OBJECT/NORMALIZE as KEEP, so that as you change the parts of the object, GEOMVIEW will not rescale the group. CHANGING COLORS: Objects can be colored in a variety of ways, and these are specified by the COLOR menu. For parametric objects, you can color the object by one of its parameters (all the points with the same parameter will be colored the same color, and the colors will be spread across the different values of the parameter). Any object can be colored by its coordinates. For example, if an object has coordinates x, y and z, then coloring by x means that all the points on the object with the same x-coordinate will be colored the same color. Objects can also be colored solid colors or with no color at all (Geomview will use its default grey color, which may be modified by the lighting colors). You can specify an arbitrary coloring function via the ColorFunction directive. This requires you to specify a name and a function. The function will be evaluated whenever a color is needed, and it should produce either a single value which will be used as an index into the color table (usually a number between 0 and 1) or a triple of numbers that represent RGB values for the color. For example: ColorFunction distance {sqrt(x^2+y^2)} will define a color function called "distance" that returns the distance of (x,y) from the origin. If you select this function in the COLOR/BY FUNCTION menu, the object will be colored so that concentric cylinders around the z-axis will have the same color. If you specify: ColorFunction myRGB {(x,y,z)} then the three coordinates will be used as the values of red, green and blue for the color at that point. (This color function is always available as "RGB=XYZ" in the COLOR/BY FUNCTION menu, and it gives a rather soft shading to most objects). The function in a ColorFunction is not a TCL script that is executed, but rather an expression that is evaluated; however, variable substitution and command evaluation is performed on the expression before it is computed, so if you need to do a more complicated calculation for the color function, you can do so by calling a TCL procedure, as for example: ColorFunction TwoColor {[ChooseColor $x $y $z]} proc ChooseColor {x y z} { let len = Norm($x,$y,$z) if {$len > 2} {set color 1} else {set color 0} return $color } The braces around the brackets in the ColorFunction are necessary to prevent the execution of the ChooseColor procedure until the ColorFunction is used (without them, CenterStage would call ChooseColor at the time it was trying to define ColorFunction and would use its result as the definition of TwoColor; you would probably get an error that variable x does not exist because when CenterStage is processing the directives, it doesn't). CREATING HIERARCHICAL OBJECTS: CenterStage lets you create hierarchical objects using objects of type GROUP. To create such an object, first select the OBJECT/NEW menu and scroll the object list until it shows the GROUP type. Select this, give the object a name, and click OK. The object should show up in the object list and the type-in area will be blank (there is no template for groups). To add an object to the group, select OBJECT/ADD, choose the type you want, give it a name, and click OK. The object should appear in the object list just below the group object and indented. This means the object is part of the group object. You can add more objects to the group by selecting OBJECT/ADD again, or by selecting OBJECT/NEW when the current object is part of the group you want to add to. You can add as many objects to a group as you like. You can also add group objects to a group, so you can nest groups as deeply as you want. If you have created a top-level object and then later decide you want to move it into a group, you can do that using the OBJECT/MOVE TO GROUP command. You will be asked to select a group to add the object to; simply double-click on the group in which you want the object to appear. Similarly, you can move an object out of a group by selecting OBJECT/MOVE TO GROUP and selecting a different group. You can remove an object from a group by selecting the OBJECT/REMOVE FROM GROUP menu item. CenterStage will remove the object from the group and make it a top-level object. LINKS TO OBJECTS: Some types of objects in CenterStage are defined in terms of other objects. For example, the Tube class requires a Curve object about which the tube is generated. We call the object defined in terms of another the "referrer" or the "referring object", and the object it refers to the "linked object" or the "reference object". In the example above, the Tube is the referrer and the Curve is the reference object. When you create an object that requires a reference, you will be asked to select the reference object from a list of all possible references (only the objects of the required type will be shown). You must pick an object from this list. If the reference object is updated, the referrer is updated automatically so that the two are always synchronized properly. You can link two objects together even if the referrer doesn't require a reference. For example, if you have a surface and a plane that is a tangent plane to the surface, you may want to link the tangent plane to the surface so that it will be updated whenever the surface is changed. To do so, select the referrer in the object list and choose the OBJECT/LINK TO menu. You will be able to link the object to any object. Whenever that object is updated, the current object will be updated automatically. It is possible to create loops this way, so be careful. CenterStage tries to detect these and should be able to process them correctly, but some situations may cause CenterStage to go into an infinite loop. SLIDERS, CHECK-BOXES and TYPE-INS: Frequently, your objects may be defined in terms of a parameter that can be changed; i.e., you really have a family of objects. For example, you can define a cylinder that has its radius as a parameter. For such objects, is is often convenient to have a slider or type-in area where the value of the parameter can be specified. CenterStage lets you create such sliders and type-ins via the Slider and TypeIn directives. The Slider directive has the following form: Slider name min max [init] [options] where "name" is the name of the parameter, "min" is the minimum value for the slider, "max" is the maximum value, and "init" is the initial value for the slider. Once the slider has been created, it is bound to a TCL variable of the same name, and it can be used just like any other variable when your object is being computed. For example, you can define a surface as follows: Domain {{-1 1 10} {-1 1 10}} Function {x y} { let z = a(x^2-y^2) } Slider a -1 1 Here, the slider value controls the factor by which the z coordinate is multiplied in the function definition. Whenever the slider's value is changed, the surface will be recomputed using the new value. The Slider directive has the following options: -resolution r The value of r specifies the units by which the value of the slider can change. For example, -resolution 1 means the slider will change by integers only, while -resolution .1 means the slider will change by 10ths. -ticks r If r is not 0, this means that the slider should include reference numbers at increments of r. So -ticks .5 means there should be labels every .5 starting from the minimum. -digits n This specifies how many digits to use for the slider's value. This provides an alternative to the -resolution specification. -title string By default, the slider will be labeled by its name, but you can specify some other string to use to identify the slider. For example, you might use -title "Number of divisions". You may have as many sliders as you want for a given object. Sliders for group objects are inherited by the objects within the group. Sliders for different objects can have the same name, but it is not a good idea to use the same name in an object and its parent group (if you do, the object's slider takes precedence). Some values are better handled by typing in the value rather than using a slider. For this reason, CenterStage provides a TypeIn directive, with the following form: TypeIn name init [options] where "name" is the name for this type-in (used as a variable just as with sliders above) and "init" is the initial value for the type-in. The options are: -width n This specifies the width of the type-in area, in case you need a larger one than the default. -lines n This specifies the number of lines to use for the type-in. The default is to use one, but you can have a multi-line type-in by specifying some larger number of lines. In this case, the type-in will have a scroll bar for vertical scrolling. -title string By default, the type-in will be labeled by its name, but you can specify some other string to use to identify the type-in. For example, you might use -title "Power of Z". Whenever the value of a type-in is changed (and you press RETURN or ENTER), the object will be recomputed using the new value. You may have as many type-ins as you want for a given object. Type-Ins for group objects are inherited by the objects within the group. Type-Ins for different objects can have the same name, but it is not a good idea to use the same name in an object and its parent group (if you do, the object's type-in takes precedence). Sometimes you want the be able to select a boolean value, for example, you want to be able to select whether a part of a group should be displayed or not. For this reason, CenterStage provides you with a CheckBox directive. The format for the checkbox is: CheckBox name [init] [title] where "name" is the name of the variable that will contain the value of the check-box, "init" is the initial value of the check-box (1 or 0), and "title" is the string that will be used to identify the check-box (by default, the check-box's name). Whenever the value of a check-box is changed, the object will be recomputed using the new value. You may have as many check-boxes as you want for a given object. Check-Boxes for group objects are inherited by the objects within the group. Check-Boxes for different objects can have the same name, but it is not a good idea to use the same name in an object and its parent group (if you do, the object's check-box takes precedence). DIRECTIVES AVAILABLE FOR ALL OBJECTS: The following directives can be specified for any object: Axes {names} This directive specifies the number and names of the coordinates for the object being defined. If not specified, objects inherit their axes from their parent object or the system default of {x y z}. You can name the axes anything you want, and you can have as many as you need. For example, to specify an object in four dimensions, use Axes {x y z w} CenterStage will automatically switch to Geomview's ND mode for viewing the object, showing the first three axes. The names of the axes determine the variables that you need to set when defining an object. For example, to specify a 4D surface using the axes listed above, you need to give values for x, y, z, and w. For example: Domain {{-1 1 10} {-1 1 10}} Function {x y} { let Z = (x,y) let (z,w) = Z^2 + Z } Axes {x y z w} This uses x and y as the parameters for the surface, and creates z and w as the result of a complex polynomial. Appearance appearance This lets you specify arbitrary Geomview appearance characteristics for your object (specifically those that are not available in the APPEARANCE menu, such as material and lighting effects). ColorFunction name function This lets you specify a color function which you can select in the COLOR/BY FUNCTION menu. The name is what will be used in the menu, and the function is what computes the color for the different points on the surface. This should be a single equation that returns either a single value (which is the index into the color table for this point) or a triple of numbers (which is the RGB values for the color). See CHANGING COLORS above for more information about color functions. Setup script This lets you specify a TCL script that should be run just before the object is computed. This lets you set up values or variables that are needed by the rest of the object. For example, you can set up needed values for a surface: Domain {{-1 1 10} {-1 1 10}} Function {u v} { let (x,y,z) = (u,v,u v) + V } Setup { let V (p,q,0) } Slider p -1 1 Slider q -1 1 ShowMe boolean This specifies whether the current object should be displayed in Geomview (if its OBJECT/SHOW menu allows it). The main idea for this directive is to allow the object to use a check-box or other computation to determine whether it should be displayed. For example: CheckBox show ShowMe {$show} will control the visibility of the object through a checkbox. proc name args body This lets you define a TCL procedure for use within your object. It has the same format as the standard TCL proc command, and performs the same function. NOTE: procedures are global, not local to a given object, so you should NOT use the same procedure name from within different objects. EXPRESSIONS AND THE "LET" STATEMENT: CenterStage uses TCL as its underlying language, so when you specify functions while defining CenterStage objects, you use TCL scripts. This gives you powerful programming constructs, like if-then statements, for-loops, user-defined procedures, and more. But it also means you are limited to some of TCL's peculiar syntax. In particular, TCL does not evaluate expressions unless you explicitly request it, and its expression syntax is not very mathematical, especially where variables are concerned. CenterStage tries hard to remedy this situation in two ways: first, it attempts to evaluate expressions automatically whenever this would be appropriate, so you will rarely need to use the TCL "expr" command. For example, if you specify a Vertex directive in a Polyhedron object, you can include expressions to compute the coordinates of the points and they will be evaluated automatically. Second, CenterStage provides a replacement for the "expr" command that has a more mathematical syntax, and also implements complex numbers and vector arithmetic. Normally in TCL, to set a variable equal to the result of an expression you must do something like "set x [expr $y+2*$z]". This seems needlessly complex, so CenterStage provides an easier alternative via the "let" command: let x = y + 2z The format for this command is: let var = expr where "var" is a variable name and "expr" is an expression. The equal sign is optional, but if present must have a space on both sides. In a "let" command, the expression is evaluated using the new expression evaluator and the result is assigned to the variable on the left. Note that in the expression, dollar signs are not needed in front of variable names, and multiplication is implied by concatenation. This should follow natural mathematical notation much more closely than the standard TCL "expr" command. Vectors and matrices are implemented though TCL lists, which can be specified in the standard TCL form by using braces, as in let X = {1+t t^2} or through a more mathematical notation using parentheses and commas: let X = (1+t,t^2) Vectors can be used just like scalar values. They can be assigned to variables, added and subtracted, multiplied and divided by scalars, etc. There are also some special operations and functions for vectors, such as vector cross- and dot-products and vector norm (see below). Vectors of length two are treated as complex numbers and can be multiplied and divided and raised to a scalar power. There are also complex functions such as sine, cosine, log, exp, etc. (see below). CenterStage also provides matrix-vector and matrix-matrix multiplication for square matrices. A matrix is represented as a vector that is of length equal to a perfect square. If such a matrix is multiplied by a vector of the same length, this is done as matrix-matrix multiplication. If a vector of length n*n is multiplied by a vector of length n, then matrix-vector multiplication is performed. For example, let V = { (cos(t), -sin(t), sin(t), cos(t)) * (x,y)} will perform matrix-vector multiplication using the rotation matrix on the left and the 2-vector (x,y) on the right. Basically, it tries hard to do the right thing when it sees multiplication. IMPLIED MULTIPLICATION AND FUNCTION CALLS: Multiplication and function calls are implied by concatenation. For example let x = 2y sets x equal to twice the value of y, while let x = sin y sets x equal to the value of the sine of y. Function-apply has slightly higher precedence than implied multiplication, so let x = sin y cos z sets x to sin(x)*cos(z). This has the drawback that let z = sin x y sets z to (sin x)*y rather than sin(xy). On the other hand, explicit multiplication has higher precedence than implied function calls, so let z = sin x*y sets z to sin(x*y). OPERATORS, PRECEDENCE AND FUNCTIONS: The operators available are: + addition of scalars, vectors or matrices - subtraction of scalars, vectors or matrices * multiplication of scalars complex numbers, or scalar-vector, scalar-matrix, matrix-vector or matrix-matrix multiplication. * is implied by concatenation, except within braces when a space is used as a separator in a list / division of scalars, complex numbers, or vector by a scalar % remainder after division of integers ^ exponentiation of scalars or complex numbers >< vector cross product (for 3-vectors only) . vector dot product @ vector element extraction, e.g., (3,2,5)@1 is 3, (3,2,5)@(1,2) is (3,2), etc. < scalar comparison for less-than > scalar comparison for greater-than == scalar, vector, matrix, string comparison for exact equality === scalar, vector, matrix comparison for near equality <= scalar comparison for less-than-or-equal >= scalar comparison for great-than-or-equal != scalar, vector, matrix, string comparison for not equal !== scalar, vector, matrix comparison for not nearly equal & boolean AND | boolean OR ^^ boolean XOR ! boolean NOT && bitwise AND || bitwise OR ~ bitwise NOT << integer shift left, e.g., 1<<2 is 4 >> integer shift right e.g., 4>>1 is 2 The operators grouped by precedence (highest to lowest) are: ! ~ @ ^ * / % >< . implied function calls, e.g., sin x implied multiplication, e.g., 2 x + - << >> < > <= >= == != === !== & ^^ | && || The built-in functions are the following: cos, sin, tan (standard trig functions for real and complex numbers) acos, asin, atan (standard inverse trig functions) atan2 (atan2(x,y) returns the signed angle formed by the positive x-axis and the ray from the origin through the point (x,y)) cosh, sinh, tanh (the hyperbolic trig functions) hypot (hypot(x,y) is sqrt(x^2+y^2)) exp, ln, log, (real and complex exponetial, and logarithm; both ln and log are the natural log) log10 (real logarithm base 10) pow (pow(x,y) is x^y, for compatibility) sqrt (real and complex square root) abs (absolute value of scalars and vector norm) ceil, floor (least-integer and greatest-integer functions) round (nearest integer) int (integer part of) double (convert to real) fmod (fmod(x,y) is the real remainder of x divided by y) Sgn (Sgn(x) is -1 if x<0, 1 if x>0 and 0 if x==0) Norm (vector norm) Unit (Unit(x) is a unit vector in the direction of X) Conj (complex conjugate) Arg, Mod (complex argument and modulus) Re, Im (real and imaginary parts) SOME ISSUES OF SPACING: TCL uses spaces to separate items in a list so there is ambiguity about an expression like "{1 -t t^2}"; does it mean "(1,-t,t^2)" or "(1-t,t^2)"? It turns out to be the former, which seems to make sense. On the other hand, while the parenthetic form is not ambiguous even if spaces are inserted, the fact that TCL uses spaces to separate items in a list makes it difficult to use the parenthetic form in situations where TCL expects a list (as in Domain directives, or Vertices directives). In these cases you may find it more convenient to use the braced form, or better yet, combine the two: Vertices { {(1, t + 2, -t)} {(t, -t, 1)} } Here, the extra braces guarantee that CenterStage keeps the complete vertices together as one item, but you can still use spaces within the expressions to make them more readable. [note: a better solution is under development.] Also, since TCL ends a command at a line break, it is sometimes necessary to enclose the entire expression in braces: let X = {(1+t^2, sin(t)-cos(2t), log(t^2+1))} In general, you do have to be a careful about spaces and line breaks. EXPRESSIONS OUTSIDE OF THE "LET" COMMAND: The new expression evaluator in CenterStage only operates within the "let" command and within object directives, but not within standard TCL commands. For example, if you write a script for a Function directive and want to use an if-then statement, the if expression uses the standard TCL expression syntax, not the enhanced one defined above. There are two ways around this problem: either use a "let" command prior to the if-then to obtain the result of the expression using the enhanced mathematics, as in let result = ((x,y,z) == (1,0,0)) if {$result} { (do what you need to do) } or use the "Math" command, which works like the "expr" command, but with the new expression evaluator, as in if [Math (x,y,z) == (1,0,0)] { (do what you need to do) } This is not necessary in most directives that take numeric arguments, as these are processed by the "Math" command automatically. You should only need to use this if you are writing TCL scripts like those used in the Function and Setup directives. DECOMPOSING A VECTOR: In a "let" command, the variable on the left can actually be a list of variables, as in let (x,y,z) = (t,t^2,t^3) Here, the result on the right is a vector, and x is assigned the value of the first component of the result, y the value of the second component, and z the value of the third component. This is especially useful when the right-hand side is the result of a vector computation, as in let (x,y,z) = (t,t^2,t^3) >< (1-t,2t,abs(t)) When the "let" command is used in this way, both the list on the left and the result on the right must have the same number of components. FUTURE ENHANCEMENTS: There are still quite a few object classes that need to be written. The color editor needs improvement. The linked object updating needs work. Font handling could be improved. Everything needs to be optimized for speed. KNOWN BUGS: BUG REPORTS AND COMMENTS: Please send bug reports and comments to .