(c) 1992 Steve Hawtin Introduction ************ This directory contains the sources for "jug", a program that animates juggling patterns. The directory contains the source code for three versions of the program jug works on ASCII terminals xjug works on X windows ajug works on Amigas using WB1.3 the program has been written to make it easy to add new graphical interfaces. If you have any questions or suggestions about the program get in touch with Steve Hawtin EMAIL: steve@geosys.co.uk 68 Gloucester Drive Basingstoke RG22 4PH UK enclose a stamped addressed envelope if you want a reply. If you generate any interesting patterns please send them to me or post them in "rec.juggling" the USENET news group. If you feel that a program of this complexity and sophistication deserves a monetry reward then send a donation to your local ceribral palsey charity, they need your money more than I do. Legal Bit ********* Unless otherwise noted all files in this directory are copyright, you are hereby given permission to use these files for any non-commercial purpose, you are not permitted to use this information in commercial software without the written permission of the authour. You are permitted to sell this software provided no more than a reasonable duplication fee is charged. The authors of the software accept no liability with respect to the software and documentation contained in this package. Background ********** In order to learn how to juggle you must solve two problems, first you must understand "the pattern" then you must teach your body to do it. To most non jugglers I am sure that the second step seems far more difficult, however this is not always the case. One major reason for jugglers getting together is so that they can trade interesting ways of throwing balls in the air. Of course the best way to learn a new pattern is to have personal tuition from someone that has learned it. There are two times when it is worth using a program like jug, either when there are no good jugglers nearby, or when you want to take a pattern step by step. I originally wrote the program to attempt to explain patterns over electronic news systems, I have since also used it to try out new patterns in a world where the balls get caught every time they should. I will go through some of the patterns to show jug in action, I will first assume that you do not yet juggle, using jug I can show you how to start, then I will assume that you can juggle and are attempting to learn a five ball cascade. For all the following I will refer to "jug", if you are running under X windows then substitute "xjug", similarly on the Amiga use "ajug". If you are not yet a juggler there are two ways to start, the first is to get a set of light scarfs, the type that float away on the slightest breeze then use the pattern jug -s scarf the important bit to notice here is that when a hand has dropped a scarf it moves across first, not down. Once you have that pattern try "4scarf" for an entertaining time, make sure you are not near any breakables. The other way to start is by going strait to balls, get three palm sized balls, they should be small enough that you can hold two in one hand with no problem, and heavy enough not to bounce out of your hand. The first step is to learn to throw from hand to hand jug -s step1 notice that both sides throw the ball up to eye level. Keep practicing throwing from hand to hand until you can throw every ball up to eye level and you don't need to reach for it to catch it. Now we can go to the second step, with two balls try jug -s step2 throw the second ball just as the first reaches its peak, make sure that both balls get up to the same height. If you can do this with your right hand then practice with your left. Once you can do that every time, with both hands, then the cascade is just a continual set of similar throws jug -s cascade if you find this hard then you did not spend enough time on step two. Once you are happy with the cascade then you can add some tricks, one simple trick is the over throw, rather than throwing the ball under the incomming one throw it over jug -s overthrw this is just a cascade with every second throw from the right hand going over the incomming ball. Start by trying to do an overthrow every so often, then make it more frequent, by making every right hand throw an overthrow we have a nice pattern known as a half shower jug -s hshower by making every throw on a particular ball an overthrow we have a pattern known as jugglers tennis jug -s tennis and by making every throw an overthrow we have a pattern known as reverse cascade jug -s revcasc so by learning just two types of throw you can juggle five distinct patterns. Suppose you can juggle, you can just about manage a four ball fountain and you want to learn a five ball cascade, the first thing to mention is that I cannot yet do a five ball cascade so this all comes from hearsay. Try to get hold of the document about five ball juggling on "piggy" at Indiana, if you are on electronic mail then send a message containing the two lines intro send juggling-help/5-balls to "juggling-request@piggy.cogsci.indiana.edu". Here are some suggested patterns that you could learn on your way to a perfect five ball cascade, some of these might help if they don't then just concentrate on those that do jug -s high3 each throw goes high enough for a five ball cascade, concentrate on accurate throws jug -s 3flash notice the hand clap, like five with two holes, then you can go on to jug -s -t200 fivep to get used to holding three balls. This pattern seems hard to me, another route is to try jug -s j50500 jug -s j52512 once you have the first the second gets the rythmn right. jug -s 3chase a hard one, like five with two holes next to each other jug -s j53 jug -s j552 jug -s j55550 these are just for the speed, I have heard that the second is too "lumpy" to help with five but useful for making your five solid jug -s 5flash make sure the throws are consistent, once you have this solid try making six throws, then seven, and so on until jug -s five if you can do this you are there, now the best way to learn seven is... Patterns ******** This is a list of some of the patterns that jug understands, to see any of these just give the name as an argument to the jug program. scarf Scarf Cascade cascade Cascade j330 Two ball chase overthrw Simple overthrows tennis Juggler's tennis hshower Half shower revcasc Reverse cascade 2flash Two ball flash 411 411 site swap htennis Half Juggler's tennis fcolumns The lazy juggler's columns columns Simple columns carries Alternating column carries pistons Pistons rchunder Reach under ucarry Carry Under shower Right hand shower box The box hchops Half chops chops Chops exchange The exchange four Four ball synchronus fountain Four ball fountain j53 four ball half shower millsp Mills Mess Practice (for George's version) mills Mills Mess (British version) mills2 Mills Mess (Eric's version) mills3 Mills Mess (George's version) rhcarry Right hand carries bcarry Both Carries hwiper Half Wipers wipers Windscreen wipers hmess Mills Mess (George's version) imills Inverted Mills Mess (George's version) burke Burke's Barrage j50500 High two ball chase 3chase Three ball chase 3flash Three ball flash j52512 Baby juggling five Five ball cascade multi Simple multiplex 4split Multiplex four ball split 5split Multiplex five ball split 6stack Six ball stacked 7split Multiplex seven ball split j45141 site swap '45141' j45501 site swap '45501' j5241 site swap '5241' j531 site swap '531' j5340 site swap '5340' j5511 site swap '5511' j552 site swap '552' j633 site swap '633' j64 Three and two j663 site swap '663' j75 Six ball half shower History ******* There are two possible reasons for creating a language to describe juggling patterns, the first is to be able to describe patterns unambiguously, the second is to allow the user to discover new patterns. Every juggling language attempts to address these two areas, some concentrate on the first element and some on the second. You can attempt to describe juggles using normal prose however describing patterns in English is fraught with peril, it is very easy to make the description unclear and even wrong. A more sucessful way of describing patterns is to use English with drawings, for example George Gillson in his book "Beyond the Cascade" uses a special type of diagram to describe patterns, the result is easy to follow, unambiguous and precise, unfortunately it is hard to transmit the diagrams on computers. On computers the most popular language is "Site Swap" notation from Bruce Tiemann, Bengt Magnusson, and Joel Hamkins. This notation is easy to understand and can be subject to mathematical analysis to discover new patterns. Unfortunately it can only deal with a restricted set of juggling "moves". Some people have attempted to extend siteswap descriptions to make them more flexible, I have yet to find a set of extensions that do not obscure the meaning. If you are interested in the idea of mathematical analysis of juggling patterns I would recommend that you find a copy of "J2" by Jack Boyce, you can even use it to create ".jug" files for this program. I have read of a number of other "languages" for describing juggling patterns, as yet I have not found one that "feels right", however I thought I might have a go at creating such a language. Being a programmer with a special interest in computer languages, I felt that the best way to ensure a juggling language was not ambiguous was to write an interpreter, however I also wanted a language that a human being could stand some chance of reading and writing, without requiring a degree in Computer Science. So I put together a program that takes pattern descriptions in an "English like" language, and displays them on a computer screen. The result is a purely textual language that is unambiguous, you just feed the pattern description into the animator and watch the pattern. As for generating new patterns, the language does not have the mathematical purity of siteswap, I do not think you could create an automatic .jug generator program, however I have used it on occasion to find some new patterns, it is usefull to have a juggler that you can watch in step motion, and that performs exactly the moves you specify every time. I feel that the language as it stands is still too complicated, describing new patterns is too much like writing a program, even given the strong dose of syntactic sugar, and there are too many explicit numbers in the commands. However it does allow the description of more complex patterns than site swaping and the interpreter makes the job of creating new juggles easier. If anyone has any ideas of how the language could be improved, please get in touch. Language ******** When I do a pattern it can be split into three steps, 1. Pick up the balls, clubs, rings or cats 2. Throw some of them into the air 3. Now that everything is moving start the pattern With this in mind a pattern description should contain a description of these three steps. The first step just tells me what to pick up in which hand, and possibly where my hands should be, for example if I have a red ball, a green club and a blue cat right red green left blue but what about where my hand should be? It seems logical to me that my right hand is at 0 when throwing in the cascade, with positive positions going towards my left hand, and the same in reverse for my left hand, so say postion 4 on my right hand is the same as position 0 on my left hand # right -2 -1 0 1 2 3 4 5 6 # left 6 5 4 3 2 1 0 -1 -2 of course we have more than one dimension, otherwise juggling would be slightly harder than it currently is, so we could specify the position as right red green position -1,1,1 where the second component, height, is positive upwards, and the third component is positive away from you. Now that we know where to start from the second step is to describe what to throw up to get the pattern started, when we have instructions there are a number of things that must be specified. First we have the time at which to do the action, next we need to know what to do, so if at time 0 we want to do a throw we could say 0: throw green right from -1,2 with a throw we must also specify how far across to throw the ball and how high to throw it. One way to do this is to say where the ball should be when it falls back to the level it started from, and how many time periods later this should be, so if we say 0: throw green right from 0,0 towards 5,5 then at time 5 the green ball will be at 5,0 on its way to the floor. So we could add 5: catch left green position -1 since 5,0 for the right hand is the same as -1,0 for the left. Of course we could also have moved the hand at time 4 and caught the ball at time 5 by saying 4: move left -1,0 5: catch left Now we have a number of objects travelling arround under the influence of gravity, we need to specify a pattern of actions to stop them hitting the floor. Using the same instructions that were used for the second stage a simple cascade could be 4: throw left towards 5,5 # No need to specify ball, only one there 5: catch left # Just catch the nearest at -1,0 6: move left 0 # Move the left hand ready for the next throw 8: swap hand # Using the other hand loop time 4 # Go back to label 3 and do again Of course the '#' character introduces a comment that lasts until the end of the line. So we can now have a complete description of a shower, it could be # Right hand shower # First where the balls are to start with right red green left blue # Next how to get into the pattern 0: throw right green towards 4,7 from 0 # Finally the pattern itself 4: throw right towards 4,7 throw left towards 4,2 6: catch right 7: catch left 8: loop 4 So in this language we have a number of components, first we have a set of hands, "left" "right" a set of objects specified by colour "red" "green" "blue" "yellow" "violet" "cyan" "white" "black" "brown" "orange" a set of actions we can perform "throw" "catch" "move" "swap" "loop" "goto" a set of parameter specifiers for the actions "hand" "ball" "position" "from" "speed" "towards" "time" "label" so the string "ball 0" means the same as "red", of course most of the time you would use "red" or "left" however when specifying positions or labels the specifiers are used. Here is what the actions do THROW Project an object from the hand, if more than one hand is in use the hand must be specified, if the specified hand has more than one ball then the ball must be specifed too, the speed of the throw must always be specified. You can use "from" to specify where to throw from. Because of the way the simulation is done it is usually best to move the hand to the right place before doing a throw. CATCH Catch an object in a hand, again the hand must be given if more than one is in use. You can specify where to catch from, however this just acts as a start point to look for an object to catch. If you specify a ball to catch then that one will be caught, if not then the closest free ball to the hand will be caught. Once a ball has been located the hand is moved to that position for the catch. Because of the order of the simulation you do not need to move the hand before the catch. MOVE Move the specified hand to the position. SWAP This command allows you to do the same thing using the other hand for example. If you say "swap hand" then from now on all commands for the left hand will be carried out by the right hand and commands for the right hand will be carried out by the left. The more unusual option is to say "swap ball", if you have three balls, "red", "green" and "blue" then "swap ball" causes all actions specified for the red ball to be carried out on the green one, all actions specified for the green ball to be carried out on the blue one, and all actions for the blue ball to be done on the red one. The most complex version of this action would be something like "swap hand 3 ball 2". LOOP or GOTO These two actions both do the same thing, they set the "current time" to the label specified and go back to an earlier part of the pattern. The final command should always be a loop to a previous point in the pattern. This is what the parameter specifiers do HAND The next number is the hand that should be used, for example you could specify a throw as "throw hand 1 towards 4,4", this is the same as using a hand name such as "left", except that you specify the hand number. The main use of this is with the "swap" command, "swap hand" is translated straight into "swap hand 1". BALL Like the previous specifier this allows you to specify balls by logical number. POSITION or FROM Specify where something is to happen, the position is always modified by the hand it is applied to. The position is specified as a tripple of numbers giving distance from left to right, height upwards and distance away from you. Any unspecified dimension is given a default value, normally causing no movement in that direction. SPEED or TOWARDS Specify the speed of a throw, this must always contain the horizontal speed, and the delay until the object will be at the same level going down. You could also specify the speed away from the body. TIME or LABEL Specify destination time for a loop command. There is a final added extra, the '!' command, this sets one of the global variables, so !name Right hand shower sets the "name" of the juggle to "Right hand shower", the variables you can set at the moment are name Name of this juggle max-moves The maximum number of moves (normally 100) gravity The force of gravity (Normally 200) this set will be expanded as time goes on. New patterns ************ Of course you do not want to be restricted to the juggles that are distributed with the jug program, you want to create your own patterns. There are two ways that I create new jug patterns, the easy way and the flexible way. The easy way to create patterns is to use "j2anim" from "J2" by Jack Boyce, this converts siteswaps into juggling patterns so if you want to look at the siteswap 333531522 then you can use the command j2anim >siteswap.jug 333531522 -jug to create a file "siteswap.jug" with the moves for the siteswap. Of course your patterns have the same restrictions as Jack Boyce's extensions to site swap but this is the quickest way to produce working .jug files. The flexible way is more work, I tend to start from a juggle that is close, either copy one of the given examples or use "j2anim" to generate a file. Then I start an editor and the jug viewer on the same file, those of not running under a multiprocessing operating system will just have to run the programs alternately, that will teach you for buying a toy computer. Now concentrate on the start of the pattern, find the first place that the animation does not match what you want. Edit the file to correct the problem, save the file then type at the viewer, it should read the new file and start again. A couple of hints, I tend to remove the final "loop" or "goto" command, replacing it with 100: loop 0 until I am sure that I am matching the pattern, I find the loop command is the most confusing part of creating a new pattern, especially if a swap of some sort is done at the same time. Remember that all throws must specify where they are throwing to, the command throw left 5,7 will be translated into throw left from 5,7 so the throw does not specify the force of the throw. Because of the way the simulation runs it is best to move the hands just after a catch, if you move and throw from the same hand in one time period the path the ball takes is "interesting". When catching the hands "do the right thing" anyway. The program *********** The program is run as jug works on ASCII terminals xjug works on X windows ajug works on Amigas using WB1.3 as well as specifying a pattern you can use a number of switches on the command line to affect the behaviour of the program. Where switches have paramters they should follow immediately from the switch, for example jug -t400 mills3 would set the max time to 400 ticks. -? or -q Display the command switches that jug accepts. -v Display the version number of the program. -s Normally the program will run in step mode, that is the program will pause after each time step waiting for the user to hit a key or press a mouse button. The animation can be run without pause by specifying this flag, this mode can also be inverted by the single key command. -t The animation will keep going for a number of clock ticks this can be set with the max-time global variable or the -t switch. The value will be ignored if the loop-count varibale is set. The default value is 100. -d When the animation is running in run mode it pauses for delay-time seconds between each clock tick. This is normally set to 0.0 to make the animation continuous. -g This sets the gravity varibale, this determines the force of gravity in use for the animation. If the gravity varibale is set in the pattern file this will override the value on the command line. The default value is 200. -p The animation draws clock-division images for each time step, this makes the animation smoother at the expence of more calculation. The default value depends on the graphics system you are running on. -x This sets the relative scale of the drawing. -e This allows the user to extend the vertical exageration, if for example you wish to create a set of ASCII images for inclusion in text describing a pattern then you do not need the full height, using this varible you can draw the patterns in half the lines. -b This sets the loop-count varibale, this determines how many goto commands are obeyed, for example by setting the value to one the animation will only go through the pattern once. If this is set it overrides the max-time variable. Some command line options are only available on certain versions of the program. -m Run in monochrome, only used on the X windows version. -a Dont draw the figure when animating a pattern, only used when the figure is drawn, in the Amiga and X version. -c Colour the arms of the figure as it juggles, only in the Amiga and X version. While the animation is running you can ussue commands by pressing keys, the keys that the animator understands are Print a list of valid keys Quit the animation If in step mode run continuously, otherwise run in step mode Enlarge the scale of the image Reduce the scale of the image Reread the animation file and start again Programming *********** Creating the jug program on your machine should be easy, there are four possibilities, you are running the ASCII version, the X11 version, the Amiga version or you are creating your own version on a new machine. ASCII version If you have a standard C compiler the ASCII version should make on any machine. The one change that is well worth doing is to edit the screen_flush() function in "ascii.c" to make it print out the string that clears your screen. X11 version Under UNIX the X11 version of jug is easy to make, just copy the file "makefile.unx" to "Makefile" and type "make", it should not be too hard under other OSs. Amiga version If you have a copy of "NorthC" the PD C compiler then the Amiga version is made by copying "makefile.ntc" to "Makefile" and typing "make". If you are running WB2.0 then NorthC will not work, complain to the author of that program, I understand that he has not done much work on NorthC for a while, he has spent too much time learning weird juggling patterns, by the way the address at the top of the file is the correct one, the one on NorthC 1.3 is out of date. It should be easy to make jug compile on other Amiga C compilers, if you manage to do this send me the changes and I will put them in a future release. New version Suppose that you are moving jug to a new machine, you have ported the ASCII version but now want to see some real pictures. I have attempted to make you task as easy as possible, you must create a file that defines a number of functions in C, this will replace "ascii.c" in the same way that "x11.c" does. The file must contain a number of definitions, these include some system specific numbers int time_x,time_y; The position to draw the status line, this tells the user what the time is and so on. int ball_offset offset between balls when held in a hand, this depends on the radius of the balls and the scale. double x_scale,y_scale; scale factor for drawing, this is used to zoom in the picture, you should use these values when desciding where to draw the elements. The functions used to control the graphics start with a pair to start and stop the graphics void init_screen(); void tidy_screen(); the program will call the first function to start the graphics, the other function is used to release any graphics resources just prior to the program quitting. The program assumes that drawing is done in two steps, first the image is constructed "off screen", then the constructed image is made visable, this is controlled by void screen_clr(); void screen_flush(); the first function clears the off screen area, preparing it for drawing balls and hands, the second function copies the image from off screen to the visable window. There are three function that draw into the off screen area void draw_ball(x,y,z,ball); void draw_hand(x,y,z,hand); void out_string(x,y,str); the first two functions supply the full three dimensional position and a structure defining the ball or hand to be drawn, the structure is defined in "jug.h". The third function only passes a two dimensional position on the screen. The other three functions that need to be supplied are more obscure, int is_option(num,argv,argc) int *num; char **argv; int argc; is called when jug is passed a command line option it does not recognise, if the graphics wants to use it then the function should return a non zero value, if the graphics does not recognise the option then print out the options the graphics does recognise and return zero. The next function void rescale(); is called each time jug changes the scale, all the obvious calculations are done by jug so all you probably need to do is change the radius of the balls. The final function is the most difficult void wait_step(); this is called when jug is waiting for input before going on, for example when stopping at each time step, the function should return when the user has supplied the right input, normally a or mouse click. If wait_step() gets a key press its should call process_key() with the key that was obtained, this allows the user to control the on going animation by typing keys at it. The best way to create a new animation file is to take an existing file and edit it. Bugs **** Here are some bugs I have found with the current version When reading a file using the key there is some problem with the position of the hands or the timing of throws, the program does not behave the same as the first time you read the file. The input of keys is not right on all systems, this is OK on the systems that I use but needs work on some others, any volunteers? Future Possibilities ******************** There are a number of improvements that could be made to the program this file just puts down some of my thoughts. I might try to do some of these, if I have the time, if anyone else makes improvements to the program please send them to me, I will ensure that they get passed on. 1. Graphics I have tried to make the graphical output as transportable as possible, you should be able to see the basics of any pattern on any computer which has a 'C' compiler. However the program would be improved by making use of graphics facilities on machines, I have tried to keep the display portion seperate from the rest of the code, so anyone with knowledge of a specific machine can replace "ascii.c" with a set of routines to display graphics on thier own systems. Look at "x11.c" and "amiga.c" for an idea of what needs to be done. If you want a challenge how about creating a 3D rendering output, adding two more hands and specifying an six ball passing pattern between two people :-) 2. Hand movement As the program currently stands you must specify each movement that a hand makes, a better option would be to specify just the key points and have the program create the movement commands to ensure a better transition. 3. Hand orientation There should be a way to specify what the hand is doing, for example adding clawing, holding the hand upside down, claping and so on. 4. Extra commands With the current output there is no point in including fancy commands, such as claw A catch with hand palm down toss Throw club with spin spin Specify how fast to spin the club clap Sound effects :-) however these might be worth doing if there are some graphics that allow you to see such things. 5. Subroutines It might be a good idea to have "subroutines", this would allow you to say things like, "throw four cascades then three reverse cascades", or "do overthrow when user presses button" 6. Graphical input It would be nice to be able to "teach" the program how to juggle using graphical input. For example have the program play a bit of a juggle then select throws and hand movements by manipulation of the images of the balls and hands. 7. Different objects Objects should have a "type" for example "ball", "club", "scarf", "cat" and so on. These could modify both the appearence of the object and its behaviour, so scarfs could suffer from less gravity, cats could twist in mid air without being spun, and so on. 9. Bouncing It should be possible to add some bounce juggles, this would need to specify the position of the floor and some idea how bouncy the ball is. Changes ******* This file lists some of the changes that have been made to this program since it was first distributed. Version 0.2 Moved display() function into jug.c, away from the machine specific code. Process the free list before the moves, this makes the balls behave slightly more reasonably. Inserted extra frames in moves, controlled via the "-p" flag, this makes the versions that run on real graphics better. Made the space between the hands 3 units rather than 4, the odd number of slots makes it easier to write symetrical tricks. # left hand -1 0 1 2 3 4 5 # right hand 5 4 3 2 1 0 -1 so 2,0 refers to the centre slot from both hands. Changed the file names to make them easier to move via MSDOS disks. Version 0.3 Corrected toupper() bug in readjug.c from Terry Jones. Corrected the assumption that I am using a colour display, again from Terry Jones. Introduced some scaling for juggles, controlled by the command line and by keyboard commands in xjug. Version 0.4 Added a single letter below each hand to identify the hand on monochrome X servers. Suggested by Terry Jones and Eric Grannan. Added a "jug.man" file to help document the program. Added "loop-count" as global variable and "-b" to set the number of times the pattern should be run. If you wish to include an ASCII picture of a juggle in some documentation you could try something like jug -b1 -e0.5 5split > split.pict on a UNIX machine. Version 0.5 Fixed the bug in the XSetStandardProperties call, from Steve Trainoff. Version 0.6 Remove the stupid restriction on the number of moves that could be processed, this was causing problems with automatically generated patterns. Put all the patterns in a seperate directory, specified with the "-r" flag. Use "j2anim" from Jack Boyce, part of "J2", to create a number of animation files for siteswaps. Add "r" key to restart the pattern, usefull when editing patterns Version 0.7