Sherwood (Woody) Anderson's Master's Thesis at Syracuse University in 1967 resulted in two languages CAMP (2-D) and CAMPER (3-D) used to define animated films on a variety of devices.
These were presented at the UAIDE Conference in 1968.
Graphical items were defined on 80-column cards and placed in one of several lists. Transformations (scale, rotate, translate) could be performed on single items in the list or the whole list. In consequence a complex object could be made up of several smaller ones. The objects could be parameterised which greatly increased the flexibility of the system. The systems were written in Fortran so moving it to another computer or even another output device was quite straightforward.
CAMP had a set of basic drawing objects such as circle, rectangle, arrow etc and its own alphabet so it was a well-contained system. The CAMP system at the Atlas Computer Laboratory was produced by Dave Ralphs, a Brunel undergraduate who spent part of his degree course at Atlas and then joined later as a permanent employee. Woody Anderson provided the Laboratory with a listing that was used to create the SC4020 version on Atlas.
The number of basic figures defined in CAMP is limited in order to keep storage requirements to a reasonable size. They fall, basically, into four classes. The first group consists of simple geometric shapes such as circles, triangles, rectangles, crosses. The second consists of more complex shapes which are frequently required. These include arrows, clocks and sine waves. The third class consists of electrical circuit symbols which are not of general interest. These include meters, transistors, resistors and capacitors. They reflect the fact that this work originated in an electrical engineering department. The fourth class is a set of alphanumeric characters of variable size which can be added to a picture at any position.
RUNNING CAMP JOBS ON ATLAS
Before going into the details of the CAMP commands, an example of a complete program ready to run on Atlas will be given. Jobs will normally be punched on cards in the standard Atlas card code. Each program consists of the following:
- Job description.
- Standard data cards for identification
- User commands defining his graphical output
- Program terminator
- Job terminator
1. Job description
A standard job description follows which suffice for most CAMP jobs:
JOB E1111 BLOGGS EXAMPLE 1 COMPUTING 30 SECONDS TAPE 99 N0012FRAH4*INHIBIT OUTPUT 0 LINEPRINTER 1000 LINES OUTPUT 12 LINEPRINTER 50 LINES OUTPUT 13 LINEPRINTER 50 LINES TAPE IBM 14COMMON/SC/BLOGGS STORE 60/60 BLOCKS COMPILER LOAD 001/CAMP
Longer running jobs will of course require a greater computing time than the 30 seconds requested here. However, it is possible for the CAMP system to come off with the diagnostic
C TIME EXCEEDED
when an incorrect CAMP command has been read. As CAMP commands are printed once they have been obeyed, it is useful to examine the command immediately following the last one printed to see if an error occurs in its format. Full delails of Atlas job descriptions are given in the Atlas User's Handbook.
The job number, name and title are, only an example and should be replaced by the user's own. Similarly the name BLOGGS in the tape command should be replaced by the use name.
2. Standard data cards
The data cards following are standard and therefore if the user wishes to run more than one CAMP job at a time it is possible to duplicate these cards to save re-punching.
CAMRA 3 DRAW 1 FRAME ERASE1 DRAW 2 FRAME ERASE2 DRAW 3 FRAME ERASE3 LETER1 1 BLOGGS DRAW 1 FRAME ERASE1 CAMRA 2
The command names must be left-adjusted, i.e. start in column 1. The users name must be left-adjusted in column 61 and must not be more than 12 characters in length including spaces. This is used for identification purposes. The command CAMRA 2 causes the output to be on hardcopy. CAMRA 1 would produce microfilm and CAMRA 3 produces both. The second 1 in the LETER command must be right adjusted as must all array numbers.
3. User commands
The following is an example set of CAMP commands with the picture it produced (Fig. 1).
Fig. 1: Picture from example set of CAMP commands.
12345678901234567890123456789012345678901234567890123456789012345678901234567890 C STICK TEST C TESTING STICK FIGURE ERASE1 0 CLEAR STACK 1 MULTV 1 0. 0. 0. CLEAR VARIABLE 1 ADDV 1 6.0 0. 0. 0. SETCV1 1 901. 8.0 7.0 8. SET UP HEAD EXPAR1 1 7.0 6. 5.0 6. EXPAR1 1 5.0 8. 6.0 8. SETLN1 1 6.0 6. 6.0 2. BODY EXPAR1 1 6.0 2. 4.0 0. LEGS EXPAR1 1 6.0 2. 8.0 0. SETLN1 1 4.0 4. 8.0 4. ARMS CIRCL1 20 8. 5. 1. RECT 1 3 3.5 4. 1. 1. TRNGL1 4 5.75 6.5 0.5 0.5 CROSS1 5 5.5 7.25 0.25 CROSS1 6 6.25 7.25 0.25 ARROW1 7010.45 6.25 11.45 7.75 .4 ARROW1 8110.45 6.25 9.45 7.75 .6 ARROW1 9210.45 6.25 11.45 4.75 .7 ARROW1 10310.45 6.25 9.45 4.75 .5 CLOCK1 11 2.05 2.05 1.45 8.25 SINWV1 12 0.25 7.25 1.25 540. 3. TRANS1 133 9.75 3.05 1.5 CAP 1 14 9.75 0.75 0.3 RESIS1 15 7.05 3.05 2.5 GRND 1 16 7.05 3.05 1.5 METER1 17 1.45 4.75 1.0 0.15 DRAW 1 0 PLOT A STICK FRAME RESET X-AXIS
4. Program terminator
This is the command STOP in columns 1 to 4 of a card. It causes the magnetic tape for the SC4020 plotter to be correctly terminated.
5. Job terminator
This is the standard ATLAS job terminator consisting of a card having a 7/8 multipunch in column 1 and the rest blank.
CO-ORDINATE SYSTEM
In CAMP all X and Y values used in defining a visible picture should be within the limits 0 ≤ X ≤12 and 0 ≤Y ≤9. The SC4020 is capable of resolving points to the second decimal place so that it is not sensible to have an increment smaller than 0.01. Restricting plotting within the X and Y ranges ensures that plotting lies within the normal cine frame on the film. It is possible to produce output for Y values in the range -1.5 ≤ Y ≤ 10.5 but the extended Y values will be outside the standard cine image. X or Y values outside the limits 0 ≤ X ≤ 12 and -1.5 ≤ Y ≤ 10.5 will be automatically scissored by the CAMP system. There is no restriction to using X or Y values outside these ranges. It is just that they will not be visible. (This is sometimes useful when doing zooms and wipes).
DATA CARDS
All commands must be entered by means of data cards. The column assignment is as follows:
Column(s) Entry 1-5 Command name 6 Stack number 7-9 Array number (right justified), or variable number 10 Figure parameter (if required) 12-20 Argument 1 or variable number 21-30 Argument 2 or variable number 31-40 Argument 3 or variable number 41-50 Argument 4 or variable number 51-60 Argument 5 or variable number 61-80 Comments
Arguments 1-5 can be placed anywhere within the columns allotted, provided a decimal point is included. A blank argument is read as zero. The array number must be right justified; i.e. the units digit of the array number must appear in column 9.
It is strongly suggested when key punching the cards that a program drum card be used to eliminate column position errors (using an 026 or 029 card punch):
Columns Character punched 1-61 1 2-5 A 7-11 13-20 22-30 Plus punch (12 zone punch) 32-40 42-50 52-60
COMMANDS
The list of commands is comprised of 4 basic classes. Class 1 commands set up a figure in an array. The figure must be loaded into an array before it can be drawn. Class 2 commands manipulate the co-ordinates of an array in some way. Once these commands are invoked, the original array is, of course, destroyed. If it is desired to save these values, they should be transferred into a new array and operated upon there. Class 3 commands perform arithmetic operations upon the 8 variables and define instruction loops. Class 4 commands deal with the plotter itself.
Comments may be placed on every card from columns 61-80. However, a special card may be devoted to this purpose by simply putting a C in column 1, and comments in columns 61-80. Blank commands are ignored. An invalid command ends the program and causes an error message to be printed. All cards are printed out on the users computer output in the order in which they are executed. This is quite helpful when debugging a sequence of commands for a picture.
A complete list of the commands available in the CAMP system on Atlas is given later. These must always be punched in the format described above. In the test that follows, a less exact format is used with spaces separating the individual fields. A parameter that is not applicable to the command being described is replaced by an asterisk. For example:
TRNGL S ARR * X Y BASE HGT
This would indicate that the command TRNGL does not require the figure parameter to be used. Note also that argument 5 is not printed as it is not required.
Class 1 commands: picture definitions
The S and ARR variables always refer to the stack and array to which the picture is being defined.
CIRCL S ARR D X Y RAD (Fig. 2)
defines a rectangle centred at (X,Y) with radius RAD. If D = 0 then the circle is solid. If D = 1 the circle will be dashed. The circle is always made up of exactly 36 line segments independent of the size of the circle.
Fig. 2: A circle centre at (X,Y) with radius RAD.
RECT S ARR * X Y LNGTH HGT (Fig. 3)
defines a rectangle with the lower left corner at (X,Y) of length, LNGTH, and height, HGT.
Fig. 3: A rectangle with the lower left corner at (X,Y) of length LNGTH, and height HGT.
TRNGL S ARR * X Y BASE HGT (Fig. 4)
defines an isosceles triangle with the lower left edge at (X,Y) of base, BASE and height HGT.
Fig. 4: An isosceles triangle with the lower left edge at (X,Y) of base BASE and height HGT.
ARROW S ARR P X1 Y1 X2 Y2 HEAD (Fig. 5)
defines an arrow directed from (X1,Y1) to (X2,Y2) whose head is of size HEAD. The parameter P takes values between 0 and 3 and defines whether the shaft of the arrow is broken and the form of the tip. The four possibilities are shown in the diagram.
Fig. 5: An arrow directed from from (X1,Y1)to (X2.Y2) whose head is of size HEAD.
GRID S ARR * XDIV YDIV (Fig. 6)
defines a border around the 12 × 9 visible picture area and divides this by additional lines into XDIV equally spaced divisions in the X direction and YDIV equally spaced divisions in the Y direction.
Fig. 6: A border around the 12 × 9 visible picture area which is divided into equally spaced divisions in both the X and Y directions.
CROSS S ARR * X Y SIDE (Fig. 7)
defines a cross with the lower left edge at (X,Y) of width and height equal to SIDE.
Fig. 7: A cross with the lower left edge at (X,Y) of width and height equal to SIDE.
CLOCK S ARR * X Y RAD TIME (Fig. 8)
defines a clock centred at (X,Y) with radius RAD showing time TIME where the integer part of TIME defines the hour and the fractional part is the decimal fraction of an hour.
Fig. 8: A clock centred at (X,Y) with radius RAD showing time TIME.
SINWV S ARR * X Y AMP DEG LNGTH (Fig. 9)
defines a sine wave with origin at (X,Y). The length of the wave is LNGTH and amplitude AMP The sine wave extends from 0 to DEG degrees.
Fig. 9: A sine wave with origin at (X,Y). The length of the wave is LNGTH the amplitude AMP.
CAPP S ARR * X Y DIST (Fig. 10)
defines a capacitor with centre of left plate at (X,Y) and plate separation of DIST.
Fig. 10: A capacitor with centre of left plate at (X,Y) and plate separation of DIST.
RESIS S ARR * X Y LNGTH (Fig. 11)
defines a resistor whose left edge is at (X,Y) and is of length, LNGTH.
Fig. 11: A resistor whose left edge is (X,Y) and is of length LNGTH.
GRND S ARR * X Y DIST {Fig. 12)
defines an earth symbol (or ground) with a connection at (X,Y) of length and height, DIST.
Fig. 12: An earth symbol (or ground) with a connection at (X,Y) of length and height DIST.
TRANS S ARR P X Y DIST (Fig. 13)
defines a transistor with the left hand contact at (X,Y). The picture defines the variations produced by the arguments P and DIST.
Fig. 13: A transistor with the left hand contact at (X,Y).
METER S ARR * X Y RAD PICT (Fig. 14)
defines a meter centred at (X,Y) of radius RAD whose dial indicates PCT as the fraction of full scale reading.
So far we have described the basic figures available to the CAMP user. In general these will not be sufficient to define all that the user requires. Consequently three additional commands are provided for defining arrays as a set of lines.
Fig. 14: A meter centred at (X,Y) of radius RAD.
SETCV S ARR * X1 Y1 X2 Y2
defines the first two points of an array plotted as a closed curve.
SETLN S ARR * X1 Y2 X2 Y2
defines the first two points of an array plotted as a series of unjoined lines.
EXPAR S ARR * X1, Y1, X2 Y2
expands a previously defined SETCV or SETLN array by adding two more points onto the end. The EXPAR command can be used as many times as desired. However, it should only expand the array which is currently at the end of the stack. If an odd number of points is to be placed in a closed curve array (one started by SETCV) then it is necessary to set both points equal in the last EXPAR command, i.e. X2=X1 and Y2=Y1.
Character set
Once the user has obeyed the standard set of commands required at the head of each program (described earlier) all stacks should be empty except stacks 7 and 8. Stack 7 contains the definitions of the character set on the assumption that they are to appear in the area 0 ≤ X,Y ≤ 1. Commands will be described later for producing text of a specified size at any position on the plotting area. If the user wishes to produce textual output then he must be careful not to use stack 7. Full details of the character set and equivalent array numbers are given later.
Stack 8, array 1 contains a rectangle which borders the cine frame.
Class 2 commands: array modification
This set of commands is designed to manipulate and change the contents of arrays and stacks.
ERASE S ARR
this clears a particular array to all zeros. If the array is the last defined in stack S then the space is reclaimed and can be used again. If ARR is zero, the entire stack is set to zero. It is good practice to start each frame or sequence with ERASEed stacks to avoid any carry over from previous frames.
ROTAT S ARR * X Y ANG
rotates an array about the point (X,Y) by ANG degrees. If ANG is positive then rotation is anti clockwise. If ARR is zero then the whole stack is rotated. Each X and Y value in the specified array or stack is replaced by its rotated value. Cumulative rotations can cause build up of rounding error so that the picture disintegrates. It is good practice, therefore, to reinitialise pictures where possible to avoid this.
OFSET S ARR * DX DY
offsets an array by DX in the X direction and DY in the Y direction. DX and DY can be either positive or negative. If ARR is zero then the entire stack is offset.
SIZE S ARR * XREF YREF XMAG YMAG
expands or contracts all points of an array about the reference point (XREF,YREF). New coordinates of all X,Y values in the array are computed by the following relations:
X' = (X - XREF} * XMAG + XREF Y' = (Y - YREF) * YMAG + YREF
where (X,Y) are the original co-ordinates of any point in the array. If XMAG and YMAG are greater than 1, the points expand about the reference point; if XMAG and YMAG are less than 1, the points contract about the reference point; if XMAG and YMAG equal 1 then the points are unchanged; if XMAG and YMAG equal zero then all points are set equal to the reference point. As long as XMAG and YMAG are equal, the picture merely changes its size without being distorted. If ARR is zero, the entire stack is affected.
MOVE STA ARRA * STB ARRB
This command is used with a DO LOOP (to be described later) to move in equal increments, a figure whose initial position is stored in stack STA, array ARRA, to a final position which is stored in stack STB, array ARRB. If both ARRA and ARRB are zero, the entire stack is moved. The parameter NTIMES from the DO instruction determines the total number of equal increments used. The contents of stack STA, array ARRA contain their original values the first time through the loop. For each time through the contents are changed by the MOVE command until, at the end of the loop, stack STA, array ARRA contains the contents of STB, array ARRB. The contents of stack STB, array ARRB will have been destroyed at the end of the loop.
Consider, for example, a film requiring an arrow to drift across the screen in 2 seconds (assume 24 frames per second):
ARROW 1 1 P X1 Y1 X2 Y2 HEAD ARROW 1 2 P X1 Y1 X2 Y2 HEAD DO 48 MOVE 1 1 1 2 DRAW 1 1 0 FRAME LOOP
TNSFR SB ARRB P P1 P2 SA ARRA BPT1
transfers points P1 to P2 inclusive from an array ARRA, stack SA into array ARRB, stack SB. Point P of array ARRA will begin loading into array ARRB starting at point BPT1. If BPT1 is left blank or set to zero then it is assumed to have the value 1. If P is:
ARRB 0, both X and Y co-ordinates are transferred new 1, only X co-ordinates are transferred 2, only Y co-ordinates are transferred ARRB 3, both X and Y co-ordinates are transferred already 4, only X co-ordinates are transferred exists 5, only Y co-ordinates are transferred 9, both X and Y co-ordinates are transferred until either all the points PI to P2 are transferred, or until the end of array ARRA is reached, whichever occurs first. This allows a user to insert a large value to P2 if the actual length of array ARRA is not known.
For example:
SETLN 1 1 1.0 2.0 3.0 4.0 SETLN 1 2 5.0 6.0 7.0 8.0 TNSFR 1 24 2.0 2.0 1.0 1.0 1.0 is equivalent to defining array 2 as SETLN 1 2 3.0 6.0 7.0 8.0
DUMP S
As a debugging aid, it is possible to print the contents of the 1000 locations of stack S using this command.
POINT S ARR * X Y PT
This replaces the PTth point of array ARR, stack S with the new point (X,Y). Array ARR should already be defined.
LETER S ARR * * * * * * TEXT
Individual characters may be defined by transferring the contents of the corresponding array in stack 7 into stack S array ARR. The number of points in each character is defined below. This does become tedious if a large number of characters in a textual string is to be transferred. The LETER command loads up to 20 characters of TEXT into stack S starting with array ARR. Each character is embedded in a 1 × 1 square (which includes a small inter-character gap) and resides in a separate array of stack 7.
The text to be transferred is placed in the last 20 columns of the card (usually reserved for comments in other commands). If fewer than 20 characters are to be transferred, then the string of text should be terminated by the character > (the symbol # is the terminator on the 360 version). The text is loaded into stack S starting in array ARR, with each new character placed into the next consecutive array and offset an inch to the right of the previous one. The first character is located with the lower left hand corner (ARR-1) units to the right of the origin, with the others following it at 1 unit intervals in the X direction, A blank is considered a legal character. If more than 20 characters are required, LETER commands can be used consecutively to concatenate the strings of text.
Suppose we wish to plot a message 0.2 units high.
LETER1 1 THE MEDIUM IS THE ME LETER1 21 SSAGE> SIZE 1 0 0.0 0.0 0.2 0.2 DRAW 1 0 0.0
These commands would load 25 characters into stack 1 (arrays 1 to 26), reduce their height to 0.2 units and the total length to 5.2 and output the message starting at the origin.
Class 3 commands: variable operations
So far we have implied that the arguments in the class 1 and 2 commands are constant values which define the action of the command. However, it is sometimes useful to be able to define a command which can vary in meaning.
CAMP defines a set of nine variables, V1 to V9, which can be set to any particular value or manipulated by the class 3 commands. It is possible to replace all arguments other than the stack and parameter arguments by one of the nine variables. Due to limitations in the FORTRAN input/output package (the language in which CAMP is written), it is not possible to write,for example, V1 in a CAMP command as only numbers are allowed. Most arguments should be small numbers. Therefore V1 to V9 are represented by the numbers 901.0 to 909.0. For example:
12345678901234567890123456789012345678901234567890 CIRCL1 10 4.0 4.0 3.0
defines a circle centred at (4.0,4.0) and radius 3.0.
12345678901234567890123456789012345678901234567890 CIRCL1 10 4.0 4.0 901.0
defines a circle centred at (4.0,4.0) and radius equal to the current value of the variable V1.
The introduction of variables does not, by itself, increase the flexibility of the system by much. However, there are class 3 commands which allow a set of commands to be repeated a number of times. If these commands depend on the current values of variables, it is possible to achieve quite complex picture manipulations with a few CAMP commands in a loop.
The class 3 commands have the general format:
CMND * * VAR OPRND BGIN END
The argument VAR is in the parameter field and therefore must be a single digit. This defines the particular variable to be used in the operation. A variable used in any other argument position will have the usual representation, i.e. the constants 901.0 to 909.0.
The two parameters BGIN and END decide whether or not this command is to be executed. If V9 is less than the value of BGIN then the command will not be executed. If END is not blank or zero then the command will only be executed if V9 is less than the value of END.
In general V9 is reserved to mean the loop variable. It is therefore sensible never to set V9 except when it is defined by a loop. The class 3 commands are as follows:
ADDV * * VAR OPRND BGIN END
places the contents of variable VAR plus OPRND into VAR
SUBV * * VAR OPRND BGIN END
places the contents of variable VAR minus OPRND into VAR
MULTV * * VAR OPRND BGIN END
places the contents of variable VAR times OPRND into VAR
DIVV * * VAR OPRND BGIN END
places the contents of variable VAR divided by OPRND into VAR
SINV * * VAR OPRND BGIN END
places the sine of OPRND degrees into variable VAR
COSV * * VAR OPRND BGIN END
places the cosine of OPRND degrees into variable VAR
SQRTV * * VAR OPRND BGIN END
places the square root of OPRND into variable VAR
EXPV * * VAR OPRND BGIN END
places eOPRND into variable VAR
DO * * * NTIMES
sets up a loop of commands to be repeated NTIMES iterations.
LOOP
defines the end of the group of commands starting with DO which comprise the loop. Loops cannot be nested, i.e. one must end before another begins.
On obeying the DO command initially, the variable V9 is set to 1. Each time the LOOP command is encountered, the value of V9 is increased by one and the commands immediately following the DO command are executed again. This continues until the value of V9 is equal to NTIMES when the LOOP command is encountered. In this case the next command obeyed is the one following the LOOP command.
Class 4 commands: picture drawing
DRAW S ARR * NODRW
The picture defined as array ARR of stack S is drawn as long as NODRW is blank or zero. If NODRW is non-zero the command is ignored. IF ARR is zero, the whole stack is drawn rather than the single array ARR.
MDRAW S ARR P LFT RGT BOT TOP
The picture defined as array ARR of stack S is drawn with the part of the picture defined interior to the rectangle LFT ≤ X ≤ RGT, BOT ≤ Y ≤ TOP being masked off. If ARR=0 the entire stack is drawn with masking. If the parameter P is 1, the lines defining the picture are scissored by the border of the cine frame (i.e. 0 ≤ X ≤ 12, 0 ≤ Y ≤ 9). This extra test is not performed if P is blank or zero.
WDRAW S ARR P LFT RGT BOT TOP
draws those parts of the lines in the picture defined as stack S, array ARR which fall within the rectangle window LFT ≤ X ≤ RGT, BOT ≤ Y ≤ TOP. If ARR-0 the whole stack is drawn under the same conditions. If the parameter P is 1, the last four arguments are assumed to be 0.0, 12.0, 0.0, 9.0 and can therefore be omitted.
SAVE ESAVE REPET * * * NTIMES
These three commands are used to store picture drawing SC4020 instructions which are to be repeated many times. They save a considerable amount of computing time. SAVE begins storing all drawing and frame advance instructions instead of performing them. Approximately 2500 lines can be saved. If this number is exceeded, an error message is printed, and the program stops. Each time SAVE is obeyed, the previously saved commands are destroyed.
The command ESAVE ends the saving process. Any further drawing or frame advance commands are obeyed rather than being saved.
The REPET command performs all the SC4020 instructions that have been stored for NTIMES. For example:
SAVE DRAW 2 0 0.0 WDRAW 3 01 FRAME ESAVE REPET 48.0
will draw stack 2 and the part of stack 3 inside the 9 × 12 border of the cine frame for 48 frames. This is much more efficient than an equivalent set of commands using DO and LOOP.
Often several stacks of figures remain stationary while only one moves. To save processing time, the commands for outputting the stationary stacks and advancing the film should be stored and called once for each cycle of a DO LOOP For example:
SAVE DRAW 1 0 0.0 DRAW 2 0 0.0 FRAME ESAVE DO 96.0 OFSET 3 0 0.1 0.1 WDRAW 3 01 REPET 1.0 LOOP
This set of commands saves the stationary figures in stacks 1 and 2 and the advance film. For each iteration, the figure in stack 3 is moved and then output with the stationary information on the next frame.
FRAME
This concludes the current frame of film and moves the film ready for output on the next frame.
STOP
stops the program.
CAMRA * * I
If I=1, the microfilm camera is selected for output.
If I=2, the hardcopy camera is selected for output.
If I=3, both cameras are selected together.
It is usual to debug films by outputtig selected frames on hardcopy in the early runs. When the bugs have been removed, the microfilm camera is selected.
CAMP COMMANDS
Columns | 1-5 | 6 | 7-9 | 10 | 11-20 | 21-30 | 31-40 | 41-50 | 51-60 | 61-80 |
---|---|---|---|---|---|---|---|---|---|---|
Class | Name | Stack | Array | Par | Arg1 | Arg2 | Arg3 | Arg4 | Arg5 | Comments |
1 | CIRCL | S | ARR | D | X | Y | RAD | |||
1 | RECT | S | ARR | X | Y | LNGTH | HGT | |||
1 | TRNGL | S | ARR | X | Y | BASE | HGT | |||
1 | ARROW | S | ARR | P | X1 | Y1 | X2 | Y2 | HEAD | |
1 | SETCV | S | ARR | X1 | Y1 | X2 | Y2 | |||
1 | SETLN | S | ARR | X1 | Y1 | X2 | Y2 | |||
1 | EXPAR | S | ARR | X1 | Y1 | X2 | Y2 | |||
1 | GRID | S | ARR | XDIV | YDIV | |||||
1 | CROSS | S | ARR | X | Y | SIDE | ||||
1 | CLOCK | S | ARR | X | Y | Z | RAD | TIME | ||
1 | SINWV | S | ARR | X | Y | AMP | DEG | LNGTH | ||
1 | CAP | S | ARR | X | Y | DIST | ||||
1 | RESIS | S | ARR | X | Y | LNGTH | ||||
1 | GRND | S | ARR | X | Y | DIST | ||||
1 | TRANS | S | ARR | P | X | Y | DIST | |||
1 | METER | S | ARR | X | Y | RAD | PCT | |||
1 | FOR1 | S | ARR | P | A1 | A2 | A3 | A4 | A5 | |
1 | FOR2 | S | ARR | P | A1 | A2 | A3 | A4 | A5 | |
2 | C | COMMENTS | ||||||||
2 | ERASE | S | ARR | |||||||
2 | ROTAT | S | ARR | X | Y | ANG | ||||
2 | OFSET | S | ARR | DX | DY | |||||
2 | SIZE | S | ARR | XREF | YREF | XMAG | YMAG | |||
2 | MOVE | STA | ARRA | STB | ARRB | |||||
2 | TNSFR | SB | ARRB | P | P1 | P2 | SA | ARRA | BPT1 | |
2 | POINT | S | ARR | X | Y | PT | ||||
2 | LETER | S | ARR | TEXT | ||||||
3 | ADDV | VAR | OPRND | BGIN | END | |||||
3 | SUBV | VAR | OPRND | BGIN | END | |||||
3 | MULTV | VAR | OPRND | BGIN | END | |||||
3 | DIVV | VAR | OPRND | BGIN | END | |||||
3 | SINV | VAR | OPRND | BGIN | END | |||||
3 | COSV | VAR | OPRND | BGIN | END | |||||
3 | EXPV | VAR | OPRND | BGIN | END | |||||
3 | SQRTV | VAR | OPRND | BGIN | END | |||||
3 | DO | NTIMES | ||||||||
3 | LOOP | |||||||||
4 | DRAW | S | ARR | NODRW | ||||||
4 | MDRAW | S | ARR | P | LFT | RGT | BOT | TOP | ||
4 | WDRAW | S | ARR | P | LFT | RGT | BOT | TOP | ||
4 | SAVE | |||||||||
4 | ESAVE | |||||||||
4 | REPET | NTIMES | ||||||||
4 | FRAME | |||||||||
4 | STOP | |||||||||
4 | CAMRA | P |
CAMP CHARACTER SET
The following characters are already defined in stack 7 when CAMP is entered.
Character | Array | No. of Pts | Character | Array | No. of Pts |
---|---|---|---|---|---|
A | 1 | 8 | Z | 26 | 4 |
B | 2 | 12 | . | 27 | 6 |
C | 3 | 8 | . | 28 | 6 |
D | 4 | 8 | . | 29 | 2 |
E | 5 | 8 | 0 | 30 | 10 |
F | 6 | 8 | 1 | 31 | 6 |
G | 7 | 10 | 2 | 32 | 8 |
H | 8 | 6 | 3 | 33 | 14 |
I | 9 | 6 | 4 | 34 | 6 |
J | 10 | 12 | 5 | 35 | 10 |
K | 11 | 6 | 6 | 36 | 12 |
L | 12 | 4 | 7 | 37 | 4 |
M | 13 | 6 | 8 | 38 | 16 |
N | 14 | 4 | 9 | 39 | 12 |
O | 15 | 10 | Space | 40 | 2 |
P | 16 | 8 | + | 41 | 4 |
Q | 17 | 12 | * | 42 | 8 |
R | 18 | 14 | / | 43 | 2 |
S | 19 | 14 | = | 44 | 4 |
T | 20 | 4 | ( | 45 | 6 |
U | 21 | 6 | ) | 46 | 6 |
V | 22 | 4 | ' | 47 | 6 |
W | 23 | 6 | ? | 48 | 22 |
X | 24 | 4 | > Atlas | - | |
Y | 25 | 6 | ≠ 360 | - | - |
Z | > PDP15 | - | - |
. CAMP ONLY
49 For CAMP the termination character is the 49th whereas for CAMPER it is the 41st character
? is a multi-punch for Atlas
Fig. 15: CAMP Character Set
TABLE OF LOCATIONS REQUIRED BY FIGURE IN CAMP
Figure Location Circle 75 Circle (dashed) 73 Cross 9 Triangle 9 Rectangle 11 Sine Wave 75 Clock 150 Grid(DX,DY) 4*(DX+DY)+9 Capacitor 28 Resistor 17 Transistor 102 Meter 159 Ground 17 Arrow (Solid Tail, Open Head) 12 Arrow (Solid Tail, Closed Head) 14 Arrow (Dashed Tail, Open Head) 32 Arrow (Dashed Tail, Closed Head) 34 SETLN 5 SETCV 5 EXPAR (Each Use) 4
Construction of Basic Figures in CAMP
Fig. 16a: Construction of basic figures in CAMP: Cross.
Location 1 40000. Locations 2-9 4 points
Fig. 16b: Construction of basic figures in CAMP: Triangle.
Location 1 30000. Locations 2-9 4 points
Fig. 16c: Construction of basic figures in CAMP: Rectangle.
Location 1 30000. Locations 2-11 5 points
Fig. 16d: Construction of basic figures in CAMP: Circle.
Location 1 30000. for solid, 40000. for dashed Locations 2-73 36 points dashed Locations 2-75 37 points solid
Fig. 16e: Construction of basic figures in CAMP: Arrow.
Location 1 40000. Locations 2-5 2 points solid line Location 6 10000. Location 7-12 3 points, open arrow head Location 7-14 4 points, closed arrow head
Location 1 40000. Locations 2-25 12 points, dashed line Location 26 10000. Location 27-32 3 points, open arrow head Location 27-34 4 points, closed arrow head
Fig. 16f: Construction of basic figures in CAMP: Clock.
Locations 1-75 Circle Locations 76-89 Arrow (minutes) Locations 90-101 Arrow (hour) Location 102 20000. Locations 103-150 24 points
Fig. 16g: Construction of basic figures in CAMP: Sine curve.
Location 1 30000. Locations 2-75 37 points
Fig. 16h: Construction of basic figures in CAMP: Grid.
Location 1 40000. Locations 2- 4*(DX+DY) + 9 2*(DX+DY+2) Points
Fig. 16i: Construction of basic figures in CAMP: Resistor.
Location 1 30000. Locations 2-17 8 points
Fig. 16j: Construction of basic figures in CAMP: Capacitor.
Location 1 40000. Locations 2-5 2 points Location 6 10000. Location 7-28 11 points
Fig. 16k: Construction of basic figures in CAMP: Ground.
Location 1 40000. Locations 2-17 8 points
Fig. 16l: Construction of basic figures in CAMP: Transistor.
Locations 1-14 Arrow Location 15 20000. Locations 16-27 6 points Location 28-102 Circle
Fig. 16m: Construction of basic figures in CAMP: Meter.
Locations 1-39 Half-circle Locations 40-114 Circle Locations 115-128 Arrow Locations 129-137 Triangle Location 138 10000. Locations 139 -146 4 points Location 147 20000. Locations 148 -159 6 points
CAMP Example 1
Suppose it is desired to depict 450° of a cosine wave. A sine wave must be set up, and the first 90° discarded. Since the sine wave is approximated by 36 straight lines connecting the points of the sine function evaluated every 15 degrees, 37 points are needed altogether. For the present example, 1 to 37 are needed. TNSFR is used with zero in column 10.
C ERASE1 0 ERASE2 0 SINWV1 1 0.0 4.5 4.0 540.0 12.0 TNSFR2 10 1.0 37.0 1.0 1.0 1.0 OFSET2 1 -1.8 0.0 SETLN2 2 0.2 9.0 0.2 0.0 SETLN2 3 0.2 5.0 10.2 5.0 LETER2 4 XY> SIZE 2 4 3.0 0.0 0.2 0.2 SIZE 2 5 4.0 0.0 0.2 0.2 OFSET2 4 7.05 4.5 OFSET2 5 -3.8 7.8 LETER3 1 Y=COS X> OFSET3 0 2.5 5.0 SIZE 3 0 2.5 5.0 0.2 0.2 DRAW 2 DRAW 3 FRAME
Fig. 17: Cosine wave.
CAMP Example 2
A transistor circuit is shown below. A current source drives the base, an ammeter is in series with the emitter lead, and a voltmeter is connected from collector to emitter. This circuit was planned on a large piece of graph paper, and the SIZE instruction was used to reduce the scale before plotting. Notice that the left input terminal at (1.9,5.) is used as a reference point in the SIZE command. Hence this point remains stationary while the rest of the figure shrinks toward it. It is reduced once again and replotted 6.0 inches to the right.
C TRANSISTOR W METERS ERASE1 0 CLEAR STACK 1 CIRCL1 10 1.9 5. .1 LEFT INPUT TERMINAL SETLN1 2 2. 5. 3. 5. LINE CIRCL1 30 3.5 5. .5 CURRENT SOURCE ARROW1 41 3.1 5. 3.9 5. .3 CURRENT SOURCE ARROW SETLN1 5 4. 5. 5. 5. LINE TRANS1 63 7. 6. 2. TRANSISTOR ROTAT1 6 7. 6. -90. ROTATE TRANSISTOR CIRCL1 70 7. 8.1 .1 TOP TERMINAL SETLN1 8 7. 8. 7. 6. CONNECTING LINES EXPAR1 8 7. 4. 7. 2.75 EXPAR1 8 7. 1.25 7. 1. EXPAR1 8 8.75 6.5 8.75 5.75 EXPAR1 8 8.75 4.25 8.75 2.75 EXPAR1 8 8.75 6.5 7.0 6.5 EXPAR1 8 8.75 3.5 7.0 3.5 CIRCL1 90 7. .9 .1 BOTTOM TERMINAL METER1 10 7. 2. .75 .6 AMMETER IN SERIES METER1 11 8.75 5. .75 .8 VOLTMETER PARALLEL SETLN1 12 8.75 6.5 7.0 6.5 MORE LINES EXPAR1 12 8.75 3.5 7.0 3.5 SIZE 1 0 1.9 5. .8 .8 REDUCE SIZE DRAW 1 0 PLOT CIRCUIT LETER2 1 CIRCUIT DIAGRAM OF A LETER2 21 TRANSISTOR WITH > LETER2 38 METERS ATTACHED.> OFSET2 0 0.1 1.3 SIZE 2 0 0.1 1.3 0.2 0.2 DRAW 2 0 FRAME
Fig. 18: Circuit diagram of a transistor with meters attached.
CAMP Example 3
Suppose a triangle is desired with an angle of 40 degrees shown explicitly. The triangle is simply set up as 4 connected points using the SETCV and EXPAR commands. TRNGL cannot be used sines this is not an isosceles triangle. The angle indicator is made up of an arrow and a portion of a circle. The arrow tail is only .1 inch long, but the head is .4 long. A circle is actually 36 straight lines connecting 37 points (points 1 to 37 are congruent). Point 1 is at the right of the circle's centre, and successive points follow counterclockwise along the circle. Only the first 5 points are needed to produce the desired arc.
C TRIANGLE ERASE1 0 CLEAR STACKS ERASE5 0 SETCV1 1 0. 0. 5. 0. SET UP TRIANGLE EXPAR1 1 5. 5.84 0. 0. LOAD INITIAL TIME CIRCL5 10 0. 0. 1.5 SET UP FILL CIRCLE TNSFR1 20 1. 5. 5. 1. 1. TRANSFER FIRST 5 PTS ARROW1 3 1.5 .1 1.5 0. .4 SET UP ARROW HEAD DRAW 1 0 PLOT FIGURE FRAME RESET X-AXIS
Fig. 19: Example of triangle as described.
CAMP Example 4
You are the president of Chrondex Timepiece Limited. While tossing the watch of you chief competitor, Glotz Clocks, into the air, you discover that it runs faster falling down than going up! To expose this obvious fraud, you make a plot showing a clock face every 15 degrees along a sine curve, advancing 5 minutes per figure up to 90 degrees, and 10 minutes per figure after that. Notice the change in ADDV commands on the 7th iteration of the loop.
C TIME FLYING ERASE1 0 CLEAR STACK 1 MULTV 1 0. 0. 0. 0. CLEAR VARIABLE 1 ADDV 1 12.00 0. 0. 0. LOAD INITIAL TIME MULTV 2 0. 0. 0. CLEAR VARIABLE 2 MULTV 4 0. DO 13. SET UP DO LOOP ADDV 4 0.8 SINV 3 902.0 0. 0. LOAD SINE INTO VAR 3 MULTV 3 5. 0. 0. SCALE AMPLITUDE CLOCK1 1 0. 903.0 .5 901.0 SET UP CLOCK OFSET1 1 904.0 1. DRAW 1 1 PLOT A CLOCK ERASE1 1 ERASE ADDV 2 15. 0. 0. INCREMENT ANGLE ADDV 1 .083 0. 7. INCR. TIME BY 5 MIN ADDV 1 .166 7. 0. INCR. TIME BY 10 MIN LOOP END OF LOOP STOP RESET X-AXIS
Fig. 20: Line curve of watch trajectory.
By adding a FRAME command after the DRAW command, it is then possible to animate the clock's movement.
Fig. 21: Animated watch trajectory.
Appendix: CAMP Font Definition in Stack 7 (Usually Preloaded)
C FONT ERASE7 0 SETLN7 1 0. 0. .25 1. A EXPAR7 1 .25 1. .417 1. EXPAR7 1 .417 1. .667 0. EXPAR7 1 .125 .5 .541 .5 SETCV7 2 0. .5 .417 .5 B EXPAR7 2 .583 .667 .583 .833 EXPAR7 2 .417 1. 0. 1. EXPAR7 2 0. 0. .5 0. EXPAR7 2 .667 .167 .667 .417 EXPAR7 2 .5 .5 .5 .5 SETCV7 3 .667 .833 .5 1. C EXPAR7 3 .167 1. 0. .833 EXPAR7 3 0. .167 .167 0. EXPAR7 3 .5 0. .667 .167 SETCV7 4 0. 0. 0. 1. D EXPAR7 4 .5 1. .667 .833 EXPAR7 4 .667 0.17 .5 0. EXPAR7 4 0. 0. 0. 0. SETLN7 5 0. .5 .417 .5 E EXPAR7 5 .583 1. 0. 1. EXPAR7 5 0. 1. 0. 0. EXPAR7 5 0. 0. .667 0. SETLN7 6 0. .5 .417 .5 F EXPAR7 6 .583 1. 0. 1. EXPAR7 6 0. 1. 0. 0. SETCV7 7 .667 .833 .5 1. EXPAR7 7 .167 1. 0. .833 EXPAR7 7 0. .167 .167 0. EXPAR7 7 .5 0. .667 .167 EXPAR7 7 .667 .417 .417 .417 SETLN7 8 0. 0. 0. 1. H EXPAR7 8 0. .5 .667 .5 EXPAR7 8 .667 1. .667 0. SETLN7 9 .25 1. .417 1. I EXPAR7 9 .333 1. .333 0. EXPAR7 9 .25 0. .417 0. SETLN7 10 0. .333 0. .167 J EXPAR7 10 0. .167 .167 0. EXPAR7 10 .167 0. .417 0. EXPAR7 10 .417 0. .583 .167 EXPAR7 10 .583 .167 .583 1. EXPAR7 10 .5 1. .667 1. SETLN7 11 0. 0. 0. 1. K EXPAR7 11 .583 1. 0. .417 EXPAR7 11 .25 .583 .667 0. SETCV7 12 0. 1. 0. 0. L EXPAR7 12 .667 0. .667 0. SETCV7 13 0. 0. 0. 1. M EXPAR7 13 .333 .5 .667 1. EXPAR7 13 .667 0. .667 0. SETCV7 14 0. 0. 0. 1. N EXPAR7 14 .667 0. .667 1. SETCV7 15 0. .167 0. .833 O EXPAR7 15 .167 1. .5 1. EXPAR7 15 .667 .833 .667 .167 EXPAR7 15 .5 0. .167 0. EXPAR7 15 0. .167 0. .167 SETCV7 16 0. 0. 0. 1. P EXPAR7 16 .5 1. .667 .833 EXPAR7 16 .667 .667 .5 .5 EXPAR7 16 0. .5 0. .5 SETCV7 17 .417 .25 .583 .083 Q EXPAR7 17 .5 0. .167 0. EXPAR7 17 0. .167 0. .833 EXPAR7 17 .167 1. .5 1. EXPAR7 17 .667 .833 .667 .167 EXPAR7 17 .583 .083 .667 0. SETLN7 18 0. 0. 0. 1. R EXPAR7 18 0. 1. .5 1. EXPAR7 18 .5 1. .667 .833 EXPAR7 18 .667 .833 .667 .667 EXPAR7 18 .667 .667 .5 .5 EXPAR7 18 .5 .5 0. .5 EXPAR7 18 .5 .5 .667 0. SETCV7 19 0. .333 0. .167 S EXPAR7 19 .167 0. .5 0. EXPAR7 19 .667 .167 .667 .333 EXPAR7 19 .5 .5 .167 .5 EXPAR7 19 0. .667 0. .833 EXPAR7 19 .167 1. .417 1. EXPAR7 19 .583 .833 .583 .833 SETLN7 20 0. 1. .667 1. T EXPAR7 20 .333 1. .333 0. SETCV7 21 0. 1. 0. .167 U EXPAR7 21 .167 0. .5 0. EXPAR7 21 .667 0.17 .667 1. SETCV7 22 0. 1. .333 0. V EXPAR7 22 .667 1. .667 1. SETCV7 23 0. 1. .167 0. W EXPAR7 23 .333 .667 .5 0. EXPAR7 23 .667 1. .667 1. SETLN7 24 0. 1. .667 0. X EXPAR7 24 0. 0. .667 1. SETLN7 25 0. 1. .333 .5 Y EXPAR7 25 .667 1. .333 .5 EXPAR7 25 .333 .5 .333 0. SETCV7 26 0. 1. .667 1. Z EXPAR7 26 0. 0. .667 0. SETCV7 27 .333 -.167 .416 0. , EXPAR7 27 .416 .167 .25 .167 EXPAR7 27 .25 0. .416 0. SETCV7 28 .25 0. .417 0. . EXPAR7 28 .417 .167 .25 .167 EXPAR7 28 .25 0. .25 0. SETCV7 29 0. .5 .667 .5 DASH SETCV7 30 0. .167 0. .833 0 EXPAR7 30 .167 1. .5 1. EXPAR7 30 .667 .833 .667 .167 EXPAR7 30 .5 0. .167 0. EXPAR7 30 0. .167 0. .167 SETLN7 31 .167 .667 .333 1. 1 EXPAR7 31 .333 1. .333 0. EXPAR7 31 .167 0. .5 0. SETCV7 32 0. .833 .167 1. 2 EXPAR7 32 .5 1. .667 .833 EXPAR7 32 .667 .667 0. 0. EXPAR7 32 .667 0. .667 0. SETCV7 33 0. .833 .167 1. 3 EXPAR7 33 .5 1. .667 .833 EXPAR7 33 .667 .667 .5 .5 EXPAR7 33 .167 .5 .5 .5 EXPAR7 33 .667 .333 .667 .167 EXPAR7 33 .5 0. .167 0. EXPAR7 33 0. .167 0. .167 SETCV7 34 .667 .25 0. .25 4 EXPAR7 34 .333 1. .5 1. EXPAR7 34 .5 0. .5 0. SETCV7 35 0. .167 .167 0. 5 EXPAR7 35 .5 0. .667 .167 EXPAR7 35 .667 .417 .5 .583 EXPAR7 35 .083 .583 .083 1. EXPAR7 35 .667 1. .667 1. SETCV7 36 0. .5 .5 .5 6 EXPAR7 36 .667 .333 .667 .167 EXPAR7 36 .5 0. .167 0. EXPAR7 36 0. .167 0. .833 EXPAR7 36 .167 1. .5 1. EXPAR7 36 .67 .833 .67 .833 SETCV7 37 0. 1. .667 1. 7 EXPAR7 37 .167 0. .167 0. SETCV7 38 .167 .5 0. .667 8 EXPAR7 38 0. .833 .167 1. EXPAR7 38 .5 1. .667 .833 EXPAR7 38 .667 .667 .5 .5 EXPAR7 38 .167 .5 0. .333 EXPAR7 38 0. .167 .167 0. EXPAR7 38 .5 0. .667 .167 EXPAR7 38 .667 .333 .5 .5 SETCV7 39 .167 0. .167 0. 9 EXPAR7 39 .5 0. .667 .167 EXPAR7 39 .667 .833 .5 1. EXPAR7 39 .167 1. 0. .833 EXPAR7 39 0. .667 .167 .5 EXPAR7 39 .5 .5 .667 .667 SETCV7 40 0. 0. 0. 0. SPACE SETLN7 41 0. .5 .667 .5 + EXPAR7 41 .333 .167 .333 .833 SETLN7 42 0. .5 .667 .5 * EXPAR7 42 .333 .167 .333 .833 EXPAR7 42 .111 .811 .555 .189 EXPAR7 42 .555 .811 .111 .189 SETLN7 43 .111 .111 .889 .889 / SETLN7 44 0. .633 .667 .633 = EXPAR7 44 0. .367 .667 .333 SETCV7 45 .167 0. 0. .167 ( EXPAR7 45 0. .833 .167 1. SETCV7 46 .5 1. .667 .833 ) EXPAR7 46 .667 .167 .5 0. SETCV7 47 .68 1. .83 1. QUOTE EXPAR7 47 .75 .75 .68 .75 EXPAR7 47 .68 1. .68 1. SETCV7 48 0. .833 .167 1. QUERY EXPAR7 48 .5 1. .667 .833 EXPAR7 48 .667 .667 .5 .5 EXPAR7 48 .333 .5 .333 .333 SETCV7 48 .333 0. .4 .1 EXPAR7 48 .333 .2 .266 .1 EXPAR7 48 .333 0. .333 0. DRAW 7 0 PLOT A STICK FRAME RESET X-AXIS
Appendix: Checking CAMP Examples
Needless to stay, it is not easy to run 80-column card Fortran decks to check that the above examples work. In consequence, a crude compiler for CAMP was generated using XSLT.
This was done using a sequence of XSLT transformations:
- make_commands.xsl: just turns the 80-column cards into XML cmd elements
- reduce_commands.xsl: changes the attributes to the appropriate names for each command
- remove_loops.xsl: loops in CAMP tend to be short so that a simple solution is to unwind the loops
- remove_vars.xsl: interpreting all the type 3 commands to get the correct values of the variables at each stage
- create_stacks.xsl: finally create the stacks/arrays prior to each DRAW command
- output_camp.xsl: now just a simple job to translate to SVG
Example 4 is shown after each stage:
After make_commands.xsl
<camp> <cmnd><name>C</name><stack/><array/><par/><arg1/><arg2/><arg3/><arg4/><arg5/><comment>TIME_FLYING_________</comment></cmnd> <cmnd><name>ERASE</name><stack>1</stack><array>0</array><par/><arg1/><arg2/><arg3/><arg4/><arg5/><comment>CLEAR_STACK_1_______</comment></cmnd> <cmnd><name>MULTV</name><stack/><array/><par>1</par><arg1>0.</arg1><arg2>0.</arg2><arg3>0.</arg3><arg4>0.</arg4><arg5/><comment>CLEAR_VARIABLE_1____</comment></cmnd> <cmnd><name>ADDV</name><stack/><array/><par>1</par><arg1>12.00</arg1><arg2>0.</arg2><arg3>0.</arg3><arg4>0.</arg4><arg5/><comment>LOAD_INITIAL_TIME___</comment></cmnd> <cmnd><name>MULTV</name><stack/><array/><par>2</par><arg1>0.</arg1><arg2>0.</arg2><arg3>0.</arg3><arg4/><arg5/><comment>CLEAR_VARIABLE_2____</comment></cmnd> <cmnd><name>MULTV</name><stack/><array/><par>4</par><arg1>0.</arg1><arg2/><arg3/><arg4/><arg5/><comment>____________________</comment></cmnd> <cmnd><name>DO</name><stack/><array/><par/><arg1>13.</arg1><arg2/><arg3/><arg4/><arg5/><comment>SET_UP_DO_LOOP______</comment></cmnd> <cmnd><name>ADDV</name><stack/><array/><par>4</par><arg1>0.8</arg1><arg2/><arg3/><arg4/><arg5/><comment>____________________</comment></cmnd> <cmnd><name>SINV</name><stack/><array/><par>3</par><arg1>902.0</arg1><arg2>0.</arg2><arg3>0.</arg3><arg4/><arg5/><comment>LOAD_SINE_INTO_VAR_3</comment></cmnd> <cmnd><name>MULTV</name><stack/><array/><par>3</par><arg1>5.</arg1><arg2>0.</arg2><arg3>0.</arg3><arg4/><arg5/><comment>SCALE_AMPLITUDE_____</comment></cmnd> <cmnd><name>CLOCK</name><stack>1</stack><array>1</array><par/><arg1>0.</arg1><arg2>903.0</arg2><arg3>.5</arg3><arg4>901.0</arg4><arg5/><comment>SET_UP_CLOCK________</comment></cmnd> <cmnd><name>OFSET</name><stack>1</stack><array>1</array><par/><arg1>904.0</arg1><arg2>1.</arg2><arg3/><arg4/><arg5/><comment>____________________</comment></cmnd> <cmnd><name>DRAW</name><stack>1</stack><array>1</array><par/><arg1/><arg2/><arg3/><arg4/><arg5/><comment>PLOT_A_CLOCK________</comment></cmnd> <cmnd><name>ERASE</name><stack>1</stack><array>1</array><par/><arg1/><arg2/><arg3/><arg4/><arg5/><comment>ERASE_______________</comment></cmnd> <cmnd><name>ADDV</name><stack/><array/><par>2</par><arg1>15.</arg1><arg2>0.</arg2><arg3>0.</arg3><arg4/><arg5/><comment>INCREMENT_ANGLE_____</comment></cmnd> <cmnd><name>ADDV</name><stack/><array/><par>1</par><arg1>.083</arg1><arg2>0.</arg2><arg3>7.</arg3><arg4/><arg5/><comment>INCR._TIME_BY_5_MIN_</comment></cmnd> <cmnd><name>ADDV</name><stack/><array/><par>1</par><arg1>.166</arg1><arg2>7.</arg2><arg3>0.</arg3><arg4/><arg5/><comment>INCR._TIME_BY_10_MIN</comment></cmnd> <cmnd><name>LOOP</name><stack/><array/><par/><arg1/><arg2/><arg3/><arg4/><arg5/><comment>END_OF_LOOP_________</comment></cmnd> <cmnd><name>STOP</name><stack/><array/><par/><arg1/><arg2/><arg3/><arg4/><arg5/><comment>RESET_X-AXIS________</comment></cmnd> </camp>
After reduce_commands.xsl
To retain the spaces in the comments, these were changed to _ temporarily.
<camp> <cmnd class="2" name="C" COMMENT="TIME_FLYING_________"/> <cmnd class="2" name="ERASE" S="1" ARR="0" C="CLEAR_STACK_1_______"/> <cmnd class="3" name="MULTV" VAR="1" OPRND="0." BGIN="0." END="0." C="CLEAR_VARIABLE_1____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND="12.00" BGIN="0." END="0." C="LOAD_INITIAL_TIME___"/> <cmnd class="3" name="MULTV" VAR="2" OPRND="0." BGIN="0." END="0." C="CLEAR_VARIABLE_2____"/> <cmnd class="3" name="MULTV" VAR="4" OPRND="0." BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="DO" NTIMES="13." C="SET_UP_DO_LOOP______"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd class="3" name="LOOP" C="END_OF_LOOP_________"/> <cmnd class="4" name="STOP" C="RESET_X-AXIS________"/> </camp>
After remove_loops.xsl
Just a matter of introducing the commands related to the loop variable VAR9.
<camp> <cmnd class="2" name="C" COMMENT="TIME_FLYING_________"/> <cmnd class="2" name="ERASE" S="1" ARR="0" C="CLEAR_STACK_1_______"/> <cmnd class="3" name="MULTV" VAR="1" OPRND="0." BGIN="0." END="0." C="CLEAR_VARIABLE_1____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND="12.00" BGIN="0." END="0." C="LOAD_INITIAL_TIME___"/> <cmnd class="3" name="MULTV" VAR="2" OPRND="0." BGIN="0." END="0." C="CLEAR_VARIABLE_2____"/> <cmnd class="3" name="MULTV" VAR="4" OPRND="0." BGIN="0" END="0" C="____________________"/> <cmnd name="MULTV" VAR="9" OPRND="0." BGIN="0" END="0" C="CLEARVAR9"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd name="ADDV" VAR="9" OPRND="1." BGIN="0" END="0" C="ADD 1 TO VAR 9"/> <cmnd class="3" name="ADDV" VAR="4" OPRND="0.8" BGIN="0" END="0" C="____________________"/> <cmnd class="3" name="SINV" VAR="3" OPRND="902.0" BGIN="0." END="0." C="LOAD_SINE_INTO_VAR_3"/> <cmnd class="3" name="MULTV" VAR="3" OPRND="5." BGIN="0." END="0." C="SCALE_AMPLITUDE_____"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="903.0" RAD=".5" TIME="901.0" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="904.0" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="3" name="ADDV" VAR="2" OPRND="15." BGIN="0." END="0." C="INCREMENT_ANGLE_____"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".083" BGIN="0." END="7." C="INCR._TIME_BY_5_MIN_"/> <cmnd class="3" name="ADDV" VAR="1" OPRND=".166" BGIN="7." END="0." C="INCR._TIME_BY_10_MIN"/> <cmnd class="4" name="STOP" C="RESET_X-AXIS________"/> </camp>
After remove_vars.xsl
Each command using a variable as a result or operand needs to be updated.
<camp> <cmnd class="2" name="C" COMMENT="TIME_FLYING_________"/> <cmnd class="2" name="ERASE" S="1" ARR="0" C="CLEAR_STACK_1_______"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="0" RAD=".5" TIME="12" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="0.8" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="1.2940952255126037" RAD=".5" TIME="12.083" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="1.6" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="2.4996" RAD=".5" TIME="12.166" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="2.400004" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="3.5355339059327373" RAD=".5" TIME="12.249" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="3.2" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="4.330127018922193" RAD=".5" TIME="12.332" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="4" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="4.8296291314453486" RAD=".5" TIME="12.415001" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="4.8" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="5.00218" RAD=".5" TIME="12.498001" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="5.6" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="4.8296291314453486" RAD=".5" TIME="12.664001" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="6.3995" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="4.330127018922193" RAD=".5" TIME="12.83002" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="7.199" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="3.5355339059327373" RAD=".5" TIME="12.996002" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="7.999" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="2.4996" RAD=".5" TIME="13.162003" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="8.799" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="1.2940952255126037" RAD=".5" TIME="13.328003" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="9.6" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="1" name="CLOCK" S="1" ARR="1" X="0." Y="0" RAD=".5" TIME="13.494003" C="SET_UP_CLOCK________"/> <cmnd class="2" name="OFSET" S="1" ARR="1" DX="10.4" DY="1." C="____________________"/> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"/> <cmnd class="2" name="ERASE" S="1" ARR="1" C="ERASE_______________"/> <cmnd class="4" name="STOP" C="RESET_X-AXIS________"/> </camp>
After create_stacks.xsl
The appropriate class 1 and 2 commands are replaced by their component parts.
<camp> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> <setcv X1="1.3" X2="1.2925" Y1="1" Y2="1.087"/> <expar X1="1.27" X2="1.233" Y1="1.171" Y2="1.25"/> <expar X1="1.183" X2="1.1215" Y1="1.3215" Y2="1.383"/> <expar X1="1.05" X2="0.971" Y1="1.433" Y2="1.47"/> <expar X1="0.887" X2="0.8" Y1="1.4925" Y2="1.5"/> <expar X1="0.713" X2="0.629" Y1="1.4925" Y2="1.47"/> <expar X1="0.55" X2="0.4785" Y1="1.433" Y2="1.383"/> <expar X1="0.417" X2="0.367" Y1="1.3215" Y2="1.25"/> <expar X1="0.330" X2="0.307" Y1="1.171" Y2="1.087"/> <expar X1="0.300" X2="0.307" Y1="1" Y2="0.913"/> <expar X1="0.330" X2="0.367" Y1="0.829" Y2="0.75"/> <expar X1="0.417" X2="0.4785" Y1="0.6785" Y2="0.617"/> <expar X1="0.55" X2="0.629" Y1="0.567" Y2="0.53"/> <expar X1="0.713" X2="0.8" Y1="0.5075" Y2="0.5"/> <expar X1="0.887" X2="0.971" Y1="0.5075" Y2="0.53"/> <expar X1="1.05" X2="1.1215" Y1="0.567" Y2="0.617"/> <expar X1="1.183" X2="1.233" Y1="0.6785" Y2="0.75"/> <expar X1="1.27" X2="1.2925" Y1="0.829" Y2="0.913"/> <expar X1="1.3" X2="1.3" Y1="1" Y2="1"/> <setln X1="0.8" X2="0.8" Y1="1" Y2="1.44"/> <setcv X1="0.725" X2="0.8" Y1="1.365" Y2="1.44"/> <expar X1="0.875" X2="0.725" Y1="1.365" Y2="1.365"/> <setln X1="0.8" X2="0.8" Y1="1" Y2="1.3"/> <setcv X1="0.725" X2="0.8" Y1="1.225" Y2="1.3"/> <expar X1="0.875" X2="0.875" Y1="1.225" Y2="1.225"/> <setln X1="1.25" X2="1.35" Y1="1" Y2="1"/> <setln X1="1.1897" X2="1.2763" Y1="1.225" Y2="1.275"/> <setln X1="1.025001" X2="1.075" Y1="1.3897" Y2="1.476"/> <setln X1="0.8" X2="0.8" Y1="1.45" Y2="1.55"/> <setln X1="0.575" X2="0.525" Y1="1.3897" Y2="1.476302"/> <setln X1="0.410" X2="0.3237" Y1="1.225" Y2="1.275"/> <setln X1="0.350" X2="0.25" Y1="1" Y2="1"/> <setln X1="0.410" X2="0.3237" Y1="0.775" Y2="0.725"/> <setln X1="0.575" X2="0.525" Y1="0.610" Y2="0.5237"/> <setln X1="0.8" X2="0.8" Y1="0.55" Y2="0.45"/> <setln X1="1.025" X2="1.075" Y1="0.610301" Y2="0.5237"/> <setln X1="1.1897" X2="1.2763" Y1="0.775" Y2="0.725"/> </array> </cmnd> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> <setcv X1="2.1" X2="2.0925" Y1="2.294" Y2="2.381"/> <expar X1="2.07" X2="2.033" Y1="2.465" Y2="2.544"/> <expar X1="1.983" X2="1.9215" Y1="2.616" Y2="2.677"/> <expar X1="1.85" X2="1.771001" Y1="2.727" Y2="2.764"/> ..... </array> </cmnd> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> <setcv X1="2.90" X2="2.892" Y1="3.5" Y2="3.587"/> <expar X1="2.87" X2="2.833" Y1="3.671" Y2="3.75"/> ... </array> </cmnd> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> <setcv X1="3.7" X2="3.6925" Y1="4.535" Y2="4.6225"/> <expar X1="3.67" X2="3.633" Y1="4.706" Y2="4.785"/> ... </array> </cmnd> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> <setcv X1="4.5" X2="4.49" Y1="5.330" Y2="5.417"/> <expar X1="4.47" X2="4.433" Y1="5.501" Y2="5.580"/> ...</array> </cmnd> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> ...</array> </cmnd> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> ...</array> </cmnd> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> ...</array> </cmnd> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> ...</array> </cmnd> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> ...</array> </cmnd> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> ...</array> </cmnd> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> ...</array> </cmnd> <cmnd class="4" name="DRAW" S="1" ARR="1" NODRW="0" C="PLOT_A_CLOCK________"> <array ARR="1"> ...</array> </cmnd> <cmnd class="4" name="STOP" C="RESET_X-AXIS________"/> <stacks> <stack n="2"/> <stack n="3"/> <stack n="4"/> <stack n="5"/> <stack n="6"/> <stack n="7"> <array ARR="1"> ... <array ARR="47"> ... </array> </stack> <stack n="8"/> <stack n="9"/> <stack n="1"/> </stacks> </camp>
After output_camp.xsl
Quite straightforward, just need to introduce SVG M operators in the d attribute whenever a new line is required.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="384" viewBox="0 0 12 9"> <style type="text/css"> path.camp {fill:none;stroke:black;stroke-width:0.05} </style> <rect style="stroke:black;fill:white;stroke-width:0.1" width="12" height="9"/> <g transform="translate(6,4.5)scale(1,-1)translate(-6,-4.5)"> <path class="camp" d="M1.3,1L1.29,1.09L1.27,1.17L1.23,1.25L1.18,1.32L1.12,1.38 L1.05,1.43L0.97,1.47L0.89,1.49L0.8,1.5L0.71,1.49L0.63,1.47L0.55,1.43L0.48,1.38 L0.42,1.32L0.37,1.25L0.33,1.17L0.31,1.09L0.3,1L0.31,0.91L0.33,0.83L0.37,0.75 L0.42,0.68L0.48,0.62L0.55,0.57L0.63,0.53L0.71,0.51L0.8,0.5L0.89,0.51L0.97,0.53 L1.05,0.57L1.12,0.62L1.18,0.68L1.23,0.75L1.27,0.83L1.29,0.91L1.3,1L1.3,1M0.8,1 L0.8,1.44M0.73,1.37L0.8,1.44L0.87,1.37L0.73,1.37M0.8,1L0.8,1.3M0.73,1.23L0.8,1.3 L0.87,1.23L0.87,1.23M1.25,1L1.35,1M1.19,1.22L1.28,1.28M1.03,1.39L1.08,1.48M0.8,1.45 L0.8,1.55M0.58,1.39L0.52,1.48M0.41,1.22L0.32,1.28M0.35,1L0.25,1M0.41,0.78L0.32,0.72 M0.58,0.61L0.52,0.52M0.8,0.55L0.8,0.45M1.03,0.61L1.08,0.52M1.19,0.78L1.28,0.72"/> <path class="camp" d="M2.1,2.29L2.09,2.38L2.07,2.47L2.03,2.54L1.98,2.62L1.92,2.68 L1.85,2.73L1.77,2.76L1.69,2.79L1.6,2.79L1.51,2.79L1.43,2.76L1.35,2.73L1.28,2.68 ..."/> <path class="camp" d="M2.9,3.5L2.89,3.59L2.87,3.67L2.83,3.75L2.78,3.82L2.72,3.88 L2.65,3.93L2.57,3.97L2.49,3.99L2.4,4L2.31,3.99L2.23,3.97L2.15,3.93L2.08,3.88 ..."/> <path class="camp" d="M3.7,4.54L3.69,4.62L3.67,4.71L3.63,4.79L3.58,4.86L3.52,4.92 L3.45,4.97L3.37,5.01L3.29,5.03L3.2,5.04L3.11,5.03L3.03,5.01L2.95,4.97L2.88,4.92 ..."/> <path class="camp" d="M4.5,5.33L4.49,5.42L4.47,5.5L4.43,5.58L4.38,5.65L4.32,5.71 L4.25,5.76L4.17,5.8L4.09,5.82L4,5.83L3.91,5.82L3.83,5.8L3.75,5.76L3.68,5.71L3.62,5.65 ..."/> <path class="camp" d="M5.3,5.83L5.29,5.92L5.27,6L5.23,6.08L5.18,6.15L5.12,6.21 L5.05,6.26L4.97,6.3L4.89,6.32L4.8,6.33L4.71,6.32L4.63,6.3L4.55,6.26L4.48,6.21 ..."/> <path class="camp" d="M6.1,6L6.09,6.09L6.07,6.17L6.03,6.25L5.98,6.32L5.92,6.38 L5.85,6.43L5.77,6.47L5.69,6.49L5.6,6.5L5.51,6.49L5.43,6.47L5.35,6.43L5.28,6.38 ..."/> <path class="camp" d="M6.9,5.83L6.89,5.92L6.87,6L6.83,6.08L6.78,6.15L6.72,6.21 L6.65,6.26L6.57,6.3L6.49,6.32L6.4,6.33L6.31,6.32L6.23,6.3L6.15,6.26L6.08,6.21 ..."/> <path class="camp" d="M7.7,5.33L7.69,5.42L7.67,5.5L7.63,5.58L7.58,5.65L7.52,5.71 L7.45,5.76L7.37,5.8L7.29,5.82L7.2,5.83L7.11,5.82L7.03,5.8L6.95,5.76L6.88,5.71 ..."/> <path class="camp" d="M8.5,4.54L8.49,4.62L8.47,4.71L8.43,4.79L8.38,4.86L8.32,4.92 L8.25,4.97L8.17,5.01L8.09,5.03L8,5.04L7.91,5.03L7.83,5.01L7.75,4.97L7.68,4.92 ..."/> <path class="camp" d="M9.3,3.5L9.29,3.59L9.27,3.67L9.23,3.75L9.18,3.82L9.12,3.88 L9.05,3.93L8.97,3.97L8.89,3.99L8.8,4L8.71,3.99L8.63,3.97L8.55,3.93L8.48,3.88 ..."/> <path class="camp" d="M10.1,2.29L10.09,2.38L10.07,2.47L10.03,2.54L9.98,2.62 L9.92,2.68L9.85,2.73L9.77,2.76L9.69,2.79L9.6,2.79L9.51,2.79L9.43,2.76L9.35,2.73 ..."/> <path class="camp" d="M10.9,1L10.89,1.09L10.87,1.17L10.83,1.25L10.78,1.32 L10.72,1.38L10.65,1.43L10.57,1.47L10.49,1.49L10.4,1.5L10.31,1.49L10.23,1.47 ..."/> </g> </svg>